From ac69c8f5a458e79c98d05a65843baeec40f975e7 Mon Sep 17 00:00:00 2001 From: Rob Taylor Date: Fri, 8 Feb 2008 15:31:03 +0000 Subject: [PATCH 001/692] Added: Added: Renamed to tools/Makefile.am: Renamed to tools/compiler.c: 2008-02-08 Rob Taylor * Makefile.am: * configure.ac: * gidl/Makefile.am: Added: * girepository/Makefile.am: Added: * src/Makefile.am: Renamed to tools/Makefile.am: * src/compiler.c: Renamed to tools/compiler.c: * src/g-idl-offsets.pl: Renamed to tools/g-idl-offsets.pl: * src/generate.c: Renamed to tools/generate.c: * src/gidlmodule.c: Renamed to tools/gidlmodule.c: * src/gidlmodule.h: Renamed to tools/gidlmodule.h: * src/gidlnode.c: Renamed to tools/gidlnode.c: * src/gidlnode.h: Renamed to tools/gidlnode.h: * src/gidlparser.c: Renamed to tools/gidlparser.c: * src/gidlparser.h: Renamed to tools/gidlparser.h: * src/gidlwriter.c: Renamed to tools/gidlwriter.c: * src/gidlwriter.h: Renamed to tools/gidlwriter.h: * src/ginfo.c: Renamed to girepository/ginfo.c: * src/ginvoke.c: Renamed to girepository/ginvoke.c: * src/girepository.c: Renamed to girepository/girepository.c: * src/girepository.h: Renamed to girepository/girepository.h: * src/gmetadata.c: Renamed to girepository/gmetadata.c: * src/gmetadata.h: Renamed to girepository/gmetadata.h: * src/scanner.c: Renamed to tools/scanner.c: * src/scanner.h: Renamed to tools/scanner.h: * src/scannerlexer.l: Renamed to tools/scannerlexer.l: * src/scannerparser.y: Renamed to tools/scannerparser.y: * tests/invoke/Makefile.am: Split src/ into girepository/ and tools/ * Makefile.am: * configure.ac: * girepository/Makefile.am: * tests/Makefile.am: * tests/invoke/Makefile.am: * tests/parser/Makefile.am: * tests/roundtrips.sh: * tools/Makefile.am: Make distcheck work. svn path=/trunk/; revision=104 --- Makefile.am | 16 + ginfo.c | 1806 ++++++++++++++++++++++++++++++++++++++++++++++ ginvoke.c | 284 ++++++++ girepository.c | 499 +++++++++++++ girepository.h | 452 ++++++++++++ gmetadata.c | 1876 ++++++++++++++++++++++++++++++++++++++++++++++++ gmetadata.h | 549 ++++++++++++++ 7 files changed, 5482 insertions(+) create mode 100644 Makefile.am create mode 100644 ginfo.c create mode 100644 ginvoke.c create mode 100644 girepository.c create mode 100644 girepository.h create mode 100644 gmetadata.c create mode 100644 gmetadata.h diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000..480e95f6a --- /dev/null +++ b/Makefile.am @@ -0,0 +1,16 @@ +## Process this file with automake to produce Makefile.in + +INCLUDES = -DGIREPO_DEFAULT_SEARCH_PATH="\"$(libdir)\"" + +lib_LTLIBRARIES = libgirepository.la + +libgirepository_la_SOURCES = \ + girepository.c \ + gmetadata.h \ + gmetadata.c \ + ginfo.c \ + ginvoke.c +libgirepository_la_CFLAGS = $(GIREPO_CFLAGS) + +girepodir = $(includedir)/glib-2.0/gobject-introspection +girepo_HEADERS = girepository.h diff --git a/ginfo.c b/ginfo.c new file mode 100644 index 000000000..6d66de21b --- /dev/null +++ b/ginfo.c @@ -0,0 +1,1806 @@ +/* GObject introspection: Repository implementation + * + * Copyright (C) 2005 Matthias Clasen + * + * 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 "girepository.h" +#include "gmetadata.h" + +struct _GIBaseInfo +{ + gint type; + gint ref_count; + GIBaseInfo *container; + + GMetadata *metadata; + guint32 offset; +}; + +struct _GIUnresolvedInfo +{ + gint type; + gint ref_count; + GIBaseInfo *container; + + const gchar *name; + const gchar *namespace; +}; + +struct _GICallableInfo +{ + GIBaseInfo base; +}; + +struct _GIFunctionInfo +{ + GICallableInfo callable; +}; + +struct _GICallbackInfo +{ + GICallableInfo callable; +}; + +struct _GIRegisteredTypeInfo +{ + GIBaseInfo base; +}; + +struct _GIStructInfo +{ + GIRegisteredTypeInfo registered; +}; + +struct _GIEnumInfo +{ + GIRegisteredTypeInfo registered; +}; + +struct _GIObjectInfo +{ + GIRegisteredTypeInfo registered; +}; + +struct _GIInterfaceInfo +{ + GIRegisteredTypeInfo registered; +}; + +struct _GIConstantInfo +{ + GIBaseInfo base; +}; + +struct _GIValueInfo +{ + GIBaseInfo base; +}; + +struct _GISignalInfo +{ + GICallableInfo callable; +}; + +struct _GIVFuncInfo +{ + GICallableInfo callable; +}; + +struct _GIPropertyInfo +{ + GIBaseInfo base; +}; + +struct _GIFieldInfo +{ + GIBaseInfo base; +}; + +struct _GIArgInfo +{ + GIBaseInfo base; +}; + +struct _GITypeInfo +{ + GIBaseInfo base; +}; + +struct _GIUnionInfo +{ + GIRegisteredTypeInfo registered; +}; + + +/* info creation */ +GIBaseInfo * +g_info_new (GIInfoType type, + GIBaseInfo *container, + GMetadata *metadata, + guint32 offset) +{ + GIBaseInfo *info; + + info = g_new0 (GIBaseInfo, 1); + + info->ref_count = 1; + info->type = type; + + info->metadata = metadata; + info->offset = offset; + + if (container) + info->container = g_base_info_ref (container); + + return info; +} + +static GIBaseInfo * +g_info_from_entry (GMetadata *metadata, + guint16 index) +{ + 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 + { + 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 (); + + 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; + unresolved->namespace = namespace; + + result = (GIBaseInfo*)unresolved; + } + } + + return result; +} + +/* GIBaseInfo functions */ +GIBaseInfo * +g_base_info_ref (GIBaseInfo *info) +{ + info->ref_count++; + + return info; +} + +void +g_base_info_unref (GIBaseInfo *info) +{ + info->ref_count--; + + if (!info->ref_count) + { + if (info->container) + g_base_info_unref (info->container); + + g_free (info); + } +} + +GIInfoType +g_base_info_get_type (GIBaseInfo *info) +{ + + return info->type; +} + +const gchar * +g_base_info_get_name (GIBaseInfo *info) +{ + switch (info->type) + { + case GI_INFO_TYPE_FUNCTION: + case GI_INFO_TYPE_CALLBACK: + case GI_INFO_TYPE_STRUCT: + case GI_INFO_TYPE_BOXED: + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + case GI_INFO_TYPE_OBJECT: + case GI_INFO_TYPE_INTERFACE: + case GI_INFO_TYPE_CONSTANT: + case GI_INFO_TYPE_ERROR_DOMAIN: + case GI_INFO_TYPE_UNION: + { + CommonBlob *blob = (CommonBlob *)&info->metadata->data[info->offset]; + + return g_metadata_get_string (info->metadata, blob->name); + } + break; + + case GI_INFO_TYPE_VALUE: + { + ValueBlob *blob = (ValueBlob *)&info->metadata->data[info->offset]; + + return g_metadata_get_string (info->metadata, blob->name); + } + break; + + case GI_INFO_TYPE_SIGNAL: + { + SignalBlob *blob = (SignalBlob *)&info->metadata->data[info->offset]; + + return g_metadata_get_string (info->metadata, blob->name); + } + break; + + case GI_INFO_TYPE_PROPERTY: + { + PropertyBlob *blob = (PropertyBlob *)&info->metadata->data[info->offset]; + + return g_metadata_get_string (info->metadata, blob->name); + } + break; + + case GI_INFO_TYPE_VFUNC: + { + VFuncBlob *blob = (VFuncBlob *)&info->metadata->data[info->offset]; + + return g_metadata_get_string (info->metadata, blob->name); + } + break; + + case GI_INFO_TYPE_FIELD: + { + FieldBlob *blob = (FieldBlob *)&info->metadata->data[info->offset]; + + return g_metadata_get_string (info->metadata, blob->name); + } + break; + + case GI_INFO_TYPE_ARG: + { + ArgBlob *blob = (ArgBlob *)&info->metadata->data[info->offset]; + + return g_metadata_get_string (info->metadata, blob->name); + } + break; + + case GI_INFO_TYPE_UNRESOLVED: + { + GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info; + + return unresolved->name; + } + break; + + case GI_INFO_TYPE_TYPE: + default: ; + /* unnamed */ + } + + return NULL; +} + +const gchar * +g_base_info_get_namespace (GIBaseInfo *info) +{ + Header *header = (Header *)info->metadata->data; + + if (info->type == GI_INFO_TYPE_UNRESOLVED) + { + GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info; + + return unresolved->namespace; + } + + return g_metadata_get_string (info->metadata, header->namespace); +} + +gboolean +g_base_info_is_deprecated (GIBaseInfo *info) +{ + switch (info->type) + { + case GI_INFO_TYPE_FUNCTION: + case GI_INFO_TYPE_CALLBACK: + case GI_INFO_TYPE_STRUCT: + case GI_INFO_TYPE_BOXED: + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + case GI_INFO_TYPE_OBJECT: + case GI_INFO_TYPE_INTERFACE: + case GI_INFO_TYPE_CONSTANT: + case GI_INFO_TYPE_ERROR_DOMAIN: + { + CommonBlob *blob = (CommonBlob *)&info->metadata->data[info->offset]; + + return blob->deprecated; + } + break; + + case GI_INFO_TYPE_VALUE: + { + ValueBlob *blob = (ValueBlob *)&info->metadata->data[info->offset]; + + return blob->deprecated; + } + break; + + case GI_INFO_TYPE_SIGNAL: + { + SignalBlob *blob = (SignalBlob *)&info->metadata->data[info->offset]; + + return blob->deprecated; + } + break; + + case GI_INFO_TYPE_PROPERTY: + { + PropertyBlob *blob = (PropertyBlob *)&info->metadata->data[info->offset]; + + return blob->deprecated; + } + break; + + case GI_INFO_TYPE_VFUNC: + case GI_INFO_TYPE_FIELD: + case GI_INFO_TYPE_ARG: + case GI_INFO_TYPE_TYPE: + default: ; + /* no deprecation flag for these */ + } + + return FALSE; +} + +static int +cmp_annotation (const void *av, + const void *bv) +{ + const AnnotationBlob *a = av; + const AnnotationBlob *b = bv; + + if (b->offset < a->offset) + return -1; + + if (b->offset > a->offset) + return 1; + + return 0; +} + +const gchar * +g_base_info_get_annotation (GIBaseInfo *info, + const gchar *name) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + AnnotationBlob blob, *first, *after, *res, *next; + const gchar *rname; + + blob.offset = base->offset; + + first = (AnnotationBlob *) &base->metadata->data[header->annotations]; + after = (AnnotationBlob *) &base->metadata->data[header->annotations + + header->n_annotations * header->annotation_blob_size]; + + res = bsearch (&blob, first, header->n_annotations, + header->annotation_blob_size, cmp_annotation); + + if (res == NULL) + return NULL; + + next = res; + do + { + res = next; + next = res -= header->annotation_blob_size; + } + while (next >= first && next->offset == base->offset); + + next = res; + do + { + res = next; + + rname = g_metadata_get_string (base->metadata, res->name); + if (strcmp (name, rname) == 0) + return g_metadata_get_string (base->metadata, res->value); + + next = res += header->annotation_blob_size; + } + while (next < after && next->offset == base->offset); + + return NULL; +} + +GIBaseInfo * +g_base_info_get_container (GIBaseInfo *info) +{ + return info->container; +} + +GMetadata * +g_base_info_get_metadata (GIBaseInfo *info) +{ + return info->metadata; +} + +/* GIFunctionInfo functions */ +const gchar * +g_function_info_get_symbol (GIFunctionInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + FunctionBlob *blob = (FunctionBlob *)&base->metadata->data[base->offset]; + + return g_metadata_get_string (base->metadata, blob->symbol); +} + +GIFunctionInfoFlags +g_function_info_get_flags (GIFunctionInfo *info) +{ + GIFunctionInfoFlags flags; + GIBaseInfo *base = (GIBaseInfo *)info; + FunctionBlob *blob = (FunctionBlob *)&base->metadata->data[base->offset]; + + flags = 0; + + if (base->container != NULL) + flags = flags | GI_FUNCTION_IS_METHOD; + + if (blob->constructor) + flags = flags | GI_FUNCTION_IS_CONSTRUCTOR; + + if (blob->getter) + flags = flags | GI_FUNCTION_IS_GETTER; + + if (blob->setter) + flags = flags | GI_FUNCTION_IS_SETTER; + + if (blob->wraps_vfunc) + flags = flags | GI_FUNCTION_WRAPS_VFUNC; + + return flags; +} + +GIPropertyInfo * +g_function_info_get_property (GIFunctionInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + FunctionBlob *blob = (FunctionBlob *)&base->metadata->data[base->offset]; + GIInterfaceInfo *container = (GIInterfaceInfo *)base->container; + + return g_interface_info_get_property (container, blob->index); +} + +GIVFuncInfo * +g_function_info_get_vfunc (GIFunctionInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + FunctionBlob *blob = (FunctionBlob *)&base->metadata->data[base->offset]; + GIInterfaceInfo *container = (GIInterfaceInfo *)base->container; + + return g_interface_info_get_vfunc (container, blob->index); +} + + +/* GICallableInfo functions */ +static guint32 +signature_offset (GICallableInfo *info) +{ + switch (info->base.type) + { + case GI_INFO_TYPE_FUNCTION: + case GI_INFO_TYPE_VFUNC: + return *(guint32 *)&info->base.metadata->data[info->base.offset + 12]; + case GI_INFO_TYPE_CALLBACK: + case GI_INFO_TYPE_SIGNAL: + return *(guint32 *)&info->base.metadata->data[info->base.offset + 8]; + } + + return 0; +} + +GITypeInfo * +g_type_info_new (GIBaseInfo *container, + GMetadata *metadata, + guint32 offset) +{ + SimpleTypeBlob *type = (SimpleTypeBlob *)&metadata->data[offset]; + + return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, metadata, + type->reserved == 0 ? offset : type->offset); +} + +/** + * g_callable_info_get_return_type: + * @info: a #GICallableInfo + * + * Get the return type of a callable item as + * a #GITypeInfo + * + * Returns: a #GITypeInfo idexing the TypeBlob for the + * return type of #info + */ +GITypeInfo * +g_callable_info_get_return_type (GICallableInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + guint32 offset; + + offset = signature_offset (info); + + return g_type_info_new (base, base->metadata, offset); +} + +/** + * g_callable_info_may_return_null: + * @info: a #GICallableInfo + * + * See if a callable could return NULL. + * + * Returns: TRUE if callable could return NULL + */ +gboolean +g_callable_info_may_return_null (GICallableInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + SignatureBlob *blob = (SignatureBlob *)&base->metadata->data[signature_offset (info)]; + + return blob->may_return_null; +} + +/** + * g_callable_info_get_caller_owns: + * @info: a #GICallableInfo + * + * See whether the caller owns the return value + * of this callable. + * + * Returns: TRUE if the caller owns the return value, FALSE otherwise. + */ +GITransfer +g_callable_info_get_caller_owns (GICallableInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + SignatureBlob *blob = (SignatureBlob *)&base->metadata->data[signature_offset (info)]; + + if (blob->caller_owns_return_value) + return GI_TRANSFER_EVERYTHING; + else if (blob->caller_owns_return_container) + return GI_TRANSFER_CONTAINER; + else + return GI_TRANSFER_NOTHING; +} + +/** + * g_callable_info_get_n_args: + * @info: a #GICallableInfo + * + * Get the number of arguments (both IN and OUT) for this callable. + * + * Returns: The number of arguments this callable expects. + */ +gint +g_callable_info_get_n_args (GICallableInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + gint offset; + SignatureBlob *blob; + + offset = signature_offset (info); + blob = (SignatureBlob *)&base->metadata->data[offset]; + + return blob->n_arguments; +} + +/** + * g_callable_info_get_arg: + * @info: a #GICallableInfo + * + * Get information about a particular argument of this callable. + * + * Returns: A #GIArgInfo indexing the metadata on the given argument. + */ +GIArgInfo * +g_callable_info_get_arg (GICallableInfo *info, + gint n) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + gint offset; + + offset = signature_offset (info); + + return (GIArgInfo *) g_info_new (GI_INFO_TYPE_ARG, base, base->metadata, + offset + header->signature_blob_size + n * header->arg_blob_size); +} + +/* GIArgInfo function */ +GIDirection +g_arg_info_get_direction (GIArgInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ArgBlob *blob = (ArgBlob *)&base->metadata->data[base->offset]; + + if (blob->in && blob->out) + return GI_DIRECTION_INOUT; + else if (blob->out) + return GI_DIRECTION_OUT; + else + return GI_DIRECTION_IN; +} + +gboolean +g_arg_info_is_return_value (GIArgInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ArgBlob *blob = (ArgBlob *)&base->metadata->data[base->offset]; + + return blob->return_value; +} + +gboolean +g_arg_info_is_dipper (GIArgInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ArgBlob *blob = (ArgBlob *)&base->metadata->data[base->offset]; + + return blob->dipper; +} + +gboolean +g_arg_info_is_optional (GIArgInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ArgBlob *blob = (ArgBlob *)&base->metadata->data[base->offset]; + + return blob->optional; +} + +gboolean +g_arg_info_may_be_null (GIArgInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ArgBlob *blob = (ArgBlob *)&base->metadata->data[base->offset]; + + return blob->null_ok; +} + +GITransfer +g_arg_info_get_ownership_transfer (GIArgInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ArgBlob *blob = (ArgBlob *)&base->metadata->data[base->offset]; + + if (blob->transfer_ownership) + return GI_TRANSFER_EVERYTHING; + else if (blob->transfer_container_ownership) + return GI_TRANSFER_CONTAINER; + else + return GI_TRANSFER_NOTHING; +} + +GITypeInfo * +g_arg_info_get_type (GIArgInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + + return g_type_info_new (base, base->metadata, base->offset + 8); +} + +/* GITypeInfo functions */ +gboolean +g_type_info_is_pointer (GITypeInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + 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; + 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 iface->tag; + } +} + +GITypeInfo * +g_type_info_get_param_type (GITypeInfo *info, + gint n) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) + { + ParamTypeBlob *param = (ParamTypeBlob *)&base->metadata->data[base->offset]; + + 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; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) + { + 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; +} + +gint +g_type_info_get_array_length (GITypeInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) + { + ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->metadata->data[base->offset]; + + if (blob->tag == GI_TYPE_TAG_ARRAY) + { + if (blob->has_length) + return blob->length; + } + } + + return -1; +} + +gboolean +g_type_info_is_zero_terminated (GITypeInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) + { + ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->metadata->data[base->offset]; + + 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; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) + { + ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->metadata->data[base->offset]; + + if (blob->tag == GI_TYPE_TAG_ERROR) + return blob->n_domains; + } + + return 0; +} + +GIErrorDomainInfo * +g_type_info_get_error_domain (GITypeInfo *info, + gint n) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + + if (type->reserved != 0) + { + 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; +} + + +/* GIErrorDomainInfo functions */ +const gchar * +g_error_domain_info_get_quark (GIErrorDomainInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset]; + + return g_metadata_get_string (base->metadata, blob->get_quark); +} + +GIInterfaceInfo * +g_error_domain_info_get_codes (GIErrorDomainInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset]; + + return (GIInterfaceInfo *) g_info_from_entry (base->metadata, blob->error_codes); +} + + +/* GIValueInfo functions */ +glong +g_value_info_get_value (GIValueInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ValueBlob *blob = (ValueBlob *)&base->metadata->data[base->offset]; + + return (glong)blob->value; +} + +/* GIFieldInfo functions */ +GIFieldInfoFlags +g_field_info_get_flags (GIFieldInfo *info) +{ + GIFieldInfoFlags flags; + + GIBaseInfo *base = (GIBaseInfo *)info; + FieldBlob *blob = (FieldBlob *)&base->metadata->data[base->offset]; + + flags = 0; + + if (blob->readable) + flags = flags | GI_FIELD_IS_READABLE; + + if (blob->writable) + flags = flags | GI_FIELD_IS_WRITABLE; + + return flags; +} + +gint +g_field_info_get_size (GIFieldInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + FieldBlob *blob = (FieldBlob *)&base->metadata->data[base->offset]; + + return blob->bits; +} + +gint +g_field_info_get_offset (GIFieldInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + FieldBlob *blob = (FieldBlob *)&base->metadata->data[base->offset]; + + return blob->struct_offset; +} + +GITypeInfo * +g_field_info_get_type (GIFieldInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + + return g_type_info_new (base, base->metadata, base->offset + 8); +} + +/* GIRegisteredTypeInfo functions */ +const gchar * +g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->metadata->data[base->offset]; + + if (blob->gtype_name) + return g_metadata_get_string (base->metadata, blob->gtype_name); + + return NULL; +} + +const gchar * +g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->metadata->data[base->offset]; + + if (blob->gtype_init) + return g_metadata_get_string (base->metadata, blob->gtype_init); + + return NULL; +} + + +/* GIStructInfo functions */ +gint +g_struct_info_get_n_fields (GIStructInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + StructBlob *blob = (StructBlob *)&base->metadata->data[base->offset]; + + return blob->n_fields; +} + +GIFieldInfo * +g_struct_info_get_field (GIStructInfo *info, + gint n) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + + return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->metadata, + base->offset + header->struct_blob_size + + n * header->field_blob_size); +} + +gint +g_struct_info_get_n_methods (GIStructInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + StructBlob *blob = (StructBlob *)&base->metadata->data[base->offset]; + + return blob->n_methods; +} + +GIFunctionInfo * +g_struct_info_get_method (GIStructInfo *info, + gint n) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + StructBlob *blob = (StructBlob *)&base->metadata->data[base->offset]; + Header *header = (Header *)base->metadata->data; + gint offset; + + offset = base->offset + header->struct_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); +} + +static GIFunctionInfo * +find_method (GIBaseInfo *base, + guint32 offset, + gint n_methods, + const gchar *name) +{ + /* FIXME hash */ + Header *header = (Header *)base->metadata->data; + gint i; + + for (i = 0; i < n_methods; i++) + { + FunctionBlob *fblob = (FunctionBlob *)&base->metadata->data[offset]; + const gchar *fname = (const gchar *)&base->metadata->data[fblob->name]; + + if (strcmp (name, fname) == 0) + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, + base->metadata, offset); + + offset += header->function_blob_size; + } + + return NULL; +} + +GIFunctionInfo * +g_struct_info_find_method (GIStructInfo *info, + const gchar *name) +{ + gint offset; + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + StructBlob *blob = (StructBlob *)&base->metadata->data[base->offset]; + + offset = base->offset + header->struct_blob_size + + blob->n_fields * header->field_blob_size; + + return find_method (base, offset, blob->n_methods, name); +} + +gint +g_enum_info_get_n_values (GIEnumInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + EnumBlob *blob = (EnumBlob *)&base->metadata->data[base->offset]; + + return blob->n_values; +} + +GIValueInfo * +g_enum_info_get_value (GIEnumInfo *info, + gint n) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + gint offset; + + 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); +} + +/* GIObjectInfo functions */ +GIObjectInfo * +g_object_info_get_parent (GIObjectInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + if (blob->parent) + return (GIObjectInfo *) g_info_from_entry (base->metadata, blob->parent); + else + return NULL; +} + +const gchar * +g_object_info_get_type_name (GIObjectInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + return g_metadata_get_string (base->metadata, blob->gtype_name); +} + +const gchar * +g_object_info_get_type_init (GIObjectInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + return g_metadata_get_string (base->metadata, blob->gtype_init); +} + +gint +g_object_info_get_n_interfaces (GIObjectInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + return blob->n_interfaces; +} + +GIInterfaceInfo * +g_object_info_get_interface (GIObjectInfo *info, + gint n) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + return (GIInterfaceInfo *) g_info_from_entry (base->metadata, blob->interfaces[n]); +} + +gint +g_object_info_get_n_fields (GIObjectInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + return blob->n_fields; +} + +GIFieldInfo * +g_object_info_get_field (GIObjectInfo *info, + gint n) +{ + gint offset; + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + offset = base->offset + header->object_blob_size + + (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); +} + +gint +g_object_info_get_n_properties (GIObjectInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + return blob->n_properties; +} + +GIPropertyInfo * +g_object_info_get_property (GIObjectInfo *info, + gint n) +{ + gint offset; + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + offset = base->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + n * header->property_blob_size; + + return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, base, + base->metadata, offset); +} + +gint +g_object_info_get_n_methods (GIObjectInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + return blob->n_methods; +} + +GIFunctionInfo * +g_object_info_get_method (GIObjectInfo *info, + gint n) +{ + gint offset; + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + offset = base->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + blob->n_properties * header->property_blob_size + + n * header->function_blob_size; + + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, + base->metadata, offset); +} + +GIFunctionInfo * +g_object_info_find_method (GIObjectInfo *info, + const gchar *name) +{ + gint offset; + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + offset = base->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + + blob->n_properties * header->property_blob_size; + + return find_method (base, offset, blob->n_methods, name); +} + +gint +g_object_info_get_n_signals (GIObjectInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + return blob->n_signals; +} + +GISignalInfo * +g_object_info_get_signal (GIObjectInfo *info, + gint n) +{ + gint offset; + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + offset = base->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + + n * header->signal_blob_size; + + return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, base, + base->metadata, offset); +} + +gint +g_object_info_get_n_vfuncs (GIObjectInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + return blob->n_vfuncs; +} + +GIVFuncInfo * +g_object_info_get_vfunc (GIObjectInfo *info, + gint n) +{ + gint offset; + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + offset = base->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + + blob->n_signals * header->signal_blob_size + + n * header->vfunc_blob_size; + + return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, base, + base->metadata, offset); +} + +gint +g_object_info_get_n_constants (GIObjectInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + return blob->n_constants; +} + +GIConstantInfo * +g_object_info_get_constant (GIObjectInfo *info, + gint n) +{ + gint offset; + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + + offset = base->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + + blob->n_signals * header->signal_blob_size + + blob->n_vfuncs * header->vfunc_blob_size + + n * header->constant_blob_size; + + return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, base, + base->metadata, offset); +} + + +/* GIInterfaceInfo functions */ +gint +g_interface_info_get_n_prerequisites (GIInterfaceInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + + return blob->n_prerequisites; +} + +GIBaseInfo * +g_interface_info_get_prerequisite (GIInterfaceInfo *info, + gint n) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + + return g_info_from_entry (base->metadata, blob->prerequisites[n]); +} + + +gint +g_interface_info_get_n_properties (GIInterfaceInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + + return blob->n_properties; +} + +GIPropertyInfo * +g_interface_info_get_property (GIInterfaceInfo *info, + gint n) +{ + gint offset; + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + + offset = base->offset + header->interface_blob_size + + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + + n * header->property_blob_size; + + return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, base, + base->metadata, offset); +} + +gint +g_interface_info_get_n_methods (GIInterfaceInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + + return blob->n_methods; +} + +GIFunctionInfo * +g_interface_info_get_method (GIInterfaceInfo *info, + gint n) +{ + gint offset; + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + + offset = base->offset + header->interface_blob_size + + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + + blob->n_properties * header->property_blob_size + + n * header->function_blob_size; + + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, + base->metadata, offset); +} + +GIFunctionInfo * +g_interface_info_find_method (GIInterfaceInfo *info, + const gchar *name) +{ + gint offset; + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + + offset = base->offset + header->object_blob_size + + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + + blob->n_properties * header->property_blob_size; + + return find_method (base, offset, blob->n_methods, name); +} + +gint +g_interface_info_get_n_signals (GIInterfaceInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + + return blob->n_signals; +} + +GISignalInfo * +g_interface_info_get_signal (GIInterfaceInfo *info, + gint n) +{ + gint offset; + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + + offset = base->offset + header->interface_blob_size + + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + + n * header->signal_blob_size; + + return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, base, + base->metadata, offset); +} + +gint +g_interface_info_get_n_vfuncs (GIInterfaceInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + + return blob->n_vfuncs; +} + +GIVFuncInfo * +g_interface_info_get_vfunc (GIInterfaceInfo *info, + gint n) +{ + gint offset; + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + + offset = base->offset + header->interface_blob_size + + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + + blob->n_signals * header->signal_blob_size + + n * header->vfunc_blob_size; + + return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, base, + base->metadata, offset); +} + +gint +g_interface_info_get_n_constants (GIInterfaceInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + + return blob->n_constants; +} + +GIConstantInfo * +g_interface_info_get_constant (GIInterfaceInfo *info, + gint n) +{ + gint offset; + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + + offset = base->offset + header->interface_blob_size + + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + + blob->n_signals * header->signal_blob_size + + blob->n_vfuncs * header->vfunc_blob_size + + n * header->constant_blob_size; + + return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, base, + base->metadata, offset); +} + + + + +/* GIPropertyInfo functions */ +GParamFlags +g_property_info_get_flags (GIPropertyInfo *info) +{ + GParamFlags flags; + GIBaseInfo *base = (GIBaseInfo *)info; + PropertyBlob *blob = (PropertyBlob *)&base->metadata->data[base->offset]; + + flags = 0; + + if (blob->readable) + flags = flags | G_PARAM_READABLE; + + if (blob->writable) + flags = flags | G_PARAM_WRITABLE; + + if (blob->construct) + flags = flags | G_PARAM_CONSTRUCT; + + if (blob->construct_only) + flags = flags | G_PARAM_CONSTRUCT_ONLY; + + return flags; +} + +GITypeInfo * +g_property_info_get_type (GIPropertyInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + + return g_type_info_new (base, base->metadata, base->offset + 8); +} + + +/* GISignalInfo functions */ +GSignalFlags +g_signal_info_get_flags (GISignalInfo *info) +{ + GSignalFlags flags; + + GIBaseInfo *base = (GIBaseInfo *)info; + SignalBlob *blob = (SignalBlob *)&base->metadata->data[base->offset]; + + flags = 0; + + if (blob->run_first) + flags = flags | G_SIGNAL_RUN_FIRST; + + if (blob->run_last) + flags = flags | G_SIGNAL_RUN_LAST; + + if (blob->run_cleanup) + flags = flags | G_SIGNAL_RUN_CLEANUP; + + if (blob->no_recurse) + flags = flags | G_SIGNAL_NO_RECURSE; + + if (blob->detailed) + flags = flags | G_SIGNAL_DETAILED; + + if (blob->action) + flags = flags | G_SIGNAL_ACTION; + + if (blob->no_hooks) + flags = flags | G_SIGNAL_NO_HOOKS; + + return flags; +} + +GIVFuncInfo * +g_signal_info_get_class_closure (GISignalInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)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 NULL; +} + +gboolean +g_signal_info_true_stops_emit (GISignalInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + SignalBlob *blob = (SignalBlob *)&base->metadata->data[base->offset]; + + return blob->true_stops_emit; +} + +/* GIVFuncInfo functions */ +GIVFuncInfoFlags +g_vfunc_info_get_flags (GIVFuncInfo *info) +{ + GIVFuncInfoFlags flags; + + GIBaseInfo *base = (GIBaseInfo *)info; + VFuncBlob *blob = (VFuncBlob *)&base->metadata->data[base->offset]; + + flags = 0; + + if (blob->must_chain_up) + flags = flags | GI_VFUNC_MUST_CHAIN_UP; + + if (blob->must_be_implemented) + flags = flags | GI_VFUNC_MUST_OVERRIDE; + + if (blob->must_not_be_implemented) + flags = flags | GI_VFUNC_MUST_NOT_OVERRIDE; + + return flags; +} + +gint +g_vfunc_info_get_offset (GIVFuncInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + VFuncBlob *blob = (VFuncBlob *)&base->metadata->data[base->offset]; + + return blob->struct_offset; +} + +GISignalInfo * +g_vfunc_info_get_signal (GIVFuncInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + VFuncBlob *blob = (VFuncBlob *)&base->metadata->data[base->offset]; + + if (blob->class_closure) + return g_interface_info_get_signal ((GIInterfaceInfo *)base->container, blob->signal); + + return NULL; +} + + +/* GIConstantInfo functions */ +GITypeInfo * +g_constant_info_get_type (GIConstantInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + + return g_type_info_new (base, base->metadata, base->offset + 8); +} + +gint +g_constant_info_get_value (GIConstantInfo *info, + GArgument *value) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ConstantBlob *blob = (ConstantBlob *)&base->metadata->data[base->offset]; + + /* FIXME non-basic types ? */ + if (blob->type.reserved == 0) + { + 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; +} + +/* GIUnionInfo functions */ +gint +g_union_info_get_n_fields (GIUnionInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + UnionBlob *blob = (UnionBlob *)&base->metadata->data[base->offset]; + + return blob->n_fields; +} + +GIFieldInfo * +g_union_info_get_field (GIUnionInfo *info, + gint n) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->metadata->data; + + return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->metadata, + base->offset + header->union_blob_size + + n * header->field_blob_size); +} + +gint +g_union_info_get_n_methods (GIUnionInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + UnionBlob *blob = (UnionBlob *)&base->metadata->data[base->offset]; + + return blob->n_functions; +} + +GIFunctionInfo * +g_union_info_get_method (GIUnionInfo *info, + gint n) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + UnionBlob *blob = (UnionBlob *)&base->metadata->data[base->offset]; + Header *header = (Header *)base->metadata->data; + gint offset; + + offset = base->offset + header->union_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); +} + +gboolean +g_union_info_is_discriminated (GIUnionInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + UnionBlob *blob = (UnionBlob *)&base->metadata->data[base->offset]; + + return blob->discriminated; +} + +gint +g_union_info_get_discriminator_offset (GIUnionInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + UnionBlob *blob = (UnionBlob *)&base->metadata->data[base->offset]; + + return blob->discriminator_offset; +} + +GITypeInfo * +g_union_info_get_discriminator_type (GIUnionInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + + return g_type_info_new (base, base->metadata, base->offset + 24); +} + +GIConstantInfo * +g_union_info_get_discriminator (GIUnionInfo *info, + gint n) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + UnionBlob *blob = (UnionBlob *)&base->metadata->data[base->offset]; + + if (blob->discriminated) + { + Header *header = (Header *)base->metadata->data; + gint offset; + + offset = base->offset + header->union_blob_size + + blob->n_fields * header->field_blob_size + + blob->n_functions * header->function_blob_size + + n * header->constant_blob_size; + + return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, base, + base->metadata, offset); + } + + return NULL; +} diff --git a/ginvoke.c b/ginvoke.c new file mode 100644 index 000000000..986ca7850 --- /dev/null +++ b/ginvoke.c @@ -0,0 +1,284 @@ +/* GObject introspection: Invoke functionality + * + * Copyright (C) 2005 Matthias Clasen + * + * 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 "girepository.h" +#include "gmetadata.h" +#include "config.h" + +GQuark +g_invoke_error_quark (void) +{ + static GQuark quark = 0; + if (quark == 0) + quark = g_quark_from_static_string ("g-invoke-error-quark"); + return quark; +} + +#include "ffi.h" + +static ffi_type * +get_ffi_type (GITypeInfo *info) +{ + ffi_type *rettype; + + if (g_type_info_is_pointer (info)) + rettype = &ffi_type_pointer; + else + switch (g_type_info_get_tag (info)) + { + case GI_TYPE_TAG_VOID: + rettype = &ffi_type_void; + break; + case GI_TYPE_TAG_BOOLEAN: + rettype = &ffi_type_uint; + break; + case GI_TYPE_TAG_INT8: + rettype = &ffi_type_sint8; + break; + case GI_TYPE_TAG_UINT8: + rettype = &ffi_type_uint8; + break; + case GI_TYPE_TAG_INT16: + rettype = &ffi_type_sint16; + break; + case GI_TYPE_TAG_UINT16: + rettype = &ffi_type_uint16; + break; + case GI_TYPE_TAG_INT32: + rettype = &ffi_type_sint32; + break; + case GI_TYPE_TAG_UINT32: + rettype = &ffi_type_uint32; + break; + case GI_TYPE_TAG_INT64: + rettype = &ffi_type_sint64; + break; + case GI_TYPE_TAG_UINT64: + rettype = &ffi_type_uint64; + break; + case GI_TYPE_TAG_INT: + rettype = &ffi_type_sint; + break; + case GI_TYPE_TAG_UINT: + rettype = &ffi_type_uint; + break; + case GI_TYPE_TAG_SSIZE: /* FIXME */ + case GI_TYPE_TAG_LONG: + rettype = &ffi_type_slong; + break; + case GI_TYPE_TAG_SIZE: /* FIXME */ + case GI_TYPE_TAG_ULONG: + rettype = &ffi_type_ulong; + break; + case GI_TYPE_TAG_FLOAT: + rettype = &ffi_type_float; + break; + case GI_TYPE_TAG_DOUBLE: + rettype = &ffi_type_double; + break; + case GI_TYPE_TAG_UTF8: + case GI_TYPE_TAG_FILENAME: + 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: + case GI_TYPE_TAG_ERROR: + rettype = &ffi_type_pointer; + break; + default: + g_assert_not_reached (); + } + + return rettype; +} + +/** + * g_function_info_invoke: + * @info: a #GIFunctionInfo describing the function to invoke + * @in_args: an array of #GArguments, one for each in + * parameter of @info. If there are no in parameter, @in_args + * can be %NULL + * @n_in_args: the length of the @in_args array + * @out_args: an array of #GArguments, one for each out + * parameter of @info. If there are no out parameters, @out_args + * may be %NULL + * @n_out_args: the length of the @out_args array + * @return_value: return location for the return value of the + * function. If the function returns void, @return_value may be + * %NULL + * @error: return location for detailed error information, or %NULL + * + * Invokes the function described in @info with the given + * arguments. Note that inout parameters must appear in both + * argument lists. This function uses dlsym() to obtain a pointer + * to the function, so the library or shared object containing the + * described function must either be linked to the caller, or must + * have been dlopen()ed before calling this function. + * + * Returns: %TRUE if the function has been invoked, %FALSE if an + * error occurred. + */ +gboolean +g_function_info_invoke (GIFunctionInfo *info, + const GArgument *in_args, + int n_in_args, + const GArgument *out_args, + int n_out_args, + GArgument *return_value, + GError **error) +{ + ffi_cif cif; + ffi_type *rtype; + ffi_type **atypes; + const gchar *symbol; + gpointer func; + GITypeInfo *tinfo; + GIArgInfo *ainfo; + gint n_args, in_pos, out_pos, i; + gpointer *args; + gboolean success = FALSE; + + symbol = g_function_info_get_symbol (info); + + if (!g_module_symbol (g_base_info_get_metadata((GIBaseInfo *) info)->module, + symbol, &func)) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_SYMBOL_NOT_FOUND, + "Could not locate %s: %s", symbol, g_module_error ()); + + return FALSE; + } + + tinfo = g_callable_info_get_return_type ((GICallableInfo *)info); + rtype = get_ffi_type (tinfo); + g_base_info_unref ((GIBaseInfo *)tinfo); + + n_args = g_callable_info_get_n_args ((GICallableInfo *)info); + atypes = g_new (ffi_type*, n_args); + args = g_new (gpointer, n_args); + + in_pos = 0; + out_pos = 0; + for (i = 0; i < n_args; i++) + { + ainfo = g_callable_info_get_arg ((GICallableInfo *)info, i); + switch (g_arg_info_get_direction (ainfo)) + { + case GI_DIRECTION_IN: + tinfo = g_arg_info_get_type (ainfo); + atypes[i] = get_ffi_type (tinfo); + g_base_info_unref ((GIBaseInfo *)tinfo); + + if (in_pos >= n_in_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too few \"in\" arguments"); + goto out; + } + + args[i] = (gpointer)&in_args[in_pos]; + in_pos++; + + break; + case GI_DIRECTION_OUT: + atypes[i] = &ffi_type_pointer; + + if (out_pos >= n_out_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too few \"out\" arguments"); + goto out; + } + + args[i] = (gpointer)&out_args[out_pos]; + out_pos++; + break; + case GI_DIRECTION_INOUT: + atypes[i] = &ffi_type_pointer; + + if (in_pos >= n_in_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too few \"in\" arguments"); + goto out; + } + + if (out_pos >= n_out_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too few \"in\" arguments"); + goto out; + } + + args[i] = (gpointer)&in_args[in_pos]; + in_pos++; + out_pos++; + break; + default: + g_assert_not_reached (); + } + g_base_info_unref ((GIBaseInfo *)ainfo); + } + if (in_pos < n_in_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too many \"in\" arguments"); + goto out; + } + if (out_pos < n_out_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too many \"out\" arguments"); + goto out; + } + + if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, rtype, atypes) != FFI_OK) + goto out; + + ffi_call (&cif, func, return_value, args); + + success = TRUE; + + out: + g_free (atypes); + g_free (args); + + return success; +} diff --git a/girepository.c b/girepository.c new file mode 100644 index 000000000..c9b3b683c --- /dev/null +++ b/girepository.c @@ -0,0 +1,499 @@ +/* -*- Mode: C; c-file-style: "gnu"; -*- */ +/* GObject introspection: Repository implementation + * + * Copyright (C) 2005 Matthias Clasen + * + * 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 +#include +#include "girepository.h" +#include "gmetadata.h" + +static GIRepository *default_repository = NULL; +static GHashTable *default_metadata = NULL; +static GSList *search_path = NULL; + +struct _GIRepositoryPrivate +{ + GHashTable *metadata; /* (string) namespace -> GMetadata */ +}; + +G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT); + +static void +g_irepository_init (GIRepository *repository) +{ + repository->priv = G_TYPE_INSTANCE_GET_PRIVATE (repository, G_TYPE_IREPOSITORY, + GIRepositoryPrivate); +} + +static void +g_irepository_finalize (GObject *object) +{ + GIRepository *repository = G_IREPOSITORY (object); + + g_hash_table_destroy (repository->priv->metadata); + + (* G_OBJECT_CLASS (g_irepository_parent_class)->finalize) (G_OBJECT (repository)); +} + +static void +g_irepository_class_init (GIRepositoryClass *class) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (class); + + gobject_class->finalize = g_irepository_finalize; + + g_type_class_add_private (class, sizeof (GIRepositoryPrivate)); +} + +const gchar * +g_irepository_register (GIRepository *repository, + GMetadata *metadata) +{ + Header *header; + const gchar *name; + GHashTable *table; + GError *error = NULL; + + g_return_val_if_fail (metadata != NULL, NULL); + + header = (Header *)metadata->data; + + g_return_val_if_fail (header != NULL, NULL); + + if (repository != NULL) + { + if (repository->priv->metadata == NULL) + repository->priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) NULL, + (GDestroyNotify) g_metadata_free); + table = repository->priv->metadata; + } + else + { + if (default_metadata == NULL) + default_metadata = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) NULL, + (GDestroyNotify) g_metadata_free); + table = default_metadata; + } + + name = g_metadata_get_string (metadata, header->namespace); + + if (g_hash_table_lookup (table, name)) + { + g_printerr ("metadata (%p) for '%s' already registered\n", + metadata, name); + + return NULL; + } + g_hash_table_insert (table, g_strdup(name), (void *)metadata); + + if (metadata->module == NULL) + metadata->module = g_module_open (NULL, 0); + + return name; +} + + +void +g_irepository_unregister (GIRepository *repository, + const gchar *namespace) +{ + GHashTable *table; + + if (repository != NULL) + table = repository->priv->metadata; + else + table = default_metadata; + + if (!g_hash_table_remove (table, namespace)) + { + g_printerr ("namespace '%s' not registered\n", namespace); + } +} + +gboolean +g_irepository_is_registered (GIRepository *repository, + const gchar *namespace) +{ + GHashTable *table; + + if (repository != NULL) + table = repository->priv->metadata; + else + table = default_metadata; + + return g_hash_table_lookup (table, namespace) != NULL; +} + +GIRepository * +g_irepository_get_default (void) +{ + if (default_repository == NULL) + { + default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL); + if (default_metadata == NULL) + default_metadata = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) NULL, + (GDestroyNotify) g_metadata_free); + default_repository->priv->metadata = default_metadata; + } + + return default_repository; +} + +static void +count_interfaces (gpointer key, + gpointer value, + gpointer data) +{ + guchar *metadata = ((GMetadata *) value)->data; + gint *n_interfaces = (gint *)data; + + *n_interfaces += ((Header *)metadata)->n_local_entries; +} + +gint +g_irepository_get_n_infos (GIRepository *repository, + const gchar *namespace) +{ + gint n_interfaces = 0; + + if (namespace) + { + GMetadata *metadata; + + metadata = g_hash_table_lookup (repository->priv->metadata, namespace); + + if (metadata) + n_interfaces = ((Header *)metadata->data)->n_local_entries; + } + else + { + g_hash_table_foreach (repository->priv->metadata, + count_interfaces, &n_interfaces); + } + + return n_interfaces; +} + +typedef struct +{ + gint index; + const gchar *name; + const gchar *type; + GIBaseInfo *iface; +} IfaceData; + +static void +find_interface (gpointer key, + gpointer value, + gpointer data) +{ + gint i; + GMetadata *metadata = (GMetadata *)value; + IfaceData *iface_data = (IfaceData *)data; + gint index; + gint n_entries; + guint32 offset; + const gchar *name; + const gchar *type; + DirEntry *entry; + + index = 0; + n_entries = ((Header *)metadata->data)->n_local_entries; + + if (iface_data->name) + { + for (i = 1; i <= n_entries; i++) + { + entry = g_metadata_get_dir_entry (metadata, i); + name = g_metadata_get_string (metadata, entry->name); + if (strcmp (name, iface_data->name) == 0) + { + index = i; + break; + } + } + } + else if (iface_data->type) + { + for (i = 1; i <= n_entries; i++) + { + entry = g_metadata_get_dir_entry (metadata, i); + if (entry->blob_type < 4) + continue; + + offset = *(guint32*)&metadata->data[entry->offset + 8]; + type = g_metadata_get_string (metadata, offset); + if (strcmp (type, iface_data->type) == 0) + { + index = i; + break; + } + } + } + else if (iface_data->index > n_entries) + iface_data->index -= n_entries; + else if (iface_data->index > 0) + { + index = iface_data->index; + iface_data->index = 0; + } + + if (index != 0) + { + entry = g_metadata_get_dir_entry (metadata, index); + iface_data->iface = g_info_new (entry->blob_type, NULL, + metadata, entry->offset); + } +} + +GIBaseInfo * +g_irepository_get_info (GIRepository *repository, + const gchar *namespace, + gint index) +{ + IfaceData data; + + data.name = NULL; + data.type = NULL; + data.index = index + 1; + data.iface = NULL; + + if (namespace) + { + GMetadata *metadata; + + metadata = g_hash_table_lookup (repository->priv->metadata, namespace); + + if (metadata) + find_interface ((void *)namespace, metadata, &data); + } + else + g_hash_table_foreach (repository->priv->metadata, find_interface, &data); + + return data.iface; +} + +GIBaseInfo * +g_irepository_find_by_gtype (GIRepository *repository, + GType type) +{ + IfaceData data; + + data.name = NULL; + data.type = g_type_name (type); + data.index = -1; + data.iface = NULL; + + g_hash_table_foreach (repository->priv->metadata, find_interface, &data); + + return data.iface; +} + +GIBaseInfo * +g_irepository_find_by_name (GIRepository *repository, + const gchar *namespace, + const gchar *name) +{ + IfaceData data; + + data.name = name; + data.type = NULL; + data.index = -1; + data.iface = NULL; + + if (namespace) + { + GMetadata *metadata; + + metadata = g_hash_table_lookup (repository->priv->metadata, namespace); + + if (metadata) + find_interface ((void *)namespace, metadata, &data); + } + else + g_hash_table_foreach (repository->priv->metadata, find_interface, &data); + + return data.iface; +} + +static void +collect_namespaces (gpointer key, + gpointer value, + gpointer data) +{ + GList **list = data; + + *list = g_list_append (*list, key); +} + +gchar ** +g_irepository_get_namespaces (GIRepository *repository) +{ + GList *l, *list = NULL; + gchar **names; + gint i; + + g_hash_table_foreach (repository->priv->metadata, collect_namespaces, &list); + + names = g_malloc0 (sizeof (gchar *) * (g_list_length (list) + 1)); + i = 0; + for (l = list; l; l = l->next) + names[i++] = g_strdup (l->data); + g_list_free (list); + + return names; +} + +const gchar * +g_irepository_get_shared_library (GIRepository *repository, + const gchar *namespace) +{ + GMetadata *metadata; + Header *header; + + metadata = g_hash_table_lookup (repository->priv->metadata, namespace); + if (!metadata) + return NULL; + header = (Header *) metadata->data; + if (header->shared_library) + return g_metadata_get_string (metadata, header->shared_library); + else + return NULL; +} + +static inline void +g_irepository_build_search_path (void) +{ + gchar **dir; + gchar **tokens; + + if (g_getenv ("GIREPOPATH")) { + gchar *path; + path = g_strconcat (g_getenv ("GIREPOPATH"), ":", GIREPO_DEFAULT_SEARCH_PATH, NULL); + tokens = g_strsplit (path, ":", 0); + g_free (path); + } else + tokens = g_strsplit (GIREPO_DEFAULT_SEARCH_PATH, ":", 0); + + search_path = g_slist_prepend (search_path, "."); + for (dir = tokens; *dir; ++dir) + search_path = g_slist_prepend (search_path, *dir); + search_path = g_slist_reverse (search_path); + g_free (tokens); +} + +const gchar * +g_irepository_register_file (GIRepository *repository, + const gchar *namespace, + GError **error) +{ + GSList *ldir; + const char *dir; + gchar *fname, *full_path; + GMappedFile *mfile; + GError *error1 = NULL; + GMetadata *metadata = NULL; + const gchar *metadata_namespace, *shlib_fname; + GModule *module; + guint32 shlib; + GHashTable *table; + + if (repository != NULL) + table = repository->priv->metadata; + else + table = default_metadata; + + /* don't bother loading a namespace if already registered */ + if (g_hash_table_lookup (table, namespace)) + return NULL; + + if (search_path == NULL) + g_irepository_build_search_path (); + + fname = g_strconcat (namespace, ".repo", NULL); + + for (ldir = search_path; ldir; ldir = ldir->next) { + dir = ldir->data; + full_path = g_build_filename (dir, fname, NULL); + mfile = g_mapped_file_new (full_path, FALSE, &error1); + if (error1) { + g_debug ("Failed to mmap \"%s\"", full_path); + g_clear_error (&error1); + g_free (full_path); + continue; + } + g_free (full_path); + metadata = g_metadata_new_from_mapped_file (mfile); + metadata_namespace = g_metadata_get_string (metadata, ((Header *) metadata->data)->namespace); + if (strcmp (metadata_namespace, namespace) != 0) { + g_set_error (error, G_IREPOSITORY_ERROR, + G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH, + "Metadata file %s for namespace '%s' contains namespace '%s'" + " which doesn't match the file name", + full_path, namespace, metadata_namespace); + return NULL; + } + break; + } + g_free (fname); + if (metadata == NULL) { + g_set_error (error, G_IREPOSITORY_ERROR, + G_IREPOSITORY_ERROR_METADATA_NOT_FOUND, + "Metadata file for namespace '%s' was not found in search" + " path or could not be openened", namespace); + return NULL; + } + /* optionally load shared library and attach it to the metadata */ + shlib = ((Header *) metadata->data)->shared_library; + if (shlib) { + shlib_fname = g_metadata_get_string (metadata, shlib); + module = g_module_open (shlib_fname, G_MODULE_BIND_LAZY|G_MODULE_BIND_LOCAL); + if (module == NULL) { + g_set_error (error, G_IREPOSITORY_ERROR, + G_IREPOSITORY_ERROR_METADATA_NOT_FOUND, + "Metadata for namespace '%s' references shared library %s," + " but it could not be openened (%s)", + namespace, shlib_fname, g_module_error ()); + return NULL; + } + } + + g_hash_table_remove (table, namespace); + return g_irepository_register (repository, metadata); +} + + +GQuark +g_irepository_error_quark (void) +{ + static GQuark quark = 0; + if (quark == 0) + quark = g_quark_from_static_string ("g-irepository-error-quark"); + return quark; +} diff --git a/girepository.h b/girepository.h new file mode 100644 index 000000000..7ad1067a1 --- /dev/null +++ b/girepository.h @@ -0,0 +1,452 @@ +/* GObject introspection: Repository + * + * Copyright (C) 2005 Matthias Clasen + * + * 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_IREPOSITORY_H__ +#define __G_IREPOSITORY_H__ + +#include +#include + +G_BEGIN_DECLS + +#define G_TYPE_IREPOSITORY (g_irepository_get_type ()) +#define G_IREPOSITORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_IREPOSITORY, GIRepository)) + +typedef struct _GIRepository GIRepository; +typedef struct _GIRepositoryClass GIRepositoryClass; +typedef struct _GIRepositoryPrivate GIRepositoryPrivate; +typedef struct _GIBaseInfo GIBaseInfo; +typedef struct _GICallableInfo GICallableInfo; +typedef struct _GIFunctionInfo GIFunctionInfo; +typedef struct _GICallbackInfo GICallbackInfo; +typedef struct _GIRegisteredTypeInfo GIRegisteredTypeInfo; +typedef struct _GIStructInfo GIStructInfo; +typedef struct _GIUnionInfo GIUnionInfo; +typedef struct _GIEnumInfo GIEnumInfo; +typedef struct _GIObjectInfo GIObjectInfo; +typedef struct _GIInterfaceInfo GIInterfaceInfo; +typedef struct _GIConstantInfo GIConstantInfo; +typedef struct _GIValueInfo GIValueInfo; +typedef struct _GISignalInfo GISignalInfo; +typedef struct _GIVFuncInfo GIVFuncInfo; +typedef struct _GIPropertyInfo GIPropertyInfo; +typedef struct _GIFieldInfo GIFieldInfo; +typedef struct _GIArgInfo GIArgInfo; +typedef struct _GITypeInfo GITypeInfo; +typedef struct _GIErrorDomainInfo GIErrorDomainInfo; +typedef struct _GIUnresolvedInfo GIUnresolvedInfo; +typedef struct _GMetadata GMetadata; + +struct _GIRepository +{ + GObject parent; + + /*< private >*/ + GIRepositoryPrivate *priv; +}; + +struct _GIRepositoryClass +{ + GObjectClass parent; +}; + + +/* Repository */ + +GType g_irepository_get_type (void) G_GNUC_CONST; +GIRepository *g_irepository_get_default (void); +const gchar * g_irepository_register (GIRepository *repository, + GMetadata *metadata); +void g_irepository_unregister (GIRepository *repository, + const gchar *namespace); +const gchar * g_irepository_register_file (GIRepository *repository, + const gchar *filename, + GError **error); +gboolean g_irepository_is_registered (GIRepository *repository, + const gchar *namespace); +GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, + const gchar *namespace, + const gchar *name); +gchar ** g_irepository_get_namespaces (GIRepository *repository); +GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository, + GType gtype); +gint g_irepository_get_n_infos (GIRepository *repository, + const gchar *namespace); +GIBaseInfo * g_irepository_get_info (GIRepository *repository, + const gchar *namespace, + gint index); +const gchar * g_irepository_get_shared_library (GIRepository *repository, + const gchar *namespace); +/* Metadata */ + +GMetadata * g_metadata_new_from_memory (guchar *memory, + gsize len); +GMetadata * g_metadata_new_from_const_memory (const guchar *memory, + gsize len); +GMetadata * g_metadata_new_from_mapped_file (GMappedFile *mfile); +void g_metadata_free (GMetadata *metadata); +void g_metadata_set_module (GMetadata *metadata, + GModule *module); +const gchar * g_metadata_get_namespace (GMetadata *metadata); + +typedef enum +{ + G_IREPOSITORY_ERROR_METADATA_NOT_FOUND, + G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH, + G_IREPOSITORY_ERROR_LIBRARY_NOT_FOUND +} GIRepositoryError; + +#define G_IREPOSITORY_ERROR (g_irepository_error_quark ()) + +GQuark g_irepository_error_quark (void); + + +/* Types of objects registered in the repository */ + +typedef enum +{ + GI_INFO_TYPE_INVALID, + GI_INFO_TYPE_FUNCTION, + GI_INFO_TYPE_CALLBACK, + GI_INFO_TYPE_STRUCT, + GI_INFO_TYPE_BOXED, + GI_INFO_TYPE_ENUM, + GI_INFO_TYPE_FLAGS, + GI_INFO_TYPE_OBJECT, + GI_INFO_TYPE_INTERFACE, + GI_INFO_TYPE_CONSTANT, + GI_INFO_TYPE_ERROR_DOMAIN, + GI_INFO_TYPE_UNION, + GI_INFO_TYPE_VALUE, + GI_INFO_TYPE_SIGNAL, + GI_INFO_TYPE_VFUNC, + GI_INFO_TYPE_PROPERTY, + GI_INFO_TYPE_FIELD, + GI_INFO_TYPE_ARG, + GI_INFO_TYPE_TYPE, + GI_INFO_TYPE_UNRESOLVED +} GIInfoType; + + +/* GIBaseInfo */ + +GIBaseInfo * g_base_info_ref (GIBaseInfo *info); +void g_base_info_unref (GIBaseInfo *info); +GIInfoType g_base_info_get_type (GIBaseInfo *info); +const gchar * g_base_info_get_name (GIBaseInfo *info); +const gchar * g_base_info_get_namespace (GIBaseInfo *info); +gboolean g_base_info_is_deprecated (GIBaseInfo *info); +const gchar * g_base_info_get_annotation (GIBaseInfo *info, + const gchar *name); +GIBaseInfo * g_base_info_get_container (GIBaseInfo *info); +GMetadata * g_base_info_get_metadata (GIBaseInfo *info); + +GIBaseInfo * g_info_new (GIInfoType type, + GIBaseInfo *container, + GMetadata *metadata, + guint32 offset); + + +/* GIFunctionInfo */ + +typedef enum +{ + GI_FUNCTION_IS_METHOD = 1 << 0, + GI_FUNCTION_IS_CONSTRUCTOR = 1 << 1, + GI_FUNCTION_IS_GETTER = 1 << 2, + GI_FUNCTION_IS_SETTER = 1 << 3, + GI_FUNCTION_WRAPS_VFUNC = 1 << 4 +} GIFunctionInfoFlags; + +const gchar * g_function_info_get_symbol (GIFunctionInfo *info); +GIFunctionInfoFlags g_function_info_get_flags (GIFunctionInfo *info); +GIPropertyInfo * g_function_info_get_property (GIFunctionInfo *info); +GIVFuncInfo * g_function_info_get_vfunc (GIFunctionInfo *info); + +typedef union +{ + gboolean v_boolean; + gint8 v_int8; + guint8 v_uint8; + gint16 v_int16; + guint16 v_uint16; + gint32 v_int32; + guint32 v_uint32; + gint64 v_int64; + guint64 v_uint64; + gfloat v_float; + gdouble v_double; + gint v_int; + guint v_uint; + glong v_long; + gulong v_ulong; + gssize v_ssize; + gsize v_size; + gchar * v_string; + gpointer v_pointer; +} GArgument; + +#define G_INVOKE_ERROR (g_invoke_error_quark ()) +GQuark g_invoke_error_quark (void); + +typedef enum +{ + G_INVOKE_ERROR_FAILED, + G_INVOKE_ERROR_SYMBOL_NOT_FOUND, + G_INVOKE_ERROR_ARGUMENT_MISMATCH +} GInvokeError; + +gboolean g_function_info_invoke (GIFunctionInfo *info, + const GArgument *in_args, + int n_in_args, + const GArgument *out_args, + int n_out_args, + GArgument *return_value, + GError **error); + + +/* GICallableInfo */ + +typedef enum { + GI_TRANSFER_NOTHING, + GI_TRANSFER_CONTAINER, + GI_TRANSFER_EVERYTHING +} GITransfer; + +GITypeInfo * g_callable_info_get_return_type (GICallableInfo *info); +GITransfer g_callable_info_get_caller_owns (GICallableInfo *info); +gboolean g_callable_info_may_return_null (GICallableInfo *info); +gint g_callable_info_get_n_args (GICallableInfo *info); +GIArgInfo * g_callable_info_get_arg (GICallableInfo *info, + gint n); + +/* GIArgInfo */ + +typedef enum { + GI_DIRECTION_IN, + GI_DIRECTION_OUT, + GI_DIRECTION_INOUT +} GIDirection; + +GIDirection g_arg_info_get_direction (GIArgInfo *info); +gboolean g_arg_info_is_dipper (GIArgInfo *info); +gboolean g_arg_info_is_return_value (GIArgInfo *info); +gboolean g_arg_info_is_optional (GIArgInfo *info); +gboolean g_arg_info_may_be_null (GIArgInfo *info); +GITransfer g_arg_info_get_ownership_transfer (GIArgInfo *info); +GITypeInfo * g_arg_info_get_type (GIArgInfo *info); + + +/* GITypeInfo */ + +typedef enum { + GI_TYPE_TAG_VOID = 0, + GI_TYPE_TAG_BOOLEAN = 1, + GI_TYPE_TAG_INT8 = 2, + GI_TYPE_TAG_UINT8 = 3, + GI_TYPE_TAG_INT16 = 4, + GI_TYPE_TAG_UINT16 = 5, + GI_TYPE_TAG_INT32 = 6, + GI_TYPE_TAG_UINT32 = 7, + GI_TYPE_TAG_INT64 = 8, + GI_TYPE_TAG_UINT64 = 9, + GI_TYPE_TAG_INT = 10, + GI_TYPE_TAG_UINT = 11, + GI_TYPE_TAG_LONG = 12, + GI_TYPE_TAG_ULONG = 13, + GI_TYPE_TAG_SSIZE = 14, + GI_TYPE_TAG_SIZE = 15, + GI_TYPE_TAG_FLOAT = 16, + GI_TYPE_TAG_DOUBLE = 17, + GI_TYPE_TAG_UTF8 = 18, + GI_TYPE_TAG_FILENAME = 19, + 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, + GI_TYPE_TAG_ERROR = 25 +} GITypeTag; + +gboolean g_type_info_is_pointer (GITypeInfo *info); +GITypeTag g_type_info_get_tag (GITypeInfo *info); +GITypeInfo * g_type_info_get_param_type (GITypeInfo *info, + gint n); +GIBaseInfo * g_type_info_get_interface (GITypeInfo *info); +gint g_type_info_get_array_length (GITypeInfo *info); +gboolean g_type_info_is_zero_terminated (GITypeInfo *info); + +gint g_type_info_get_n_error_domains (GITypeInfo *info); +GIErrorDomainInfo *g_type_info_get_error_domain (GITypeInfo *info, + gint n); + +/* GIErrorDomainInfo */ + +const gchar * g_error_domain_info_get_quark (GIErrorDomainInfo *info); +GIInterfaceInfo * g_error_domain_info_get_codes (GIErrorDomainInfo *info); + + +/* GIValueInfo */ + +glong g_value_info_get_value (GIValueInfo *info); + + +/* GIFieldInfo */ + +typedef enum +{ + GI_FIELD_IS_READABLE = 1 << 0, + GI_FIELD_IS_WRITABLE = 1 << 1 +} GIFieldInfoFlags; + +GIFieldInfoFlags g_field_info_get_flags (GIFieldInfo *info); +gint g_field_info_get_size (GIFieldInfo *info); +gint g_field_info_get_offset (GIFieldInfo *info); +GITypeInfo * g_field_info_get_type (GIFieldInfo *info); + + +/* GIUnionInfo */ +gint g_union_info_get_n_fields (GIUnionInfo *info); +GIFieldInfo * g_union_info_get_field (GIUnionInfo *info, + gint n); +gint g_union_info_get_n_methods (GIUnionInfo *info); +GIFunctionInfo * g_union_info_get_method (GIUnionInfo *info, + gint n); +gboolean g_union_info_is_discriminated (GIUnionInfo *info); +gint g_union_info_get_discriminator_offset (GIUnionInfo *info); +GITypeInfo * g_union_info_get_discriminator_type (GIUnionInfo *info); +GIConstantInfo * g_union_info_get_discriminator (GIUnionInfo *info, + gint n); + + +/* GIStructInfo */ +gint g_struct_info_get_n_fields (GIStructInfo *info); +GIFieldInfo * g_struct_info_get_field (GIStructInfo *info, + gint n); +gint g_struct_info_get_n_methods (GIStructInfo *info); +GIFunctionInfo * g_struct_info_get_method (GIStructInfo *info, + gint n); +GIFunctionInfo * g_struct_info_find_method (GIStructInfo *info, + const gchar *name); + +/* GIRegisteredTypeInfo */ + +const gchar * g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info); +const gchar * g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info); + + +/* GIEnumInfo */ + +gint g_enum_info_get_n_values (GIEnumInfo *info); +GIValueInfo * g_enum_info_get_value (GIEnumInfo *info, + gint n); + +/* GIObjectInfo */ + +const gchar * g_object_info_get_type_name (GIObjectInfo *info); +const gchar * g_object_info_get_type_init (GIObjectInfo *info); +GIObjectInfo * g_object_info_get_parent (GIObjectInfo *info); +gint g_object_info_get_n_interfaces (GIObjectInfo *info); +GIInterfaceInfo * g_object_info_get_interface (GIObjectInfo *info, + gint n); +gint g_object_info_get_n_fields (GIObjectInfo *info); +GIFieldInfo * g_object_info_get_field (GIObjectInfo *info, + gint n); +gint g_object_info_get_n_properties (GIObjectInfo *info); +GIPropertyInfo * g_object_info_get_property (GIObjectInfo *info, + gint n); +gint g_object_info_get_n_methods (GIObjectInfo *info); +GIFunctionInfo * g_object_info_get_method (GIObjectInfo *info, + gint n); +GIFunctionInfo * g_object_info_find_method (GIObjectInfo *info, + const gchar *name); +gint g_object_info_get_n_signals (GIObjectInfo *info); +GISignalInfo * g_object_info_get_signal (GIObjectInfo *info, + gint n); +gint g_object_info_get_n_vfuncs (GIObjectInfo *info); +GIVFuncInfo * g_object_info_get_vfunc (GIObjectInfo *info, + gint n); +gint g_object_info_get_n_constants (GIObjectInfo *info); +GIConstantInfo * g_object_info_get_constant (GIObjectInfo *info, + gint n); + + +/* GIInterfaceInfo */ + +gint g_interface_info_get_n_prerequisites (GIInterfaceInfo *info); +GIBaseInfo * g_interface_info_get_prerequisite (GIInterfaceInfo *info, + gint n); +gint g_interface_info_get_n_properties (GIInterfaceInfo *info); +GIPropertyInfo * g_interface_info_get_property (GIInterfaceInfo *info, + gint n); +gint g_interface_info_get_n_methods (GIInterfaceInfo *info); +GIFunctionInfo * g_interface_info_get_method (GIInterfaceInfo *info, + gint n); +GIFunctionInfo * g_interface_info_find_method (GIInterfaceInfo *info, + const gchar *name); +gint g_interface_info_get_n_signals (GIInterfaceInfo *info); +GISignalInfo * g_interface_info_get_signal (GIInterfaceInfo *info, + gint n); +gint g_interface_info_get_n_vfuncs (GIInterfaceInfo *info); +GIVFuncInfo * g_interface_info_get_vfunc (GIInterfaceInfo *info, + gint n); +gint g_interface_info_get_n_constants (GIInterfaceInfo *info); +GIConstantInfo * g_interface_info_get_constant (GIInterfaceInfo *info, + gint n); + + +/* GIPropertyInfo */ + +GParamFlags g_property_info_get_flags (GIPropertyInfo *info); +GITypeInfo * g_property_info_get_type (GIPropertyInfo *info); + + +/* GISignalInfo */ + +GSignalFlags g_signal_info_get_flags (GISignalInfo *info); +GIVFuncInfo * g_signal_info_get_class_closure (GISignalInfo *info); +gboolean g_signal_info_true_stops_emit (GISignalInfo *info); + + +/* GIVFuncInfo */ + +typedef enum +{ + GI_VFUNC_MUST_CHAIN_UP = 1 << 0, + GI_VFUNC_MUST_OVERRIDE = 1 << 1, + GI_VFUNC_MUST_NOT_OVERRIDE = 1 << 2 +} GIVFuncInfoFlags; + +GIVFuncInfoFlags g_vfunc_info_get_flags (GIVFuncInfo *info); +gint g_vfunc_info_get_offset (GIVFuncInfo *info); +GISignalInfo * g_vfunc_info_get_signal (GIVFuncInfo *info); + + +/* GIConstantInfo */ + +GITypeInfo * g_constant_info_get_type (GIConstantInfo *info); +gint g_constant_info_get_value (GIConstantInfo *info, + GArgument *value); + + +G_END_DECLS + +#endif /* __G_IREPOSITORY_H__ */ + diff --git a/gmetadata.c b/gmetadata.c new file mode 100644 index 000000000..b68039043 --- /dev/null +++ b/gmetadata.c @@ -0,0 +1,1876 @@ +/* GObject introspection: metadata validation, auxiliary functions + * related to the binary metadata format + * + * Copyright (C) 2005 Matthias Clasen + * + * 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" + + +#define ALIGN_VALUE(this, boundary) \ + (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) + + +DirEntry * +g_metadata_get_dir_entry (GMetadata *metadata, + guint16 index) +{ + Header *header = (Header *)metadata->data; + + return (DirEntry *)&metadata->data[header->directory + (index - 1) * header->entry_blob_size]; +} + +void +g_metadata_check_sanity (void) +{ + /* Check that struct layout is as we expect */ + g_assert (sizeof (Header) == 100); + g_assert (sizeof (DirEntry) == 12); + g_assert (sizeof (SimpleTypeBlob) == 4); + g_assert (sizeof (ArgBlob) == 12); + g_assert (sizeof (SignatureBlob) == 8); + g_assert (sizeof (CommonBlob) == 8); + g_assert (sizeof (FunctionBlob) == 16); + g_assert (sizeof (InterfaceTypeBlob) == 4); + g_assert (sizeof (ArrayTypeBlob) == 8); + g_assert (sizeof (ParamTypeBlob) == 4); + g_assert (sizeof (ErrorTypeBlob) == 4); + g_assert (sizeof (ErrorDomainBlob) == 16); + g_assert (sizeof (ValueBlob) == 12); + g_assert (sizeof (FieldBlob) == 12); + g_assert (sizeof (RegisteredTypeBlob) == 16); + g_assert (sizeof (StructBlob) == 20); + g_assert (sizeof (EnumBlob) == 20); + g_assert (sizeof (PropertyBlob) == 12); + g_assert (sizeof (SignalBlob) == 12); + g_assert (sizeof (VFuncBlob) == 16); + g_assert (sizeof (ObjectBlob) == 32); + g_assert (sizeof (InterfaceBlob) == 28); + g_assert (sizeof (ConstantBlob) == 20); + g_assert (sizeof (AnnotationBlob) == 12); + g_assert (sizeof (UnionBlob) == 28); +} + + +static gboolean +is_aligned (guint32 offset) +{ + return offset == ALIGN_VALUE (offset, 4); +} + +#define MAX_NAME_LEN 200 + +static gboolean +is_name (const guchar *data, guint32 offset) +{ + gchar *name; + + name = (gchar*)&data[offset]; + + if (!memchr (name, '\0', MAX_NAME_LEN)) + return FALSE; + + if (strspn (name, G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_") < strlen (name)) + return FALSE; + + return TRUE; +} + +static gboolean +validate_header (GMetadata *metadata, + GError **error) +{ + Header *header; + + if (metadata->len < sizeof (Header)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + header = (Header *)metadata->data; + + if (strncmp (header->magic, G_IDL_MAGIC, 16) != 0) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_HEADER, + "Magic string not found"); + return FALSE; + + } + + if (header->major_version != 1 || header->minor_version != 0) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_HEADER, + "Version mismatch"); + return FALSE; + + } + + if (header->n_entries < header->n_local_entries) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_HEADER, + "Inconsistent entry counts"); + return FALSE; + } + + if (header->size != metadata->len) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_HEADER, + "Metadata size mismatch"); + 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, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_HEADER, + "Misaligned directory"); + return FALSE; + } + + if (!is_aligned (header->annotations)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_HEADER, + "Misaligned annotations"); + return FALSE; + } + + if (header->annotations == 0 && header->n_annotations > 0) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_HEADER, + "Wrong number of annotations"); + return FALSE; + } + + if (!is_name (metadata->data, header->namespace)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_HEADER, + "Invalid namespace name"); + return FALSE; + } + + return TRUE; +} + +static gboolean validate_type_blob (GMetadata *metadata, + guint32 offset, + guint32 signature_offset, + gboolean return_type, + GError **error); + +static gboolean +validate_array_type_blob (GMetadata *metadata, + guint32 offset, + guint32 signature_offset, + gboolean return_type, + GError **error) +{ + ArrayTypeBlob *blob; + + 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", blob->tag); + return FALSE; + } + + /* FIXME validate length */ + + if (!validate_type_blob (metadata, + offset + G_STRUCT_OFFSET (ArrayTypeBlob, type), + 0, FALSE, error)) + return FALSE; + + return TRUE; +} + +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, + gboolean return_type, + gint n_params, + GError **error) +{ + ParamTypeBlob *blob; + gint i; + + blob = (ParamTypeBlob*)&metadata->data[offset]; + + if (!blob->pointer) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Pointer type exected for tag %d", blob->tag); + return FALSE; + } + + if (blob->n_types != n_params) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Parameter type number mismatch"); + return FALSE; + } + + for (i = 0; i < n_params; i++) + { + if (!validate_type_blob (metadata, + offset + sizeof (ParamTypeBlob) + + i * sizeof (SimpleTypeBlob), + 0, FALSE, error)) + return FALSE; + } + + return TRUE; +} + +static gboolean +validate_error_type_blob (GMetadata *metadata, + guint32 offset, + guint32 signature_offset, + gboolean return_type, + GError **error) +{ + ErrorTypeBlob *blob; + Header *header; + gint i; + DirEntry *entry; + + blob = (ErrorTypeBlob*)&metadata->data[offset]; + + header = (Header *)metadata->data; + + if (!blob->pointer) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Pointer type exected for tag %d", blob->tag); + return FALSE; + } + + for (i = 0; i < blob->n_domains; i++) + { + 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", blob->domains[i]); + return FALSE; + } + + 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)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Wrong blob type"); + return FALSE; + } + } + + return TRUE; +} + +static gboolean +validate_type_blob (GMetadata *metadata, + guint32 offset, + guint32 signature_offset, + gboolean return_type, + GError **error) +{ + SimpleTypeBlob *simple; + InterfaceTypeBlob *iface; + + simple = (SimpleTypeBlob *)&metadata->data[offset]; + + if (simple->reserved == 0 && + simple->reserved2 == 0) + { + if (simple->tag >= TYPE_TAG_ARRAY) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Wrong tag in simple type"); + return FALSE; + } + + 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", simple->tag); + return FALSE; + } + + return TRUE; + } + + 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_INTERFACE: + if (!validate_iface_type_blob (metadata, simple->offset, + signature_offset, return_type, error)) + return FALSE; + break; + case TYPE_TAG_LIST: + case TYPE_TAG_SLIST: + if (!validate_param_type_blob (metadata, simple->offset, + signature_offset, return_type, 1, error)) + return FALSE; + break; + case TYPE_TAG_HASH: + if (!validate_param_type_blob (metadata, simple->offset, + signature_offset, return_type, 2, error)) + return FALSE; + break; + case TYPE_TAG_ERROR: + if (!validate_error_type_blob (metadata, simple->offset, + signature_offset, return_type, error)) + return FALSE; + break; + default: + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Wrong tag in complex type"); + return FALSE; + } + + return TRUE; +} + +static gboolean +validate_arg_blob (GMetadata *metadata, + guint32 offset, + guint32 signature_offset, + GError **error) +{ + ArgBlob *blob; + + if (metadata->len < offset + sizeof (ArgBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (ArgBlob*) &metadata->data[offset]; + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid argument name"); + return FALSE; + } + + if (!validate_type_blob (metadata, + offset + G_STRUCT_OFFSET (ArgBlob, arg_type), + signature_offset, FALSE, error)) + return FALSE; + + return TRUE; +} + +static gboolean +validate_signature_blob (GMetadata *metadata, + guint32 offset, + GError **error) +{ + SignatureBlob *blob; + gint i; + + if (metadata->len < offset + sizeof (SignatureBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (SignatureBlob*) &metadata->data[offset]; + + if (blob->return_type.offset != 0) + { + if (!validate_type_blob (metadata, + offset + G_STRUCT_OFFSET (SignatureBlob, return_type), + offset, TRUE, error)) + return FALSE; + } + + for (i = 0; i < blob->n_arguments; i++) + { + if (!validate_arg_blob (metadata, + offset + sizeof (SignatureBlob) + + i * sizeof (ArgBlob), + offset, + error)) + return FALSE; + } + + /* FIXME check constraints on return_value */ + /* FIXME check array-length pairs */ + return TRUE; +} + +static gboolean +validate_function_blob (GMetadata *metadata, + guint32 offset, + guint16 container_type, + GError **error) +{ + FunctionBlob *blob; + + if (metadata->len < offset + sizeof (FunctionBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (FunctionBlob*) &metadata->data[offset]; + + if (blob->blob_type != BLOB_TYPE_FUNCTION) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Wrong blob type"); + return FALSE; + } + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid function name"); + return FALSE; + } + + if (!is_name (metadata->data, blob->symbol)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid function symbol"); + return FALSE; + } + + if (blob->constructor) + { + switch (container_type) + { + case BLOB_TYPE_BOXED: + case BLOB_TYPE_OBJECT: + case BLOB_TYPE_INTERFACE: + break; + default: + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Constructor not allowed"); + return FALSE; + } + } + + if (blob->setter || blob->getter || blob->wraps_vfunc) + { + switch (container_type) + { + case BLOB_TYPE_OBJECT: + case BLOB_TYPE_INTERFACE: + break; + default: + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Setter, getter or wrapper not allowed"); + return FALSE; + } + } + + if (blob->index) + { + if (!(blob->setter || blob->getter || blob->wraps_vfunc)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Must be setter, getter or wrapper"); + return FALSE; + } + } + + /* FIXME: validate index range */ + /* FIXME: validate "this" argument for methods */ + /* FIXME: validate return type for constructors */ + + if (!validate_signature_blob (metadata, blob->signature, error)) + return FALSE; + + return TRUE; +} + +static gboolean +validate_callback_blob (GMetadata *metadata, + guint32 offset, + GError **error) +{ + CallbackBlob *blob; + + if (metadata->len < offset + sizeof (CallbackBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (CallbackBlob*) &metadata->data[offset]; + + if (blob->blob_type != BLOB_TYPE_CALLBACK) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Wrong blob type"); + return FALSE; + } + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid callback name"); + return FALSE; + } + + if (!validate_signature_blob (metadata, blob->signature, error)) + return FALSE; + + return TRUE; +} + +static gboolean +validate_constant_blob (GMetadata *metadata, + guint32 offset, + GError **error) +{ + gint value_size[] = { + 0, 4, 1, 1, 2, 2, 4, 4, 8, 8, + sizeof (gint), sizeof (guint), + sizeof (glong), sizeof (gulong), + sizeof (gssize), sizeof (gsize), + sizeof (gfloat), sizeof (gdouble), + 0, 0 + }; + ConstantBlob *blob; + SimpleTypeBlob *type; + + if (metadata->len < offset + sizeof (ConstantBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (ConstantBlob*) &metadata->data[offset]; + + if (blob->blob_type != BLOB_TYPE_CONSTANT) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Wrong blob type"); + return FALSE; + } + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid constant name"); + return FALSE; + } + + if (!validate_type_blob (metadata, offset + G_STRUCT_OFFSET (ConstantBlob, type), + 0, FALSE, error)) + return FALSE; + + if (!is_aligned (blob->offset)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Misaligned constant value"); + return FALSE; + } + + type = (SimpleTypeBlob *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)]; + if (type->reserved == 0) + { + if (type->tag == 0) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Constant value type void"); + return FALSE; + } + + if (value_size[type->tag] != 0 && + blob->size != value_size[type->tag]) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Constant value size mismatch"); + return FALSE; + } + /* FIXME check string values */ + } + + return TRUE; +} + +static gboolean +validate_value_blob (GMetadata *metadata, + guint32 offset, + GError **error) +{ + ValueBlob *blob; + + if (metadata->len < offset + sizeof (ValueBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (ValueBlob*) &metadata->data[offset]; + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid value name"); + return FALSE; + } + + return TRUE; +} + +static gboolean +validate_field_blob (GMetadata *metadata, + guint32 offset, + GError **error) +{ + FieldBlob *blob; + + if (metadata->len < offset + sizeof (FieldBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (FieldBlob*) &metadata->data[offset]; + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid field name"); + return FALSE; + } + + if (!validate_type_blob (metadata, + offset + G_STRUCT_OFFSET (FieldBlob, type), + 0, FALSE, error)) + return FALSE; + + return TRUE; +} + +static gboolean +validate_property_blob (GMetadata *metadata, + guint32 offset, + GError **error) +{ + PropertyBlob *blob; + + if (metadata->len < offset + sizeof (PropertyBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (PropertyBlob*) &metadata->data[offset]; + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid property name"); + return FALSE; + } + + if (!validate_type_blob (metadata, + offset + G_STRUCT_OFFSET (PropertyBlob, type), + 0, FALSE, error)) + return FALSE; + + return TRUE; +} + +static gboolean +validate_signal_blob (GMetadata *metadata, + guint32 offset, + guint32 container_offset, + GError **error) +{ + SignalBlob *blob; + gint n_signals; + + if (metadata->len < offset + sizeof (SignalBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (SignalBlob*) &metadata->data[offset]; + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid signal name"); + return FALSE; + } + + if ((blob->run_first != 0) + + (blob->run_last != 0) + + (blob->run_cleanup != 0) != 1) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid signal run flags"); + return FALSE; + } + + if (blob->has_class_closure) + { + if (((CommonBlob*)&metadata->data[container_offset])->blob_type == BLOB_TYPE_OBJECT) + { + ObjectBlob *object; + + object = (ObjectBlob*)&metadata->data[container_offset]; + + n_signals = object->n_signals; + } + else + { + InterfaceBlob *iface; + + iface = (InterfaceBlob*)&metadata->data[container_offset]; + + n_signals = iface->n_signals; + } + + if (blob->class_closure >= n_signals) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid class closure index"); + return FALSE; + } + } + + if (!validate_signature_blob (metadata, blob->signature, error)) + return FALSE; + + return TRUE; +} + +static gboolean +validate_vfunc_blob (GMetadata *metadata, + guint32 offset, + guint32 container_offset, + GError **error) +{ + VFuncBlob *blob; + gint n_vfuncs; + + if (metadata->len < offset + sizeof (VFuncBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (VFuncBlob*) &metadata->data[offset]; + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid vfunc name"); + return FALSE; + } + + if (blob->class_closure) + { + if (((CommonBlob*)&metadata->data[container_offset])->blob_type == BLOB_TYPE_OBJECT) + { + ObjectBlob *object; + + object = (ObjectBlob*)&metadata->data[container_offset]; + + n_vfuncs = object->n_vfuncs; + } + else + { + InterfaceBlob *iface; + + iface = (InterfaceBlob*)&metadata->data[container_offset]; + + n_vfuncs = iface->n_vfuncs; + } + + if (blob->class_closure >= n_vfuncs) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid class closure index"); + return FALSE; + } + } + + if (!validate_signature_blob (metadata, blob->signature, error)) + return FALSE; + + return TRUE; +} + +static gboolean +validate_struct_blob (GMetadata *metadata, + guint32 offset, + guint16 blob_type, + GError **error) +{ + StructBlob *blob; + gint i; + + if (metadata->len < offset + sizeof (StructBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (StructBlob*) &metadata->data[offset]; + + if (blob->blob_type != blob_type) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Wrong blob type"); + return FALSE; + } + + if ((blob->blob_type == BLOB_TYPE_BOXED && blob->unregistered) || + (blob->blob_type == BLOB_TYPE_STRUCT && !blob->unregistered)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Registration/blob type mismatch"); + return FALSE; + } + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid struct name"); + return FALSE; + } + + if (blob_type == BLOB_TYPE_BOXED) + { + if (!is_name (metadata->data, blob->gtype_name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid boxed type name"); + return FALSE; + } + + if (!is_name (metadata->data, blob->gtype_init)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid boxed type init"); + 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) + + blob->n_methods * sizeof (FunctionBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + for (i = 0; i < blob->n_fields; i++) + { + if (!validate_field_blob (metadata, + offset + sizeof (StructBlob) + + i * sizeof (FieldBlob), + error)) + return FALSE; + } + + for (i = 0; i < blob->n_methods; i++) + { + if (!validate_function_blob (metadata, + offset + sizeof (StructBlob) + + blob->n_fields * sizeof (FieldBlob) + + i * sizeof (FunctionBlob), + blob_type, + error)) + return FALSE; + } + + return TRUE; +} + +static gboolean +validate_enum_blob (GMetadata *metadata, + guint32 offset, + guint16 blob_type, + GError **error) +{ + EnumBlob *blob; + ValueBlob *v1, *v2; + gint i, j; + + if (metadata->len < offset + sizeof (EnumBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (EnumBlob*) &metadata->data[offset]; + + if (blob->blob_type != blob_type) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Wrong blob type"); + return FALSE; + } + + if (!blob->unregistered) + { + if (!is_name (metadata->data, blob->gtype_name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid enum type name"); + return FALSE; + } + + if (!is_name (metadata->data, blob->gtype_init)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid enum type init"); + return FALSE; + } + } + else + { + if (blob->gtype_name || blob->gtype_init) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Gtype data in unregistered enum"); + return FALSE; + } + } + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid enum name"); + return FALSE; + } + + if (metadata->len < offset + sizeof (EnumBlob) + + blob->n_values * sizeof (ValueBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + for (i = 0; i < blob->n_values; i++) + { + if (!validate_value_blob (metadata, + offset + sizeof (EnumBlob) + + i * sizeof (ValueBlob), + error)) + return FALSE; + + v1 = (ValueBlob *)&metadata->data[offset + sizeof (EnumBlob) + + i * sizeof (ValueBlob)]; + for (j = 0; j < i; j++) + { + v2 = (ValueBlob *)&metadata->data[offset + sizeof (EnumBlob) + + j * sizeof (ValueBlob)]; + + if (v1->value == v2->value) + { + /* FIXME should this be an error ? */ + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Duplicate enum value"); + return FALSE; + } + } + } + + return TRUE; +} + +static gboolean +validate_object_blob (GMetadata *metadata, + guint32 offset, + GError **error) +{ + Header *header; + ObjectBlob *blob; + gint i; + guint32 offset2; + + header = (Header *)metadata->data; + + if (metadata->len < offset + sizeof (ObjectBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (ObjectBlob*) &metadata->data[offset]; + + if (blob->blob_type != BLOB_TYPE_OBJECT) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Wrong blob type"); + return FALSE; + } + + if (!is_name (metadata->data, blob->gtype_name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid object type name"); + return FALSE; + } + + if (!is_name (metadata->data, blob->gtype_init)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid object type init"); + return FALSE; + } + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid object name"); + return FALSE; + } + + if (blob->parent > header->n_entries) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid parent index"); + return FALSE; + } + + if (blob->parent != 0) + { + DirEntry *entry; + + entry = g_metadata_get_dir_entry (metadata, blob->parent); + if (entry->blob_type != BLOB_TYPE_OBJECT && + (entry->local || entry->blob_type != 0)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Parent not object"); + return FALSE; + } + } + + if (metadata->len < offset + sizeof (ObjectBlob) + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * sizeof (FieldBlob) + + blob->n_properties * sizeof (PropertyBlob) + + blob->n_methods * sizeof (FunctionBlob) + + blob->n_signals * sizeof (SignalBlob) + + blob->n_vfuncs * sizeof (VFuncBlob) + + blob->n_constants * sizeof (ConstantBlob)) + + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + offset2 = offset + sizeof (ObjectBlob); + + for (i = 0; i < blob->n_interfaces; i++, offset2 += 2) + { + guint16 iface; + DirEntry *entry; + + iface = *(guint16*)&metadata->data[offset2]; + if (iface == 0 || iface > header->n_entries) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid interface index"); + return FALSE; + } + + entry = g_metadata_get_dir_entry (metadata, iface); + + if (entry->blob_type != BLOB_TYPE_INTERFACE && + (entry->local || entry->blob_type != 0)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Not an interface"); + return FALSE; + } + } + + offset2 += 2 * (blob->n_interfaces %2); + + for (i = 0; i < blob->n_fields; i++, offset2 += sizeof (FieldBlob)) + { + if (!validate_field_blob (metadata, offset2, error)) + return FALSE; + } + + for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob)) + { + if (!validate_property_blob (metadata, offset2, error)) + return FALSE; + } + + for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob)) + { + if (!validate_function_blob (metadata, offset2, BLOB_TYPE_OBJECT, error)) + return FALSE; + } + + for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob)) + { + if (!validate_signal_blob (metadata, offset2, offset, error)) + return FALSE; + } + + for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob)) + { + if (!validate_vfunc_blob (metadata, offset2, offset, error)) + return FALSE; + } + + for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob)) + { + if (!validate_constant_blob (metadata, offset2, error)) + return FALSE; + } + + return TRUE; +} + +static gboolean +validate_interface_blob (GMetadata *metadata, + guint32 offset, + GError **error) +{ + Header *header; + InterfaceBlob *blob; + gint i; + guint32 offset2; + + header = (Header *)metadata->data; + + if (metadata->len < offset + sizeof (InterfaceBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + blob = (InterfaceBlob*) &metadata->data[offset]; + + if (blob->blob_type != BLOB_TYPE_INTERFACE) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Wrong blob type"); + return FALSE; + } + + if (!is_name (metadata->data, blob->gtype_name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid interface type name"); + return FALSE; + } + + if (!is_name (metadata->data, blob->gtype_init)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid interface type init"); + return FALSE; + } + + if (!is_name (metadata->data, blob->name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid interface name"); + return FALSE; + } + + if (metadata->len < offset + sizeof (InterfaceBlob) + + (blob->n_prerequisites + blob->n_prerequisites % 2) * 2 + + blob->n_properties * sizeof (PropertyBlob) + + blob->n_methods * sizeof (FunctionBlob) + + blob->n_signals * sizeof (SignalBlob) + + blob->n_vfuncs * sizeof (VFuncBlob) + + blob->n_constants * sizeof (ConstantBlob)) + + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + offset2 = offset + sizeof (InterfaceBlob); + + for (i = 0; i < blob->n_prerequisites; i++, offset2 += 2) + { + DirEntry *entry; + guint16 req; + + req = *(guint16*)&metadata->data[offset2]; + if (req == 0 || req > header->n_entries) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Invalid prerequisite index"); + return FALSE; + } + + entry = g_metadata_get_dir_entry (metadata, req); + if (entry->blob_type != BLOB_TYPE_INTERFACE && + entry->blob_type != BLOB_TYPE_OBJECT && + (entry->local || entry->blob_type != 0)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_BLOB, + "Not an interface or object"); + return FALSE; + } + } + + offset2 += 2 * (blob->n_prerequisites % 2); + + for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob)) + { + if (!validate_property_blob (metadata, offset2, error)) + return FALSE; + } + + for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob)) + { + if (!validate_function_blob (metadata, offset2, BLOB_TYPE_INTERFACE, error)) + return FALSE; + } + + for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob)) + { + if (!validate_signal_blob (metadata, offset2, offset, error)) + return FALSE; + } + + for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob)) + { + if (!validate_vfunc_blob (metadata, offset2, offset, error)) + return FALSE; + } + + for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob)) + { + if (!validate_constant_blob (metadata, offset2, error)) + return FALSE; + } + + return TRUE; +} + +static gboolean +validate_errordomain_blob (GMetadata *metadata, + guint32 offset, + GError **error) +{ + return TRUE; +} + +static gboolean +validate_union_blob (GMetadata *metadata, + guint32 offset, + GError **error) +{ + return TRUE; +} + +static gboolean +validate_blob (GMetadata *metadata, + guint32 offset, + GError **error) +{ + CommonBlob *common; + + if (metadata->len < offset + sizeof (CommonBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + common = (CommonBlob*)&metadata->data[offset]; + + switch (common->blob_type) + { + case BLOB_TYPE_FUNCTION: + if (!validate_function_blob (metadata, offset, 0, error)) + return FALSE; + break; + case BLOB_TYPE_CALLBACK: + if (!validate_callback_blob (metadata, offset, error)) + return FALSE; + break; + case BLOB_TYPE_STRUCT: + case BLOB_TYPE_BOXED: + if (!validate_struct_blob (metadata, offset, common->blob_type, error)) + return FALSE; + break; + case BLOB_TYPE_ENUM: + case BLOB_TYPE_FLAGS: + if (!validate_enum_blob (metadata, offset, common->blob_type, error)) + return FALSE; + break; + case BLOB_TYPE_OBJECT: + if (!validate_object_blob (metadata, offset, error)) + return FALSE; + break; + case BLOB_TYPE_INTERFACE: + if (!validate_interface_blob (metadata, offset, error)) + return FALSE; + break; + case BLOB_TYPE_CONSTANT: + if (!validate_constant_blob (metadata, offset, error)) + return FALSE; + break; + case BLOB_TYPE_ERROR_DOMAIN: + if (!validate_errordomain_blob (metadata, offset, error)) + return FALSE; + break; + case BLOB_TYPE_UNION: + if (!validate_union_blob (metadata, offset, error)) + return FALSE; + break; + default: + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_ENTRY, + "Invalid blob type"); + return FALSE; + } + + return TRUE; +} + +static gboolean +validate_directory (GMetadata *metadata, + GError **error) +{ + Header *header = (Header *)metadata->data; + DirEntry *entry; + gint i; + + if (metadata->len < header->directory + header->n_entries * sizeof (DirEntry)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + for (i = 0; i < header->n_entries; i++) + { + entry = g_metadata_get_dir_entry (metadata, i + 1); + + if (!is_name (metadata->data, entry->name)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_DIRECTORY, + "Invalid entry name"); + return FALSE; + } + + if ((entry->local && entry->blob_type == BLOB_TYPE_INVALID) || + entry->blob_type > BLOB_TYPE_UNION) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_DIRECTORY, + "Invalid entry type"); + return FALSE; + } + + if (i < header->n_local_entries) + { + if (!entry->local) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_DIRECTORY, + "Too few local directory entries"); + return FALSE; + } + + if (!is_aligned (entry->offset)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_DIRECTORY, + "Misaligned entry"); + return FALSE; + } + + if (!validate_blob (metadata, entry->offset, error)) + return FALSE; + } + else + { + if (entry->local) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_DIRECTORY, + "Too many local directory entries"); + return FALSE; + } + + if (!is_name (metadata->data, entry->offset)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID_DIRECTORY, + "Invalid namespace name"); + return FALSE; + } + } + } + + return TRUE; +} + +static gboolean +validate_annotations (GMetadata *metadata, + GError **error) +{ + Header *header = (Header *)metadata->data; + + if (header->size < header->annotations + header->n_annotations * sizeof (AnnotationBlob)) + { + g_set_error (error, + G_METADATA_ERROR, + G_METADATA_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + return TRUE; +} + +gboolean +g_metadata_validate (GMetadata *metadata, + GError **error) +{ + if (!validate_header (metadata, error)) + return FALSE; + + if (!validate_directory (metadata, error)) + return FALSE; + + if (!validate_annotations (metadata, error)) + return FALSE; + + return TRUE; +} + +GQuark +g_metadata_error_quark (void) +{ + static GQuark quark = 0; + if (quark == 0) + quark = g_quark_from_static_string ("g-metadata-error-quark"); + return quark; +} + + +static inline void +_g_metadata_init (GMetadata *metadata) +{ + Header *header; + + header = (Header *) metadata->data; + if (header->shared_library) + { + const gchar *shlib; + shlib = g_metadata_get_string (metadata, header->shared_library); + metadata->module = g_module_open (shlib, G_MODULE_BIND_LAZY|G_MODULE_BIND_LOCAL); + if (metadata->module == NULL) + g_warning ("Failed to load shared library referenced by the metadata: %s", + g_module_error ()); + } +} + +/** + * g_metadata_new_from_memory: + * @memory: address of memory chunk containing the metadata + * @len: length of memory chunk containing the metadata + * + * Creates a new #GMetadata from a memory location. The memory block + * pointed to by @metadata will be automatically g_free()d when the + * repository is destroyed. + * + * Return value: the new #GMetadata + **/ +GMetadata * +g_metadata_new_from_memory (guchar *memory, gsize len) +{ + GMetadata *meta; + + meta = g_new0 (GMetadata, 1); + meta->data = memory; + meta->len = len; + meta->owns_memory = TRUE; + _g_metadata_init (meta); + return meta; +} + +/** + * g_metadata_new_from_const_memory: + * @memory: address of memory chunk containing the metadata + * @len: length of memory chunk containing the metadata + * + * Creates a new #GMetadata from a memory location. + * + * Return value: the new #GMetadata + **/ +GMetadata * +g_metadata_new_from_const_memory (const guchar *memory, gsize len) +{ + GMetadata *meta; + + meta = g_new0 (GMetadata, 1); + meta->data = (guchar *) memory; + meta->len = len; + meta->owns_memory = FALSE; + _g_metadata_init (meta); + return meta; +} + +/** + * g_metadata_new_from_mapped_file: + * @mfile: a #GMappedFile, that will be free'd when the repository is destroyed + * + * Creates a new #GMetadata from a #GMappedFile. + * + * Return value: the new #GMetadata + **/ +GMetadata * +g_metadata_new_from_mapped_file (GMappedFile *mfile) +{ + GMetadata *meta; + + meta = g_new0 (GMetadata, 1); + meta->mfile = mfile; + meta->owns_memory = FALSE; + meta->data = (guchar *) g_mapped_file_get_contents (mfile); + meta->len = g_mapped_file_get_length (mfile); + _g_metadata_init (meta); + return meta; +} + +/** + * g_metadata_free: + * @metadata: a #GMetadata + * + * Free a #GMetadata. + **/ +void +g_metadata_free (GMetadata *metadata) +{ + if (metadata->mfile) + g_mapped_file_free (metadata->mfile); + else + if (metadata->owns_memory) + g_free (metadata->data); + if (metadata->module) + g_module_close (metadata->module); + g_free (metadata); +} + +/** + * g_metadata_set_module: + * @metadata: a #GMetadata instance + * @module: a #GModule; takes ownership of this module + * + * Sets the target module for all symbols referenced by the metadata. + **/ +void +g_metadata_set_module (GMetadata *metadata, GModule *module) +{ + if (metadata->module) + g_module_close (metadata->module); + metadata->module = module; +} + +const gchar * +g_metadata_get_namespace(GMetadata *metadata) +{ + return g_metadata_get_string (metadata, ((Header *) metadata->data)->namespace); +} diff --git a/gmetadata.h b/gmetadata.h new file mode 100644 index 000000000..a22ee235e --- /dev/null +++ b/gmetadata.h @@ -0,0 +1,549 @@ +/* GObject introspection: struct definitions for the binary + * metadata format, validation + * + * Copyright (C) 2005 Matthias Clasen + * + * 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_METADATA_H__ +#define __G_METADATA_H__ + +#include +#include "girepository.h" + +G_BEGIN_DECLS + +#define G_IDL_MAGIC "GOBJ\nMETADATA\r\n\032" + +enum +{ + BLOB_TYPE_INVALID, + BLOB_TYPE_FUNCTION, + BLOB_TYPE_CALLBACK, + BLOB_TYPE_STRUCT, + BLOB_TYPE_BOXED, + BLOB_TYPE_ENUM, + BLOB_TYPE_FLAGS, + BLOB_TYPE_OBJECT, + BLOB_TYPE_INTERFACE, + BLOB_TYPE_CONSTANT, + BLOB_TYPE_ERROR_DOMAIN, + BLOB_TYPE_UNION +}; + +typedef struct +{ + gchar magic[16]; + guint8 major_version; + guint8 minor_version; + guint16 reserved; + guint16 n_entries; + guint16 n_local_entries; + guint32 directory; + guint32 n_annotations; + guint32 annotations; + + guint32 size; + guint32 namespace; + guint32 shared_library; + + guint16 entry_blob_size; + guint16 function_blob_size; + guint16 callback_blob_size; + guint16 signal_blob_size; + guint16 vfunc_blob_size; + guint16 arg_blob_size; + guint16 property_blob_size; + guint16 field_blob_size; + guint16 value_blob_size; + guint16 annotation_blob_size; + guint16 constant_blob_size; + guint16 error_domain_blob_size; + + guint16 signature_blob_size; + guint16 enum_blob_size; + guint16 struct_blob_size; + guint16 object_blob_size; + guint16 interface_blob_size; + guint16 union_blob_size; + + guint16 padding[7]; +} Header; + +typedef struct +{ + guint16 blob_type; + + guint local : 1; + guint reserved :15; + + guint32 name; + guint32 offset; +} DirEntry; + + +#define TYPE_POINTER_MASK 1 << 7 +#define TYPE_TAG_MASK 63 + +typedef enum +{ + TYPE_TAG_VOID = 0, + TYPE_TAG_BOOLEAN = 1, + TYPE_TAG_INT8 = 2, + TYPE_TAG_UINT8 = 3, + TYPE_TAG_INT16 = 4, + TYPE_TAG_UINT16 = 5, + TYPE_TAG_INT32 = 6, + TYPE_TAG_UINT32 = 7, + TYPE_TAG_INT64 = 8, + TYPE_TAG_UINT64 = 9, + TYPE_TAG_INT = 10, + TYPE_TAG_UINT = 11, + TYPE_TAG_LONG = 12, + TYPE_TAG_ULONG = 13, + TYPE_TAG_SSIZE = 14, + TYPE_TAG_SIZE = 15, + TYPE_TAG_FLOAT = 16, + TYPE_TAG_DOUBLE = 17, + TYPE_TAG_UTF8 = 18, + TYPE_TAG_FILENAME = 19, + 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 union +{ + struct + { + guint reserved : 8; + guint reserved2 :16; + guint pointer : 1; + guint reserved3 : 2; + guint tag : 5; + }; + guint32 offset; +} SimpleTypeBlob; + + +typedef struct +{ + guint32 name; + + guint in : 1; + guint out : 1; + guint dipper : 1; + guint null_ok : 1; + guint optional : 1; + guint transfer_ownership : 1; + guint transfer_container_ownership : 1; + guint return_value : 1; + guint reserved :24; + + SimpleTypeBlob arg_type; +} ArgBlob; + +typedef struct +{ + SimpleTypeBlob return_type; + + guint may_return_null : 1; + guint caller_owns_return_value : 1; + guint caller_owns_return_container : 1; + guint reserved :13; + + guint16 n_arguments; + + ArgBlob arguments[]; +} SignatureBlob; + +typedef struct +{ + guint16 blob_type; /* 1 */ + + guint deprecated : 1; + guint reserved :15; + + guint32 name; +} CommonBlob; + +typedef struct +{ + guint16 blob_type; /* 1 */ + + guint deprecated : 1; + guint setter : 1; + guint getter : 1; + guint constructor : 1; + guint wraps_vfunc : 1; + guint reserved : 1; + guint index :10; + + guint32 name; + guint32 symbol; + guint32 signature; +} FunctionBlob; + +typedef struct +{ + guint16 blob_type; /* 2 */ + + guint deprecated : 1; + guint reserved :15; + + guint32 name; + guint32 signature; +} CallbackBlob; + +typedef struct +{ + guint pointer :1; + guint reserved :2; + guint tag :5; + guint8 reserved2; + guint16 interface; +} InterfaceTypeBlob; + +typedef struct +{ + guint pointer :1; + guint reserved :2; + guint tag :5; + + guint zero_terminated :1; + guint has_length :1; + guint reserved2 :6; + + guint16 length; + + SimpleTypeBlob type; +} ArrayTypeBlob; + +typedef struct +{ + guint pointer :1; + guint reserved :2; + guint tag :5; + + guint8 reserved2; + guint16 n_types; + + SimpleTypeBlob type[]; +} ParamTypeBlob; + +typedef struct +{ + guint pointer :1; + guint reserved :2; + guint tag :5; + + guint8 reserved2; + guint16 n_domains; + + guint16 domains[]; +} ErrorTypeBlob; + +typedef struct +{ + guint16 blob_type; /* 10 */ + + guint deprecated : 1; + guint reserved :15; + + guint32 name; + + guint32 get_quark; + guint16 error_codes; + guint16 reserved2; +} ErrorDomainBlob; + +typedef struct +{ + guint deprecated : 1; + guint reserved :31; + guint32 name; + guint32 value; +} ValueBlob; + +typedef struct +{ + guint32 name; + + guint readable : 1; + guint writable : 1; + guint reserved : 6; + guint8 bits; + + guint16 struct_offset; + + SimpleTypeBlob type; +} FieldBlob; + +typedef struct +{ + guint16 blob_type; + guint deprecated : 1; + guint unregistered :15; + guint32 name; + + guint32 gtype_name; + guint32 gtype_init; +} RegisteredTypeBlob; + +typedef struct +{ + guint16 blob_type; + + guint deprecated : 1; + guint unregistered : 1; + guint reserved :14; + + guint32 name; + + guint32 gtype_name; + guint32 gtype_init; + + guint16 n_fields; + guint16 n_methods; + +#if 0 + /* variable-length parts of the blob */ + FieldBlob fields[]; + FunctionBlob methods[]; +#endif +} StructBlob; + +typedef struct +{ + guint16 blob_type; + guint deprecated : 1; + guint unregistered : 1; + guint discriminated : 1; + guint reserved :13; + guint32 name; + + guint32 gtype_name; + guint32 gtype_init; + + guint16 n_fields; + guint16 n_functions; + + gint32 discriminator_offset; + SimpleTypeBlob discriminator_type; + +#if 0 + FieldBlob fields[]; + FunctionBlob functions[]; + ConstantBlob discriminator_values[] +#endif +} UnionBlob; + +typedef struct +{ + guint16 blob_type; + + guint deprecated : 1; + guint unregistered : 1; + guint reserved :14; + + guint32 name; + + guint32 gtype_name; + guint32 gtype_init; + + guint16 n_values; + guint16 reserved2; + + ValueBlob values[]; +} EnumBlob; + +typedef struct +{ + guint32 name; + + guint deprecated : 1; + guint readable : 1; + guint writable : 1; + guint construct : 1; + guint construct_only : 1; + guint reserved :27; + + SimpleTypeBlob type; + +} PropertyBlob; + +typedef struct +{ + guint deprecated : 1; + guint run_first : 1; + guint run_last : 1; + guint run_cleanup : 1; + guint no_recurse : 1; + guint detailed : 1; + guint action : 1; + guint no_hooks : 1; + guint has_class_closure : 1; + guint true_stops_emit : 1; + guint reserved : 6; + + guint16 class_closure; + + guint32 name; + + guint32 signature; +} SignalBlob; + +typedef struct +{ + guint32 name; + + guint must_chain_up : 1; + guint must_be_implemented : 1; + guint must_not_be_implemented : 1; + guint class_closure : 1; + guint reserved :12; + guint16 signal; + + guint16 struct_offset; + guint16 reserved2; + guint32 signature; +} VFuncBlob; + +typedef struct +{ + guint16 blob_type; /* 7 */ + guint deprecated : 1; + guint reserved :15; + guint32 name; + + guint32 gtype_name; + guint32 gtype_init; + + guint16 parent; + + guint16 n_interfaces; + guint16 n_fields; + guint16 n_properties; + guint16 n_methods; + guint16 n_signals; + guint16 n_vfuncs; + guint16 n_constants; + + guint16 interfaces[]; + +#if 0 + /* variable-length parts of the blob */ + FieldBlob fields[]; + PropertyBlob properties[]; + FunctionBlob methods[]; + SignalBlob signals[]; + VFuncBlob vfuncs[]; + ConstantBlob constants[]; +#endif +} ObjectBlob; + +typedef struct +{ + guint16 blob_type; + guint deprecated : 1; + guint reserved :15; + guint32 name; + + guint32 gtype_name; + guint32 gtype_init; + + guint16 n_prerequisites; + guint16 n_properties; + guint16 n_methods; + guint16 n_signals; + guint16 n_vfuncs; + guint16 n_constants; + + guint16 prerequisites[]; + +#if 0 + /* variable-length parts of the blob */ + PropertyBlob properties[]; + FunctionBlob methods[]; + SignalBlob signals[]; + VFuncBlob vfuncs[]; + ConstantBlob constants[]; +#endif +} InterfaceBlob; + + +typedef struct +{ + guint16 blob_type; + guint deprecated : 1; + guint reserved :15; + guint32 name; + + SimpleTypeBlob type; + + guint32 size; + guint32 offset; +} ConstantBlob; + +typedef struct +{ + guint32 offset; + guint32 name; + guint32 value; +} AnnotationBlob; + + +struct _GMetadata { + guchar *data; + gsize len; + gboolean owns_memory; + GMappedFile *mfile; + GModule *module; +}; + +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, + G_METADATA_ERROR_INVALID_HEADER, + G_METADATA_ERROR_INVALID_DIRECTORY, + G_METADATA_ERROR_INVALID_ENTRY, + G_METADATA_ERROR_INVALID_BLOB +} GMetadataError; + +#define G_METADATA_ERROR (g_metadata_error_quark ()) + +GQuark g_metadata_error_quark (void); + +gboolean g_metadata_validate (GMetadata *metadata, + GError **error); + + +G_END_DECLS + +#endif /* __G_METADATA_H__ */ + From abcc72d5eff18e0dbaff99a5e6ed233d90d7e14e Mon Sep 17 00:00:00 2001 From: Rob Taylor Date: Fri, 8 Feb 2008 18:09:05 +0000 Subject: [PATCH 002/692] Added: 2008-02-08 Rob Taylor * Makefile.am: * configure.ac: * gcov.mak: Added: * girepository/Makefile.am: * m4/Makefile.am: Added: * m4/as-compiler-flag.m4: Added: * m4/gcov.m4: Added: * tools/Makefile.am: Add ability to generate a coverage report. Adds configure option --enable-gcov and make rule 'check-coverage'. svn path=/trunk/; revision=105 --- Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile.am b/Makefile.am index 480e95f6a..c79606efb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -14,3 +14,6 @@ libgirepository_la_CFLAGS = $(GIREPO_CFLAGS) girepodir = $(includedir)/glib-2.0/gobject-introspection girepo_HEADERS = girepository.h + +GCOV_SOURCES = $(libgirepository_la_SOURCES) +include $(top_srcdir)/gcov.mak From dbdadab6240e375e9fefb60172a655afcfac63d9 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 10 Feb 2008 19:19:15 +0000 Subject: [PATCH 003/692] Make 'make distcheck' work again. 2008-02-10 Johan Dahlin * Makefile.am: * configure.ac: * girepository/Makefile.am: Make 'make distcheck' work again. svn path=/trunk/; revision=110 --- Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index c79606efb..b15f033b8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,7 @@ ## Process this file with automake to produce Makefile.in +include $(top_srcdir)/gcov.mak + INCLUDES = -DGIREPO_DEFAULT_SEARCH_PATH="\"$(libdir)\"" lib_LTLIBRARIES = libgirepository.la @@ -16,4 +18,3 @@ girepodir = $(includedir)/glib-2.0/gobject-introspection girepo_HEADERS = girepository.h GCOV_SOURCES = $(libgirepository_la_SOURCES) -include $(top_srcdir)/gcov.mak From 1d764c63ccd26e714ac40a2dd4548cb94eba6514 Mon Sep 17 00:00:00 2001 From: Rob Taylor Date: Wed, 13 Feb 2008 17:31:59 +0000 Subject: [PATCH 004/692] Rename GCOV_SOURCES to GCOVSOURCES to top automake complaining. 2008-02-13 Rob Taylor * gcov.mak: * girepository/Makefile.am: * tools/Makefile.am: Rename GCOV_SOURCES to GCOVSOURCES to top automake complaining. svn path=/trunk/; revision=113 --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index b15f033b8..2bb0e1bcd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,4 +17,4 @@ libgirepository_la_CFLAGS = $(GIREPO_CFLAGS) girepodir = $(includedir)/glib-2.0/gobject-introspection girepo_HEADERS = girepository.h -GCOV_SOURCES = $(libgirepository_la_SOURCES) +GCOVSOURCES = $(libgirepository_la_SOURCES) From 2fb6877346d865d7e051a38032942a4a8aae7b9a Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Wed, 5 Mar 2008 17:10:28 +0000 Subject: [PATCH 005/692] Take advantage of a libffi.pc if one exists, as it does on Fedora 8. Make 2008-03-05 Havoc Pennington * configure.ac: Take advantage of a libffi.pc if one exists, as it does on Fedora 8. Make libffi a hard requirement, since it was in practice anyway (was not really conditional in the code or makefile, only in configure). svn path=/trunk/; revision=121 --- Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 2bb0e1bcd..74e5ada59 100644 --- a/Makefile.am +++ b/Makefile.am @@ -12,7 +12,8 @@ libgirepository_la_SOURCES = \ gmetadata.c \ ginfo.c \ ginvoke.c -libgirepository_la_CFLAGS = $(GIREPO_CFLAGS) +libgirepository_la_CPPFLAGS = $(GIREPO_CFLAGS) +libgirepository_la_LIBADD = $(GIREPO_LIBS) girepodir = $(includedir)/glib-2.0/gobject-introspection girepo_HEADERS = girepository.h From d349902ce637d4b327057cd96cd27aa0a7c8e966 Mon Sep 17 00:00:00 2001 From: Mark Doffman Date: Mon, 10 Mar 2008 17:44:06 +0000 Subject: [PATCH 006/692] girepository/ginvoke.c girepository/girepository.h 2008-02-21 Mark Doffman * girepository/ginvoke.c * girepository/girepository.h * girepository/gmetadata.c * girepository/gmetadata.h * tools/generate.c * tools/gidlparser.c Modify TYPE_TAG_INTERFACE to TYPE_TAG_SYMBOL to avoid confusion with the interface blob. * tools/generate.c * tools/gidlparser.c Remove magic numbers and replace with type-tag enumeration symbols. * girepository/gmetadata.c Add validate declaration. WARNING: This commit does not compile. It is a partial change. svn path=/trunk/; revision=129 --- ginvoke.c | 2 +- girepository.h | 4 ++-- gmetadata.c | 11 ++++++++--- gmetadata.h | 8 ++------ 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/ginvoke.c b/ginvoke.c index 986ca7850..6324536aa 100644 --- a/ginvoke.c +++ b/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.h b/girepository.h index 7ad1067a1..179d85fcd 100644 --- a/girepository.h +++ b/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_ARRAY = 20, - GI_TYPE_TAG_INTERFACE = 21, + GI_TYPE_TAG_SYMBOL = 20, + GI_TYPE_TAG_ARRAY = 21, GI_TYPE_TAG_GLIST = 22, GI_TYPE_TAG_GSLIST = 23, GI_TYPE_TAG_GHASH = 24, diff --git a/gmetadata.c b/gmetadata.c index b68039043..d49347066 100644 --- a/gmetadata.c +++ b/gmetadata.c @@ -30,6 +30,11 @@ #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, @@ -419,9 +424,9 @@ validate_type_blob (GMetadata *metadata, signature_offset, return_type, error)) return FALSE; break; - case TYPE_TAG_INTERFACE: - if (!validate_iface_type_blob (metadata, simple->offset, - signature_offset, return_type, error)) + case TYPE_TAG_SYMBOL: + if (!validate_blob (metadata, simple->offset, + error)) return FALSE; break; case TYPE_TAG_LIST: diff --git a/gmetadata.h b/gmetadata.h index a22ee235e..f300d8e92 100644 --- a/gmetadata.h +++ b/gmetadata.h @@ -95,10 +95,6 @@ typedef struct guint32 offset; } DirEntry; - -#define TYPE_POINTER_MASK 1 << 7 -#define TYPE_TAG_MASK 63 - typedef enum { TYPE_TAG_VOID = 0, @@ -121,8 +117,8 @@ typedef enum TYPE_TAG_DOUBLE = 17, TYPE_TAG_UTF8 = 18, TYPE_TAG_FILENAME = 19, - TYPE_TAG_ARRAY = 20, - TYPE_TAG_INTERFACE = 21, + TYPE_TAG_SYMBOL = 20, + TYPE_TAG_ARRAY = 21, TYPE_TAG_LIST = 22, TYPE_TAG_SLIST = 23, TYPE_TAG_HASH = 24, From 9713aa96d744691ffa34cbb643f3c785511f1ed7 Mon Sep 17 00:00:00 2001 From: Mark Doffman Date: Mon, 10 Mar 2008 17:45:59 +0000 Subject: [PATCH 007/692] tools/gidlcompilercontext.c tools/gidlcompilercontext.h 2008-02-21 Mark Doffman * tools/gidlcompilercontext.c * tools/gidlcompilercontext.h * tools/gidlcompilerentrynode.c * tools/gidlcompilerentrynode.h * tools/gidlcompilertypenode.c * tools/gidlcompilertypenode.h Add code to compile a tree of GIdlNodes to a 'C' struct representing the metadata. This is to aid cross-compiling. Previously the g-idl-compiler created a binary blob with data written in the byte order and alignment of the tool rather than the intended target. Cleaned up and improved by Johan and Robert :-) WARNING: This commit does not compile. It is a partial change. svn path=/trunk/; revision=130 --- gmetadata.h | 1 + 1 file changed, 1 insertion(+) diff --git a/gmetadata.h b/gmetadata.h index f300d8e92..144c6a454 100644 --- a/gmetadata.h +++ b/gmetadata.h @@ -28,6 +28,7 @@ G_BEGIN_DECLS #define G_IDL_MAGIC "GOBJ\nMETADATA\r\n\032" +#define G_IDL_MAGIC_ESCAPED "GOBJ\\nMETADATA\\r\\n\\032" enum { From 0f2b1089ad4cf9d853b36462af01992cb9f969c3 Mon Sep 17 00:00:00 2001 From: Mark Doffman Date: Mon, 10 Mar 2008 17:46:58 +0000 Subject: [PATCH 008/692] girepository/ginfo.c girepository/gmetadata.c girepository/gmetadata.h 2008-02-21 Mark Doffman * girepository/ginfo.c * girepository/gmetadata.c * girepository/gmetadata.h Change the metadata format to have a standard header for all the type blobs. Merge the SimpleTypeBlob and InterfaceTypeBlob into a union. A union of these two blobs existed previously but was not explicit in the metadata format. WARNING: This commit does not compile. It is a partial change. svn path=/trunk/; revision=131 --- ginfo.c | 176 ++++++++++++++++++++++++---------------------------- gmetadata.c | 99 ++++++++++++----------------- gmetadata.h | 49 ++++++--------- 3 files changed, 137 insertions(+), 187 deletions(-) diff --git a/ginfo.c b/ginfo.c index 6d66de21b..0537654c1 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1,4 +1,4 @@ -/* GObject introspection: Repository implementation +data[offset]; + TypeHeader *header; + SimpleTypeBlob *simple; - return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, metadata, - type->reserved == 0 ? offset : type->offset); + header = (TypeHeader *)&metadata->data[offset]; + if (TYPE_IS_COMPLEX (header->tag)) + { + simple = (SimpleTypeBlob *)&metadata->data[offset]; + offset = simple->offset; + } + + return (GITypeInfo*)g_info_new (GI_INFO_TYPE_TYPE, container, + metadata, offset); } /** @@ -721,32 +733,18 @@ gboolean g_type_info_is_pointer (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - 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; - } + TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; + + return header->pointer != 0; } GITypeTag g_type_info_get_tag (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; - if (type->reserved == 0) - return type->tag; - else - { - InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->metadata->data[base->offset]; - - return iface->tag; - } + return header->tag; } GITypeInfo * @@ -754,42 +752,39 @@ g_type_info_get_param_type (GITypeInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; - - if (type->reserved != 0) - { - ParamTypeBlob *param = (ParamTypeBlob *)&base->metadata->data[base->offset]; + TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; + ParamTypeBlob *param = (ParamTypeBlob *)&base->metadata->data[base->offset]; - 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: ; - } + switch (header->tag) + { + 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; } - - return NULL; + + g_assert_not_reached (); } GIBaseInfo * g_type_info_get_interface (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; - - if (type->reserved != 0) - { - InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->metadata->data[base->offset]; - - if (blob->tag == GI_TYPE_TAG_INTERFACE) - return g_info_from_entry (base->metadata, blob->interface); - } + TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; + SimpleTypeBlob *simple = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + if (header->tag == TYPE_TAG_SYMBOL) + { + CommonBlob *common = (CommonBlob *)&base->metadata->data[simple->offset]; + return g_info_from_entry (base->metadata, simple->offset); + } return NULL; } @@ -797,19 +792,13 @@ gint g_type_info_get_array_length (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; - - if (type->reserved != 0) + 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) { - ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->metadata->data[base->offset]; - - if (blob->tag == GI_TYPE_TAG_ARRAY) - { - if (blob->has_length) - return blob->length; - } + return array->length; } - return -1; } @@ -817,33 +806,24 @@ gboolean g_type_info_is_zero_terminated (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; - - if (type->reserved != 0) - { - ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->metadata->data[base->offset]; + TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; + ArrayTypeBlob *array = (ArrayTypeBlob *)&base->metadata->data[base->offset]; - if (blob->tag == GI_TYPE_TAG_ARRAY) - return blob->zero_terminated; - } - - return FALSE; + return (header->tag == TYPE_TAG_ARRAY && + array->zero_terminated); } gint g_type_info_get_n_error_domains (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; - - if (type->reserved != 0) + TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; + ErrorTypeBlob *error = (ErrorTypeBlob *)&base->metadata->data[base->offset]; + + if (header->tag == TYPE_TAG_ERROR) { - ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->metadata->data[base->offset]; - - if (blob->tag == GI_TYPE_TAG_ERROR) - return blob->n_domains; + return error->n_domains; } - return 0; } @@ -852,17 +832,16 @@ g_type_info_get_error_domain (GITypeInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; - - if (type->reserved != 0) + TypeHeader *header = (TypeHeader *)&base->metadata->data[base->offset]; + ErrorTypeBlob *error = (ErrorTypeBlob *)&base->metadata->data[base->offset]; + guint16 *domain; + + if (header->tag == TYPE_TAG_ERROR) { - 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]); + domain = (guint16*) (&base->metadata->data[base->offset + sizeof(ErrorTypeBlob)]); + return (GIErrorDomainInfo *) g_info_from_entry (base->metadata, + domain[n]); } - return NULL; } @@ -883,7 +862,8 @@ g_error_domain_info_get_codes (GIErrorDomainInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset]; - return (GIInterfaceInfo *) g_info_from_entry (base->metadata, blob->error_codes); + return (GIInterfaceInfo *) g_info_from_entry (base->metadata, + blob->error_codes); } @@ -1010,8 +990,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); } @@ -1075,7 +1055,8 @@ 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 */ @@ -1125,7 +1106,8 @@ g_object_info_get_interface (GIObjectInfo *info, GIBaseInfo *base = (GIBaseInfo *)info; ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; - return (GIInterfaceInfo *) g_info_from_entry (base->metadata, blob->interfaces[n]); + return (GIInterfaceInfo *) g_info_from_entry (base->metadata, + blob->interfaces[n]); } gint @@ -1150,7 +1132,8 @@ 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 @@ -1572,7 +1555,8 @@ 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; } @@ -1803,4 +1787,4 @@ g_union_info_get_discriminator (GIUnionInfo *info, } return NULL; -} +} diff --git a/gmetadata.c b/gmetadata.c index d49347066..436969d00 100644 --- a/gmetadata.c +++ b/gmetadata.c @@ -234,17 +234,16 @@ validate_array_type_blob (GMetadata *metadata, gboolean return_type, GError **error) { - ArrayTypeBlob *blob; + ArrayTypeBlob *blob = (ArrayTypeBlob*)&metadata->data[offset]; + TypeHeader *header = (TypeHeader *)&metadata->data[offset]; - blob = (ArrayTypeBlob*)&metadata->data[offset]; - - if (!blob->pointer) + if (!header->pointer) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", blob->tag); - return FALSE; + "Pointer type exected for tag %d", header->tag); + return FALSE; } /* FIXME validate length */ @@ -257,32 +256,6 @@ validate_array_type_blob (GMetadata *metadata, return TRUE; } -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, @@ -291,17 +264,17 @@ validate_param_type_blob (GMetadata *metadata, gint n_params, GError **error) { - ParamTypeBlob *blob; + ParamTypeBlob *blob = (ParamTypeBlob*)&metadata->data[offset]; + TypeHeader *header = (TypeHeader *)&metadata->data[offset]; gint i; - blob = (ParamTypeBlob*)&metadata->data[offset]; - if (!blob->pointer) + if (!header->pointer) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", blob->tag); + "Pointer type exected for tag %d", header->tag); return FALSE; } @@ -334,35 +307,39 @@ 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 (!blob->pointer) + if (!type_header->pointer) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", blob->tag); - return FALSE; + "Pointer type exected for tag %d", type_header->tag); + return FALSE; } - for (i = 0; i < blob->n_domains; i++) + domain = (guint16*)&metadata->data[offset + sizeof(ErrorTypeBlob)]; + for (i = 0; i < blob->n_domains; i++, domain++) { - if (blob->domains[i] == 0 || blob->domains[i] > header->n_entries) + if (*domain == 0 || *domain > header->n_entries) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Invalid directory index %d", blob->domains[i]); + "Invalid directory index %d", *domain); return FALSE; } - entry = g_metadata_get_dir_entry (metadata, blob->domains[i]); + entry = g_metadata_get_dir_entry (metadata, *domain); if (entry->blob_type != BLOB_TYPE_ERROR_DOMAIN && (entry->local || entry->blob_type != BLOB_TYPE_INVALID)) @@ -386,14 +363,14 @@ validate_type_blob (GMetadata *metadata, GError **error) { SimpleTypeBlob *simple; - InterfaceTypeBlob *iface; - - simple = (SimpleTypeBlob *)&metadata->data[offset]; + TypeHeader *header; - if (simple->reserved == 0 && - simple->reserved2 == 0) + simple = (SimpleTypeBlob *)&metadata->data[offset]; + header = (TypeHeader *)&metadata->data[offset]; + + if (TYPE_IS_SIMPLE(header->tag)) { - if (simple->tag >= TYPE_TAG_ARRAY) + if (header->tag >= TYPE_TAG_ARRAY) { g_set_error (error, G_METADATA_ERROR, @@ -402,22 +379,20 @@ validate_type_blob (GMetadata *metadata, return FALSE; } - if (simple->tag >= TYPE_TAG_UTF8 && - !simple->pointer) + if (header->tag >= TYPE_TAG_UTF8 && + !header->pointer) { g_set_error (error, G_METADATA_ERROR, G_METADATA_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", simple->tag); - return FALSE; + "Pointer type exected for tag %d", header->tag); + return FALSE; } return TRUE; } - iface = (InterfaceTypeBlob*)&metadata->data[simple->offset]; - - switch (iface->tag) + switch (header->tag) { case TYPE_TAG_ARRAY: if (!validate_array_type_blob (metadata, simple->offset, @@ -691,6 +666,7 @@ validate_constant_blob (GMetadata *metadata, 0, 0 }; ConstantBlob *blob; + TypeHeader *header; SimpleTypeBlob *type; if (metadata->len < offset + sizeof (ConstantBlob)) @@ -734,11 +710,12 @@ validate_constant_blob (GMetadata *metadata, "Misaligned constant value"); return FALSE; } - + type = (SimpleTypeBlob *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)]; - if (type->reserved == 0) + header = (TypeHeader *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)]; + if (TYPE_IS_SIMPLE(header->tag)) { - if (type->tag == 0) + if (header->tag == 0) { g_set_error (error, G_METADATA_ERROR, @@ -747,8 +724,8 @@ validate_constant_blob (GMetadata *metadata, return FALSE; } - if (value_size[type->tag] != 0 && - blob->size != value_size[type->tag]) + if (value_size[header->tag] != 0 && + blob->size != value_size[header->tag]) { g_set_error (error, G_METADATA_ERROR, diff --git a/gmetadata.h b/gmetadata.h index 144c6a454..8c0f2b04d 100644 --- a/gmetadata.h +++ b/gmetadata.h @@ -126,20 +126,26 @@ typedef enum TYPE_TAG_ERROR = 25 } TypeTag; -typedef union +typedef struct { - struct - { - guint reserved : 8; - guint reserved2 :16; - guint pointer : 1; - guint reserved3 : 2; - guint tag : 5; - }; + 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; + guint32 offset; } SimpleTypeBlob; - typedef struct { guint32 name; @@ -209,25 +215,13 @@ typedef struct guint32 signature; } CallbackBlob; -typedef struct -{ - guint pointer :1; - guint reserved :2; - guint tag :5; - guint8 reserved2; - guint16 interface; -} InterfaceTypeBlob; - typedef struct { - guint pointer :1; - guint reserved :2; - guint tag :5; + TypeHeader header; guint zero_terminated :1; guint has_length :1; guint reserved2 :6; - guint16 length; SimpleTypeBlob type; @@ -235,9 +229,7 @@ typedef struct typedef struct { - guint pointer :1; - guint reserved :2; - guint tag :5; + TypeHeader header; guint8 reserved2; guint16 n_types; @@ -247,11 +239,8 @@ typedef struct typedef struct { - guint pointer :1; - guint reserved :2; - guint tag :5; + TypeHeader header; - guint8 reserved2; guint16 n_domains; guint16 domains[]; From 4ab667b160f860870a05bc54079c73758dcae7db Mon Sep 17 00:00:00 2001 From: Mark Doffman Date: Mon, 10 Mar 2008 17:47:20 +0000 Subject: [PATCH 009/692] girepository/ginfo.c girepository/girepository.h tools/generate.c 2008-02-21 Mark Doffman * girepository/ginfo.c * girepository/girepository.h * tools/generate.c Add a function to check if an enum is registered or not. Previously anything testing this relied on the g-type string offset having a value of 0. * girepository/gmetadata.c * girepository/gmetadata.h * tools/generate.c Remove unneccesary or erroneous checks. There were two metadata validation checks which made sure that the blob sizes were the same as some magic numbers compiled into the code. This is wrong as it breaks any forwards compatibility that may be possible. Checks were also present that made sure that unregistered type blobs had a value of 0 in the g-type offset field. This is unneccessary. If a type blob is unregistered then any value in its g-type field is simply invalid. WARNING: This commit does not compile. It is a partial change. svn path=/trunk/; revision=132 --- ginfo.c | 11 ++++++- girepository.h | 1 + gmetadata.c | 82 +------------------------------------------------- gmetadata.h | 3 -- 4 files changed, 12 insertions(+), 85 deletions(-) diff --git a/ginfo.c b/ginfo.c index 0537654c1..67385c354 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1,4 +1,4 @@ -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) diff --git a/girepository.h b/girepository.h index 179d85fcd..0c1ac6630 100644 --- a/girepository.h +++ b/girepository.h @@ -355,6 +355,7 @@ 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/gmetadata.c b/gmetadata.c index 436969d00..8c9827023 100644 --- a/gmetadata.c +++ b/gmetadata.c @@ -42,41 +42,9 @@ 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) { @@ -156,32 +124,6 @@ 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, @@ -1046,17 +988,6 @@ 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) + @@ -1142,17 +1073,6 @@ 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/gmetadata.h b/gmetadata.h index 8c0f2b04d..345749174 100644 --- a/gmetadata.h +++ b/gmetadata.h @@ -507,11 +507,8 @@ 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, From 7cd41630af4be69f1a5f256cd49c581e6bfade14 Mon Sep 17 00:00:00 2001 From: Mark Doffman Date: Mon, 10 Mar 2008 17:47:24 +0000 Subject: [PATCH 010/692] girepository/ginfo.c 2008-02-21 Mark Doffman * girepository/ginfo.c Add the ability to get the value of a constant of type TYPE_TAG_SYMBOL. In the case of a symbol the value is provided as a string. This would deal properly with: typedef char* random; const random = "A string"; WARNING: This commit does not compile. It is a partial change. svn path=/trunk/; revision=133 --- ginfo.c | 136 ++++++++++++++++++++++++++++------------------------ gmetadata.h | 18 ++++--- 2 files changed, 86 insertions(+), 68 deletions(-) diff --git a/ginfo.c b/ginfo.c index 67385c354..d803dc66d 100644 --- a/ginfo.c +++ b/ginfo.c @@ -860,10 +860,13 @@ GIInterfaceInfo * g_error_domain_info_get_codes (GIErrorDomainInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset]; - - return (GIInterfaceInfo *) g_info_from_entry (base->metadata, - blob->error_codes); + 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); } @@ -1114,9 +1117,11 @@ g_object_info_get_interface (GIObjectInfo *info, { GIBaseInfo *base = (GIBaseInfo *)info; ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + guint16 *interface; - return (GIInterfaceInfo *) g_info_from_entry (base->metadata, - blob->interfaces[n]); + interface = (guint16 *)&base->metadata->data[base->offset + sizeof(ObjectBlob)]; + + return (GIInterfaceInfo *) g_info_from_entry (base->metadata, interface[n]); } gint @@ -1324,8 +1329,11 @@ g_interface_info_get_prerequisite (GIInterfaceInfo *info, { GIBaseInfo *base = (GIBaseInfo *)info; InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + guint16 *prerequisite; - return g_info_from_entry (base->metadata, blob->prerequisites[n]); + prerequisite = (guint16 *)&base->metadata->data[base->offset + sizeof(InterfaceBlob)]; + + return g_info_from_entry (base->metadata, prerequisite[n]); } @@ -1639,63 +1647,67 @@ g_constant_info_get_value (GIConstantInfo *info, { GIBaseInfo *base = (GIBaseInfo *)info; ConstantBlob *blob = (ConstantBlob *)&base->metadata->data[base->offset]; + TypeHeader *header = (TypeHeader*) &blob->type; - /* FIXME non-basic types ? */ - if (blob->type.reserved == 0) + if (TYPE_IS_SIMPLE (header->tag)) { - 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; - } - } + 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 + { + switch (header->tag) + { + case GI_TYPE_TAG_SYMBOL: + value->v_string = *(gchar**)&base->metadata->data[blob->offset]; + break; + } } return blob->size; diff --git a/gmetadata.h b/gmetadata.h index 345749174..aa4166289 100644 --- a/gmetadata.h +++ b/gmetadata.h @@ -174,7 +174,9 @@ typedef struct guint16 n_arguments; +#if 0 ArgBlob arguments[]; +#endif } SignatureBlob; typedef struct @@ -233,8 +235,9 @@ typedef struct guint8 reserved2; guint16 n_types; - +#if 0 SimpleTypeBlob type[]; +#endif } ParamTypeBlob; typedef struct @@ -243,7 +246,9 @@ typedef struct guint16 n_domains; +#if 0 guint16 domains[]; +#endif } ErrorTypeBlob; typedef struct @@ -357,7 +362,9 @@ typedef struct guint16 n_values; guint16 reserved2; - ValueBlob values[]; +#if 0 + ValueBlob values[]; +#endif } EnumBlob; typedef struct @@ -432,10 +439,9 @@ 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[]; @@ -462,10 +468,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[]; From e8fa68458818aca51bb9c02ecd7ab5b7b1063fee Mon Sep 17 00:00:00 2001 From: Mark Doffman Date: Mon, 10 Mar 2008 17:47:26 +0000 Subject: [PATCH 011/692] girepository/ginfo.c tools/generate.c 2008-02-21 Mark Doffman * girepository/ginfo.c * tools/generate.c Change the way that external references with no namespace are dealt with. External references with no namespace are placed into the XML as-if they are a local reference. This is temporary, but helps with roundtrip tests. WARNING: This commit does not compile. It is a partial change. svn path=/trunk/; revision=134 --- ginfo.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/ginfo.c b/ginfo.c index d803dc66d..934961141 100644 --- a/ginfo.c +++ b/ginfo.c @@ -161,29 +161,35 @@ 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 = g_metadata_get_string (metadata, entry->offset); - const gchar *name = g_metadata_get_string (metadata, entry->name); - + const gchar *namespace = NULL; + const gchar *name = NULL; 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; - unresolved->namespace = namespace; - + if (entry->offset) + { + unresolved->namespace = namespace; + } + else + { + unresolved->namespace = NULL; + } result = (GIBaseInfo*)unresolved; } } From 4ff71171a93f7d7ba5258f46c0c6608a0d447281 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 22 Apr 2008 22:48:16 +0000 Subject: [PATCH 012/692] 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 --- ginfo.c | 335 ++++++++++++++++++++++++------------------------- ginvoke.c | 2 +- girepository.h | 5 +- gmetadata.c | 190 +++++++++++++++++++++------- gmetadata.h | 79 +++++++----- 5 files changed, 354 insertions(+), 257 deletions(-) diff --git a/ginfo.c b/ginfo.c index 934961141..6d66de21b 100644 --- a/ginfo.c +++ b/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; + SimpleTypeBlob *type = (SimpleTypeBlob *)&metadata->data[offset]; - header = (TypeHeader *)&metadata->data[offset]; - if (TYPE_IS_COMPLEX (header->tag)) - { - simple = (SimpleTypeBlob *)&metadata->data[offset]; - offset = simple->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]; - return header->tag; + if (type->reserved == 0) + return type->tag; + else + { + InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->metadata->data[base->offset]; + + 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)) + /* FIXME non-basic types ? */ + if (blob->type.reserved == 0) { - 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 - { - 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/ginvoke.c b/ginvoke.c index 6324536aa..986ca7850 100644 --- a/ginvoke.c +++ b/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.h b/girepository.h index 0c1ac6630..7ad1067a1 100644 --- a/girepository.h +++ b/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/gmetadata.c b/gmetadata.c index 8c9827023..b68039043 100644 --- a/gmetadata.c +++ b/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 */ @@ -198,6 +252,32 @@ validate_array_type_blob (GMetadata *metadata, return TRUE; } +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, @@ -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/gmetadata.h b/gmetadata.h index aa4166289..a22ee235e 100644 --- a/gmetadata.h +++ b/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, From db7b37822103833e1c8d90cc8907c89e6659abfd Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Wed, 23 Apr 2008 00:57:48 +0000 Subject: [PATCH 013/692] new function to get the GType given a RegisteredTypeInfo 2008-04-22 Havoc Pennington * girepository/ginfo.c (g_registered_type_info_get_g_type): new function to get the GType given a RegisteredTypeInfo svn path=/trunk/; revision=216 --- ginfo.c | 19 +++++++++++++++++++ girepository.h | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/ginfo.c b/ginfo.c index 6d66de21b..1707fa839 100644 --- a/ginfo.c +++ b/ginfo.c @@ -968,6 +968,25 @@ g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info) return NULL; } +GType +g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info) +{ + const char *type_init; + GType (* get_type_func) (void); + + type_init = g_registered_type_info_get_type_init (info); + + if (type_init == NULL) + return G_TYPE_NONE; + + get_type_func = NULL; + if (!g_module_symbol (((GIBaseInfo*)info)->metadata->module, + type_init, + (void**) &get_type_func)) + return G_TYPE_NONE; + + return (* get_type_func) (); +} /* GIStructInfo functions */ gint diff --git a/girepository.h b/girepository.h index 7ad1067a1..fa625aa2a 100644 --- a/girepository.h +++ b/girepository.h @@ -350,7 +350,7 @@ GIFunctionInfo * g_struct_info_find_method (GIStructInfo *info, const gchar * g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info); const gchar * g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info); - +GType g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info); /* GIEnumInfo */ From 54b6ec03fb70cb6c041eeb8326687e311f717fec Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Wed, 23 Apr 2008 01:04:43 +0000 Subject: [PATCH 014/692] remove G_MODULE_BIND_LOCAL flag when loading libraries, since some libs 2008-04-22 Havoc Pennington * girepository/gmetadata.c (_g_metadata_init): remove G_MODULE_BIND_LOCAL flag when loading libraries, since some libs (Glade and Clutter for example) rely on being loaded globally. svn path=/trunk/; revision=217 --- gmetadata.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/gmetadata.c b/gmetadata.c index b68039043..ac5619ac3 100644 --- a/gmetadata.c +++ b/gmetadata.c @@ -1759,8 +1759,18 @@ _g_metadata_init (GMetadata *metadata) if (header->shared_library) { const gchar *shlib; + + /* Glade's autoconnect feature and OpenGL's extension mechanism + * as used by Clutter rely on dlopen(NULL) to work as a means of + * accessing the app's symbols. This keeps us from using + * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well; + * in general libraries are not expecting multiple copies of + * themselves and are not expecting to be unloaded. So we just + * load modules globally for now. + */ + shlib = g_metadata_get_string (metadata, header->shared_library); - metadata->module = g_module_open (shlib, G_MODULE_BIND_LAZY|G_MODULE_BIND_LOCAL); + metadata->module = g_module_open (shlib, G_MODULE_BIND_LAZY); if (metadata->module == NULL) g_warning ("Failed to load shared library referenced by the metadata: %s", g_module_error ()); From 0ed924f676d010dcfe1ca267891177afa0b0dfeb Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Wed, 23 Apr 2008 01:07:05 +0000 Subject: [PATCH 015/692] Use interface_blob_size not object_blob_size to compute offset. 2008-04-22 Havoc Pennington * girepository/ginfo.c (g_interface_info_find_method): Use interface_blob_size not object_blob_size to compute offset. svn path=/trunk/; revision=218 --- ginfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ginfo.c b/ginfo.c index 1707fa839..4a2568e01 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1418,7 +1418,7 @@ g_interface_info_find_method (GIInterfaceInfo *info, Header *header = (Header *)base->metadata->data; InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; - offset = base->offset + header->object_blob_size + offset = base->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + blob->n_properties * header->property_blob_size; From 81f5d90cd53a97ad106eec277aafe9312e774ee5 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Wed, 23 Apr 2008 01:17:24 +0000 Subject: [PATCH 016/692] hack to avoid dlopening a library that is already in the main app, by 2008-04-22 Havoc Pennington * girepository/gmetadata.c (_g_metadata_init): hack to avoid dlopening a library that is already in the main app, by checking whether one of the lib's symbols is already loaded. svn path=/trunk/; revision=220 --- gmetadata.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 85 insertions(+), 12 deletions(-) diff --git a/gmetadata.c b/gmetadata.c index ac5619ac3..c33e6bffc 100644 --- a/gmetadata.c +++ b/gmetadata.c @@ -1749,6 +1749,43 @@ g_metadata_error_quark (void) return quark; } +static const char* +find_some_symbol (GMetadata *metadata) +{ + Header *header = (Header *) metadata->data; + gint i; + + for (i = 0; i < header->n_entries; i++) + { + DirEntry *entry; + + entry = g_metadata_get_dir_entry (metadata, i + 1); + + switch (entry->blob_type) + { + case BLOB_TYPE_FUNCTION: + { + FunctionBlob *blob = (FunctionBlob *) &metadata->data[entry->offset]; + + if (blob->symbol) + return g_metadata_get_string (metadata, blob->symbol); + } + break; + case BLOB_TYPE_OBJECT: + { + RegisteredTypeBlob *blob = (RegisteredTypeBlob *) &metadata->data[entry->offset]; + + if (blob->gtype_init) + return g_metadata_get_string (metadata, blob->gtype_init); + } + break; + default: + break; + } + } + + return NULL; +} static inline void _g_metadata_init (GMetadata *metadata) @@ -1760,20 +1797,56 @@ _g_metadata_init (GMetadata *metadata) { const gchar *shlib; - /* Glade's autoconnect feature and OpenGL's extension mechanism - * as used by Clutter rely on dlopen(NULL) to work as a means of - * accessing the app's symbols. This keeps us from using - * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well; - * in general libraries are not expecting multiple copies of - * themselves and are not expecting to be unloaded. So we just - * load modules globally for now. - */ - shlib = g_metadata_get_string (metadata, header->shared_library); - metadata->module = g_module_open (shlib, G_MODULE_BIND_LAZY); + /* note that NULL shlib means to open the main app, which is allowed */ + + /* If we do have a shared lib, first be sure the main app isn't already linked to it */ + if (shlib != NULL) + { + const char *symbol_in_module; + + symbol_in_module = find_some_symbol (metadata); + if (symbol_in_module != NULL) + { + metadata->module = g_module_open (NULL, G_MODULE_BIND_LAZY); + if (metadata->module == NULL) + { + g_warning ("Could not open main app as GModule: %s", + g_module_error ()); + } + else + { + void *sym; + if (!g_module_symbol (metadata->module, symbol_in_module, &sym)) + { + /* we will try opening the shlib, symbol is not in app already */ + g_module_close (metadata->module); + metadata->module = NULL; + } + } + } + else + { + g_warning ("Could not find any symbols in metadata"); + } + } + if (metadata->module == NULL) - g_warning ("Failed to load shared library referenced by the metadata: %s", - g_module_error ()); + { + /* Glade's autoconnect feature and OpenGL's extension mechanism + * as used by Clutter rely on dlopen(NULL) to work as a means of + * accessing the app's symbols. This keeps us from using + * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well; + * in general libraries are not expecting multiple copies of + * themselves and are not expecting to be unloaded. So we just + * load modules globally for now. + */ + + metadata->module = g_module_open (shlib, G_MODULE_BIND_LAZY); + if (metadata->module == NULL) + g_warning ("Failed to load shared library referenced by the metadata: %s", + g_module_error ()); + } } } From 624ac67933669d034bff982f6a9854f0b22fe292 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Wed, 23 Apr 2008 01:24:57 +0000 Subject: [PATCH 017/692] If a symbol is not in metadata->module, look for it in the global module, 2008-04-22 Havoc Pennington * girepository/ginvoke.c (g_function_info_invoke): If a symbol is not in metadata->module, look for it in the global module, in case some other object or the app itself provides the symbol. svn path=/trunk/; revision=221 --- ginvoke.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/ginvoke.c b/ginvoke.c index 986ca7850..26f3c5800 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -166,12 +166,36 @@ g_function_info_invoke (GIFunctionInfo *info, if (!g_module_symbol (g_base_info_get_metadata((GIBaseInfo *) info)->module, symbol, &func)) { - g_set_error (error, - G_INVOKE_ERROR, - G_INVOKE_ERROR_SYMBOL_NOT_FOUND, - "Could not locate %s: %s", symbol, g_module_error ()); - - return FALSE; + GModule *entire_app; + + /* + * We want to be able to add symbols to an app or an auxiliary + * library to fill in gaps in an introspected library. However, + * normally we would only look for symbols in the main library + * (metadata->module). + * + * A more elaborate solution is probably possible, but as a + * simple approach for now, if we fail to find a symbol we look + * for it in the global module. + * + * This would not be very efficient if it happened often, since + * we always do the failed lookup above first, but very few + * symbols should be outside of metadata->module so it doesn't + * matter. + */ + entire_app = g_module_open (NULL, 0); + if (!g_module_symbol (entire_app, symbol, &func)) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_SYMBOL_NOT_FOUND, + "Could not locate %s: %s", symbol, g_module_error ()); + + g_module_close (entire_app); + + return FALSE; + } + g_module_close (entire_app); } tinfo = g_callable_info_get_return_type ((GICallableInfo *)info); From df21818925a0f040c6347b3cb1912cf7643db03a Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 31 May 2008 20:49:42 +0000 Subject: [PATCH 018/692] Rename pkg-config name to gobject-introspection-1.0, Do not installed 2008-05-31 Johan Dahlin * Makefile.am: * configure.ac: * girepository/Makefile.am: * giscanner/transformer.py: * gobject-introspection-1.0.pc.in: * gobject-introspection.pc.in: * tools/Makefile.am: Rename pkg-config name to gobject-introspection-1.0, Do not installed anything which is not using the gir format. Disable compililation the old C scanner, but still keep the source until all the remaning functionallity has been ported. svn path=/trunk/; revision=277 --- Makefile.am | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index 74e5ada59..e95b3cd73 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,7 +4,7 @@ include $(top_srcdir)/gcov.mak INCLUDES = -DGIREPO_DEFAULT_SEARCH_PATH="\"$(libdir)\"" -lib_LTLIBRARIES = libgirepository.la +noinst_LTLIBRARIES = libgirepository.la libgirepository_la_SOURCES = \ girepository.c \ @@ -15,7 +15,8 @@ libgirepository_la_SOURCES = \ libgirepository_la_CPPFLAGS = $(GIREPO_CFLAGS) libgirepository_la_LIBADD = $(GIREPO_LIBS) -girepodir = $(includedir)/glib-2.0/gobject-introspection -girepo_HEADERS = girepository.h +#girepodir = $(includedir)/gobject-introspection-1.0/ +#girepo_HEADERS = girepository.h +noinst_HEADERS = girepository.h GCOVSOURCES = $(libgirepository_la_SOURCES) From 776ee5f79e32437277925240d0e17dae2dfabb0d Mon Sep 17 00:00:00 2001 From: Philip Van Hoof Date: Sun, 8 Jun 2008 14:37:30 +0000 Subject: [PATCH 019/692] tools/gidlnode.c 2008-06-08 Philip Van Hoof * girepository/girepository.c: * girepository/gtypelib.c: * girepository/ginfo.c: * girepository/ginvoke.c: * girepository/girepository.h: * girepository/gtypelib.h: * girepository/gmetadata.c: * girepository/Makefile.am: * girepository/gmetadata.h: * tools/compiler.c: * tools/gidlmodule.c: * tools/gidlnode.c * tools/generate.c: * tools/gidlmodule.h: * tools/gidlparser.c: Renamed GMetadata to GTypelib svn path=/trunk/; revision=288 --- Makefile.am | 4 +- ginfo.c | 50 ++-- ginvoke.c | 2 +- girepository.c | 46 ++-- girepository.h | 20 +- gmetadata.c => gtypelib.c | 534 +++++++++++++++++++------------------- gmetadata.h => gtypelib.h | 32 +-- 7 files changed, 344 insertions(+), 344 deletions(-) rename gmetadata.c => gtypelib.c (80%) rename gmetadata.h => gtypelib.h (94%) diff --git a/Makefile.am b/Makefile.am index e95b3cd73..9dd5e547f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,8 +8,8 @@ noinst_LTLIBRARIES = libgirepository.la libgirepository_la_SOURCES = \ girepository.c \ - gmetadata.h \ - gmetadata.c \ + gtypelib.h \ + gtypelib.c \ ginfo.c \ ginvoke.c libgirepository_la_CPPFLAGS = $(GIREPO_CFLAGS) diff --git a/ginfo.c b/ginfo.c index 4a2568e01..c54b39283 100644 --- a/ginfo.c +++ b/ginfo.c @@ -24,7 +24,7 @@ #include #include "girepository.h" -#include "gmetadata.h" +#include "gtypelib.h" struct _GIBaseInfo { @@ -32,7 +32,7 @@ struct _GIBaseInfo gint ref_count; GIBaseInfo *container; - GMetadata *metadata; + GTypelib *metadata; guint32 offset; }; @@ -136,7 +136,7 @@ struct _GIUnionInfo GIBaseInfo * g_info_new (GIInfoType type, GIBaseInfo *container, - GMetadata *metadata, + GTypelib *metadata, guint32 offset) { GIBaseInfo *info; @@ -156,18 +156,18 @@ g_info_new (GIInfoType type, } static GIBaseInfo * -g_info_from_entry (GMetadata *metadata, +g_info_from_entry (GTypelib *metadata, guint16 index) { GIBaseInfo *result; - DirEntry *entry = g_metadata_get_dir_entry (metadata, index); + DirEntry *entry = g_typelib_get_dir_entry (metadata, index); if (entry->local) result = g_info_new (entry->blob_type, NULL, metadata, entry->offset); else { - const gchar *namespace = g_metadata_get_string (metadata, entry->offset); - const gchar *name = g_metadata_get_string (metadata, entry->name); + const gchar *namespace = g_typelib_get_string (metadata, entry->offset); + const gchar *name = g_typelib_get_string (metadata, entry->name); GIRepository *repository = g_irepository_get_default (); @@ -240,7 +240,7 @@ g_base_info_get_name (GIBaseInfo *info) { CommonBlob *blob = (CommonBlob *)&info->metadata->data[info->offset]; - return g_metadata_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->metadata, blob->name); } break; @@ -248,7 +248,7 @@ g_base_info_get_name (GIBaseInfo *info) { ValueBlob *blob = (ValueBlob *)&info->metadata->data[info->offset]; - return g_metadata_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->metadata, blob->name); } break; @@ -256,7 +256,7 @@ g_base_info_get_name (GIBaseInfo *info) { SignalBlob *blob = (SignalBlob *)&info->metadata->data[info->offset]; - return g_metadata_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->metadata, blob->name); } break; @@ -264,7 +264,7 @@ g_base_info_get_name (GIBaseInfo *info) { PropertyBlob *blob = (PropertyBlob *)&info->metadata->data[info->offset]; - return g_metadata_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->metadata, blob->name); } break; @@ -272,7 +272,7 @@ g_base_info_get_name (GIBaseInfo *info) { VFuncBlob *blob = (VFuncBlob *)&info->metadata->data[info->offset]; - return g_metadata_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->metadata, blob->name); } break; @@ -280,7 +280,7 @@ g_base_info_get_name (GIBaseInfo *info) { FieldBlob *blob = (FieldBlob *)&info->metadata->data[info->offset]; - return g_metadata_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->metadata, blob->name); } break; @@ -288,7 +288,7 @@ g_base_info_get_name (GIBaseInfo *info) { ArgBlob *blob = (ArgBlob *)&info->metadata->data[info->offset]; - return g_metadata_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->metadata, blob->name); } break; @@ -320,7 +320,7 @@ g_base_info_get_namespace (GIBaseInfo *info) return unresolved->namespace; } - return g_metadata_get_string (info->metadata, header->namespace); + return g_typelib_get_string (info->metadata, header->namespace); } gboolean @@ -430,9 +430,9 @@ g_base_info_get_annotation (GIBaseInfo *info, { res = next; - rname = g_metadata_get_string (base->metadata, res->name); + rname = g_typelib_get_string (base->metadata, res->name); if (strcmp (name, rname) == 0) - return g_metadata_get_string (base->metadata, res->value); + return g_typelib_get_string (base->metadata, res->value); next = res += header->annotation_blob_size; } @@ -447,7 +447,7 @@ g_base_info_get_container (GIBaseInfo *info) return info->container; } -GMetadata * +GTypelib * g_base_info_get_metadata (GIBaseInfo *info) { return info->metadata; @@ -460,7 +460,7 @@ g_function_info_get_symbol (GIFunctionInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; FunctionBlob *blob = (FunctionBlob *)&base->metadata->data[base->offset]; - return g_metadata_get_string (base->metadata, blob->symbol); + return g_typelib_get_string (base->metadata, blob->symbol); } GIFunctionInfoFlags @@ -530,7 +530,7 @@ signature_offset (GICallableInfo *info) GITypeInfo * g_type_info_new (GIBaseInfo *container, - GMetadata *metadata, + GTypelib *metadata, guint32 offset) { SimpleTypeBlob *type = (SimpleTypeBlob *)&metadata->data[offset]; @@ -874,7 +874,7 @@ g_error_domain_info_get_quark (GIErrorDomainInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset]; - return g_metadata_get_string (base->metadata, blob->get_quark); + return g_typelib_get_string (base->metadata, blob->get_quark); } GIInterfaceInfo * @@ -951,7 +951,7 @@ g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info) RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->metadata->data[base->offset]; if (blob->gtype_name) - return g_metadata_get_string (base->metadata, blob->gtype_name); + return g_typelib_get_string (base->metadata, blob->gtype_name); return NULL; } @@ -963,7 +963,7 @@ g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info) RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->metadata->data[base->offset]; if (blob->gtype_init) - return g_metadata_get_string (base->metadata, blob->gtype_init); + return g_typelib_get_string (base->metadata, blob->gtype_init); return NULL; } @@ -1116,7 +1116,7 @@ g_object_info_get_type_name (GIObjectInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; - return g_metadata_get_string (base->metadata, blob->gtype_name); + return g_typelib_get_string (base->metadata, blob->gtype_name); } const gchar * @@ -1125,7 +1125,7 @@ g_object_info_get_type_init (GIObjectInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; - return g_metadata_get_string (base->metadata, blob->gtype_init); + return g_typelib_get_string (base->metadata, blob->gtype_init); } gint diff --git a/ginvoke.c b/ginvoke.c index 26f3c5800..d283b69f0 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -24,7 +24,7 @@ #include #include "girepository.h" -#include "gmetadata.h" +#include "gtypelib.h" #include "config.h" GQuark diff --git a/girepository.c b/girepository.c index c9b3b683c..c2b119cd7 100644 --- a/girepository.c +++ b/girepository.c @@ -26,7 +26,7 @@ #include #include #include "girepository.h" -#include "gmetadata.h" +#include "gtypelib.h" static GIRepository *default_repository = NULL; static GHashTable *default_metadata = NULL; @@ -34,7 +34,7 @@ static GSList *search_path = NULL; struct _GIRepositoryPrivate { - GHashTable *metadata; /* (string) namespace -> GMetadata */ + GHashTable *metadata; /* (string) namespace -> GTypelib */ }; G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT); @@ -70,7 +70,7 @@ g_irepository_class_init (GIRepositoryClass *class) const gchar * g_irepository_register (GIRepository *repository, - GMetadata *metadata) + GTypelib *metadata) { Header *header; const gchar *name; @@ -88,7 +88,7 @@ g_irepository_register (GIRepository *repository, if (repository->priv->metadata == NULL) repository->priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) NULL, - (GDestroyNotify) g_metadata_free); + (GDestroyNotify) g_typelib_free); table = repository->priv->metadata; } else @@ -96,11 +96,11 @@ g_irepository_register (GIRepository *repository, if (default_metadata == NULL) default_metadata = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) NULL, - (GDestroyNotify) g_metadata_free); + (GDestroyNotify) g_typelib_free); table = default_metadata; } - name = g_metadata_get_string (metadata, header->namespace); + name = g_typelib_get_string (metadata, header->namespace); if (g_hash_table_lookup (table, name)) { @@ -158,7 +158,7 @@ g_irepository_get_default (void) if (default_metadata == NULL) default_metadata = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) NULL, - (GDestroyNotify) g_metadata_free); + (GDestroyNotify) g_typelib_free); default_repository->priv->metadata = default_metadata; } @@ -170,7 +170,7 @@ count_interfaces (gpointer key, gpointer value, gpointer data) { - guchar *metadata = ((GMetadata *) value)->data; + guchar *metadata = ((GTypelib *) value)->data; gint *n_interfaces = (gint *)data; *n_interfaces += ((Header *)metadata)->n_local_entries; @@ -184,7 +184,7 @@ g_irepository_get_n_infos (GIRepository *repository, if (namespace) { - GMetadata *metadata; + GTypelib *metadata; metadata = g_hash_table_lookup (repository->priv->metadata, namespace); @@ -214,7 +214,7 @@ find_interface (gpointer key, gpointer data) { gint i; - GMetadata *metadata = (GMetadata *)value; + GTypelib *metadata = (GTypelib *)value; IfaceData *iface_data = (IfaceData *)data; gint index; gint n_entries; @@ -230,8 +230,8 @@ find_interface (gpointer key, { for (i = 1; i <= n_entries; i++) { - entry = g_metadata_get_dir_entry (metadata, i); - name = g_metadata_get_string (metadata, entry->name); + entry = g_typelib_get_dir_entry (metadata, i); + name = g_typelib_get_string (metadata, entry->name); if (strcmp (name, iface_data->name) == 0) { index = i; @@ -243,12 +243,12 @@ find_interface (gpointer key, { for (i = 1; i <= n_entries; i++) { - entry = g_metadata_get_dir_entry (metadata, i); + entry = g_typelib_get_dir_entry (metadata, i); if (entry->blob_type < 4) continue; offset = *(guint32*)&metadata->data[entry->offset + 8]; - type = g_metadata_get_string (metadata, offset); + type = g_typelib_get_string (metadata, offset); if (strcmp (type, iface_data->type) == 0) { index = i; @@ -266,7 +266,7 @@ find_interface (gpointer key, if (index != 0) { - entry = g_metadata_get_dir_entry (metadata, index); + entry = g_typelib_get_dir_entry (metadata, index); iface_data->iface = g_info_new (entry->blob_type, NULL, metadata, entry->offset); } @@ -286,7 +286,7 @@ g_irepository_get_info (GIRepository *repository, if (namespace) { - GMetadata *metadata; + GTypelib *metadata; metadata = g_hash_table_lookup (repository->priv->metadata, namespace); @@ -329,7 +329,7 @@ g_irepository_find_by_name (GIRepository *repository, if (namespace) { - GMetadata *metadata; + GTypelib *metadata; metadata = g_hash_table_lookup (repository->priv->metadata, namespace); @@ -374,7 +374,7 @@ const gchar * g_irepository_get_shared_library (GIRepository *repository, const gchar *namespace) { - GMetadata *metadata; + GTypelib *metadata; Header *header; metadata = g_hash_table_lookup (repository->priv->metadata, namespace); @@ -382,7 +382,7 @@ g_irepository_get_shared_library (GIRepository *repository, return NULL; header = (Header *) metadata->data; if (header->shared_library) - return g_metadata_get_string (metadata, header->shared_library); + return g_typelib_get_string (metadata, header->shared_library); else return NULL; } @@ -418,7 +418,7 @@ g_irepository_register_file (GIRepository *repository, gchar *fname, *full_path; GMappedFile *mfile; GError *error1 = NULL; - GMetadata *metadata = NULL; + GTypelib *metadata = NULL; const gchar *metadata_namespace, *shlib_fname; GModule *module; guint32 shlib; @@ -449,8 +449,8 @@ g_irepository_register_file (GIRepository *repository, continue; } g_free (full_path); - metadata = g_metadata_new_from_mapped_file (mfile); - metadata_namespace = g_metadata_get_string (metadata, ((Header *) metadata->data)->namespace); + metadata = g_typelib_new_from_mapped_file (mfile); + metadata_namespace = g_typelib_get_string (metadata, ((Header *) metadata->data)->namespace); if (strcmp (metadata_namespace, namespace) != 0) { g_set_error (error, G_IREPOSITORY_ERROR, G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH, @@ -472,7 +472,7 @@ g_irepository_register_file (GIRepository *repository, /* optionally load shared library and attach it to the metadata */ shlib = ((Header *) metadata->data)->shared_library; if (shlib) { - shlib_fname = g_metadata_get_string (metadata, shlib); + shlib_fname = g_typelib_get_string (metadata, shlib); module = g_module_open (shlib_fname, G_MODULE_BIND_LAZY|G_MODULE_BIND_LOCAL); if (module == NULL) { g_set_error (error, G_IREPOSITORY_ERROR, diff --git a/girepository.h b/girepository.h index fa625aa2a..ae5e2c583 100644 --- a/girepository.h +++ b/girepository.h @@ -52,7 +52,7 @@ typedef struct _GIArgInfo GIArgInfo; typedef struct _GITypeInfo GITypeInfo; typedef struct _GIErrorDomainInfo GIErrorDomainInfo; typedef struct _GIUnresolvedInfo GIUnresolvedInfo; -typedef struct _GMetadata GMetadata; +typedef struct _GTypelib GTypelib; struct _GIRepository { @@ -73,7 +73,7 @@ struct _GIRepositoryClass GType g_irepository_get_type (void) G_GNUC_CONST; GIRepository *g_irepository_get_default (void); const gchar * g_irepository_register (GIRepository *repository, - GMetadata *metadata); + GTypelib *metadata); void g_irepository_unregister (GIRepository *repository, const gchar *namespace); const gchar * g_irepository_register_file (GIRepository *repository, @@ -96,15 +96,15 @@ const gchar * g_irepository_get_shared_library (GIRepository *repository, const gchar *namespace); /* Metadata */ -GMetadata * g_metadata_new_from_memory (guchar *memory, +GTypelib * g_typelib_new_from_memory (guchar *memory, gsize len); -GMetadata * g_metadata_new_from_const_memory (const guchar *memory, +GTypelib * g_typelib_new_from_const_memory (const guchar *memory, gsize len); -GMetadata * g_metadata_new_from_mapped_file (GMappedFile *mfile); -void g_metadata_free (GMetadata *metadata); -void g_metadata_set_module (GMetadata *metadata, +GTypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile); +void g_typelib_free (GTypelib *metadata); +void g_typelib_set_module (GTypelib *metadata, GModule *module); -const gchar * g_metadata_get_namespace (GMetadata *metadata); +const gchar * g_typelib_get_namespace (GTypelib *metadata); typedef enum { @@ -156,11 +156,11 @@ gboolean g_base_info_is_deprecated (GIBaseInfo *info); const gchar * g_base_info_get_annotation (GIBaseInfo *info, const gchar *name); GIBaseInfo * g_base_info_get_container (GIBaseInfo *info); -GMetadata * g_base_info_get_metadata (GIBaseInfo *info); +GTypelib * g_base_info_get_metadata (GIBaseInfo *info); GIBaseInfo * g_info_new (GIInfoType type, GIBaseInfo *container, - GMetadata *metadata, + GTypelib *metadata, guint32 offset); diff --git a/gmetadata.c b/gtypelib.c similarity index 80% rename from gmetadata.c rename to gtypelib.c index c33e6bffc..3df1918bf 100644 --- a/gmetadata.c +++ b/gtypelib.c @@ -24,7 +24,7 @@ #include -#include "gmetadata.h" +#include "gtypelib.h" #define ALIGN_VALUE(this, boundary) \ @@ -32,7 +32,7 @@ DirEntry * -g_metadata_get_dir_entry (GMetadata *metadata, +g_typelib_get_dir_entry (GTypelib *metadata, guint16 index) { Header *header = (Header *)metadata->data; @@ -41,7 +41,7 @@ g_metadata_get_dir_entry (GMetadata *metadata, } void -g_metadata_check_sanity (void) +g_typelib_check_sanity (void) { /* Check that struct layout is as we expect */ g_assert (sizeof (Header) == 100); @@ -97,7 +97,7 @@ is_name (const guchar *data, guint32 offset) } static gboolean -validate_header (GMetadata *metadata, +validate_header (GTypelib *metadata, GError **error) { Header *header; @@ -105,8 +105,8 @@ validate_header (GMetadata *metadata, if (metadata->len < sizeof (Header)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -116,8 +116,8 @@ validate_header (GMetadata *metadata, if (strncmp (header->magic, G_IDL_MAGIC, 16) != 0) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_HEADER, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, "Magic string not found"); return FALSE; @@ -126,8 +126,8 @@ validate_header (GMetadata *metadata, if (header->major_version != 1 || header->minor_version != 0) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_HEADER, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, "Version mismatch"); return FALSE; @@ -136,8 +136,8 @@ validate_header (GMetadata *metadata, if (header->n_entries < header->n_local_entries) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_HEADER, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, "Inconsistent entry counts"); return FALSE; } @@ -145,8 +145,8 @@ validate_header (GMetadata *metadata, if (header->size != metadata->len) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_HEADER, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, "Metadata size mismatch"); return FALSE; } @@ -171,8 +171,8 @@ validate_header (GMetadata *metadata, header->union_blob_size != 28) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_HEADER, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, "Blob size mismatch"); return FALSE; } @@ -180,8 +180,8 @@ validate_header (GMetadata *metadata, if (!is_aligned (header->directory)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_HEADER, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, "Misaligned directory"); return FALSE; } @@ -189,8 +189,8 @@ validate_header (GMetadata *metadata, if (!is_aligned (header->annotations)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_HEADER, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, "Misaligned annotations"); return FALSE; } @@ -198,8 +198,8 @@ validate_header (GMetadata *metadata, if (header->annotations == 0 && header->n_annotations > 0) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_HEADER, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, "Wrong number of annotations"); return FALSE; } @@ -207,8 +207,8 @@ validate_header (GMetadata *metadata, if (!is_name (metadata->data, header->namespace)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_HEADER, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_HEADER, "Invalid namespace name"); return FALSE; } @@ -216,14 +216,14 @@ validate_header (GMetadata *metadata, return TRUE; } -static gboolean validate_type_blob (GMetadata *metadata, +static gboolean validate_type_blob (GTypelib *metadata, guint32 offset, guint32 signature_offset, gboolean return_type, GError **error); static gboolean -validate_array_type_blob (GMetadata *metadata, +validate_array_type_blob (GTypelib *metadata, guint32 offset, guint32 signature_offset, gboolean return_type, @@ -236,8 +236,8 @@ validate_array_type_blob (GMetadata *metadata, if (!blob->pointer) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Pointer type exected for tag %d", blob->tag); return FALSE; } @@ -253,7 +253,7 @@ validate_array_type_blob (GMetadata *metadata, } static gboolean -validate_iface_type_blob (GMetadata *metadata, +validate_iface_type_blob (GTypelib *metadata, guint32 offset, guint32 signature_offset, gboolean return_type, @@ -269,8 +269,8 @@ validate_iface_type_blob (GMetadata *metadata, if (blob->interface == 0 || blob->interface > header->n_entries) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid directory index %d", blob->interface); return FALSE; } @@ -279,7 +279,7 @@ validate_iface_type_blob (GMetadata *metadata, } static gboolean -validate_param_type_blob (GMetadata *metadata, +validate_param_type_blob (GTypelib *metadata, guint32 offset, guint32 signature_offset, gboolean return_type, @@ -294,8 +294,8 @@ validate_param_type_blob (GMetadata *metadata, if (!blob->pointer) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Pointer type exected for tag %d", blob->tag); return FALSE; } @@ -303,8 +303,8 @@ validate_param_type_blob (GMetadata *metadata, if (blob->n_types != n_params) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Parameter type number mismatch"); return FALSE; } @@ -322,7 +322,7 @@ validate_param_type_blob (GMetadata *metadata, } static gboolean -validate_error_type_blob (GMetadata *metadata, +validate_error_type_blob (GTypelib *metadata, guint32 offset, guint32 signature_offset, gboolean return_type, @@ -340,8 +340,8 @@ validate_error_type_blob (GMetadata *metadata, if (!blob->pointer) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Pointer type exected for tag %d", blob->tag); return FALSE; } @@ -351,20 +351,20 @@ validate_error_type_blob (GMetadata *metadata, if (blob->domains[i] == 0 || blob->domains[i] > header->n_entries) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid directory index %d", blob->domains[i]); return FALSE; } - entry = g_metadata_get_dir_entry (metadata, blob->domains[i]); + entry = g_typelib_get_dir_entry (metadata, blob->domains[i]); if (entry->blob_type != BLOB_TYPE_ERROR_DOMAIN && (entry->local || entry->blob_type != BLOB_TYPE_INVALID)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Wrong blob type"); return FALSE; } @@ -374,7 +374,7 @@ validate_error_type_blob (GMetadata *metadata, } static gboolean -validate_type_blob (GMetadata *metadata, +validate_type_blob (GTypelib *metadata, guint32 offset, guint32 signature_offset, gboolean return_type, @@ -391,8 +391,8 @@ validate_type_blob (GMetadata *metadata, if (simple->tag >= TYPE_TAG_ARRAY) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Wrong tag in simple type"); return FALSE; } @@ -401,8 +401,8 @@ validate_type_blob (GMetadata *metadata, !simple->pointer) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Pointer type exected for tag %d", simple->tag); return FALSE; } @@ -442,8 +442,8 @@ validate_type_blob (GMetadata *metadata, break; default: g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Wrong tag in complex type"); return FALSE; } @@ -452,7 +452,7 @@ validate_type_blob (GMetadata *metadata, } static gboolean -validate_arg_blob (GMetadata *metadata, +validate_arg_blob (GTypelib *metadata, guint32 offset, guint32 signature_offset, GError **error) @@ -462,8 +462,8 @@ validate_arg_blob (GMetadata *metadata, if (metadata->len < offset + sizeof (ArgBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -473,8 +473,8 @@ validate_arg_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid argument name"); return FALSE; } @@ -488,7 +488,7 @@ validate_arg_blob (GMetadata *metadata, } static gboolean -validate_signature_blob (GMetadata *metadata, +validate_signature_blob (GTypelib *metadata, guint32 offset, GError **error) { @@ -498,8 +498,8 @@ validate_signature_blob (GMetadata *metadata, if (metadata->len < offset + sizeof (SignatureBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -530,7 +530,7 @@ validate_signature_blob (GMetadata *metadata, } static gboolean -validate_function_blob (GMetadata *metadata, +validate_function_blob (GTypelib *metadata, guint32 offset, guint16 container_type, GError **error) @@ -540,8 +540,8 @@ validate_function_blob (GMetadata *metadata, if (metadata->len < offset + sizeof (FunctionBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -551,8 +551,8 @@ validate_function_blob (GMetadata *metadata, if (blob->blob_type != BLOB_TYPE_FUNCTION) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Wrong blob type"); return FALSE; } @@ -560,8 +560,8 @@ validate_function_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid function name"); return FALSE; } @@ -569,8 +569,8 @@ validate_function_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->symbol)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid function symbol"); return FALSE; } @@ -585,8 +585,8 @@ validate_function_blob (GMetadata *metadata, break; default: g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Constructor not allowed"); return FALSE; } @@ -601,8 +601,8 @@ validate_function_blob (GMetadata *metadata, break; default: g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Setter, getter or wrapper not allowed"); return FALSE; } @@ -613,8 +613,8 @@ validate_function_blob (GMetadata *metadata, if (!(blob->setter || blob->getter || blob->wraps_vfunc)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Must be setter, getter or wrapper"); return FALSE; } @@ -631,7 +631,7 @@ validate_function_blob (GMetadata *metadata, } static gboolean -validate_callback_blob (GMetadata *metadata, +validate_callback_blob (GTypelib *metadata, guint32 offset, GError **error) { @@ -640,8 +640,8 @@ validate_callback_blob (GMetadata *metadata, if (metadata->len < offset + sizeof (CallbackBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -651,8 +651,8 @@ validate_callback_blob (GMetadata *metadata, if (blob->blob_type != BLOB_TYPE_CALLBACK) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Wrong blob type"); return FALSE; } @@ -660,8 +660,8 @@ validate_callback_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid callback name"); return FALSE; } @@ -673,7 +673,7 @@ validate_callback_blob (GMetadata *metadata, } static gboolean -validate_constant_blob (GMetadata *metadata, +validate_constant_blob (GTypelib *metadata, guint32 offset, GError **error) { @@ -691,8 +691,8 @@ validate_constant_blob (GMetadata *metadata, if (metadata->len < offset + sizeof (ConstantBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -702,8 +702,8 @@ validate_constant_blob (GMetadata *metadata, if (blob->blob_type != BLOB_TYPE_CONSTANT) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Wrong blob type"); return FALSE; } @@ -711,8 +711,8 @@ validate_constant_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid constant name"); return FALSE; } @@ -724,8 +724,8 @@ validate_constant_blob (GMetadata *metadata, if (!is_aligned (blob->offset)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Misaligned constant value"); return FALSE; } @@ -736,8 +736,8 @@ validate_constant_blob (GMetadata *metadata, if (type->tag == 0) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Constant value type void"); return FALSE; } @@ -746,8 +746,8 @@ validate_constant_blob (GMetadata *metadata, blob->size != value_size[type->tag]) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Constant value size mismatch"); return FALSE; } @@ -758,7 +758,7 @@ validate_constant_blob (GMetadata *metadata, } static gboolean -validate_value_blob (GMetadata *metadata, +validate_value_blob (GTypelib *metadata, guint32 offset, GError **error) { @@ -767,8 +767,8 @@ validate_value_blob (GMetadata *metadata, if (metadata->len < offset + sizeof (ValueBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -778,8 +778,8 @@ validate_value_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid value name"); return FALSE; } @@ -788,7 +788,7 @@ validate_value_blob (GMetadata *metadata, } static gboolean -validate_field_blob (GMetadata *metadata, +validate_field_blob (GTypelib *metadata, guint32 offset, GError **error) { @@ -797,8 +797,8 @@ validate_field_blob (GMetadata *metadata, if (metadata->len < offset + sizeof (FieldBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -808,8 +808,8 @@ validate_field_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid field name"); return FALSE; } @@ -823,7 +823,7 @@ validate_field_blob (GMetadata *metadata, } static gboolean -validate_property_blob (GMetadata *metadata, +validate_property_blob (GTypelib *metadata, guint32 offset, GError **error) { @@ -832,8 +832,8 @@ validate_property_blob (GMetadata *metadata, if (metadata->len < offset + sizeof (PropertyBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -843,8 +843,8 @@ validate_property_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid property name"); return FALSE; } @@ -858,7 +858,7 @@ validate_property_blob (GMetadata *metadata, } static gboolean -validate_signal_blob (GMetadata *metadata, +validate_signal_blob (GTypelib *metadata, guint32 offset, guint32 container_offset, GError **error) @@ -869,8 +869,8 @@ validate_signal_blob (GMetadata *metadata, if (metadata->len < offset + sizeof (SignalBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -880,8 +880,8 @@ validate_signal_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid signal name"); return FALSE; } @@ -891,8 +891,8 @@ validate_signal_blob (GMetadata *metadata, (blob->run_cleanup != 0) != 1) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid signal run flags"); return FALSE; } @@ -919,8 +919,8 @@ validate_signal_blob (GMetadata *metadata, if (blob->class_closure >= n_signals) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid class closure index"); return FALSE; } @@ -933,7 +933,7 @@ validate_signal_blob (GMetadata *metadata, } static gboolean -validate_vfunc_blob (GMetadata *metadata, +validate_vfunc_blob (GTypelib *metadata, guint32 offset, guint32 container_offset, GError **error) @@ -944,8 +944,8 @@ validate_vfunc_blob (GMetadata *metadata, if (metadata->len < offset + sizeof (VFuncBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -955,8 +955,8 @@ validate_vfunc_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid vfunc name"); return FALSE; } @@ -983,8 +983,8 @@ validate_vfunc_blob (GMetadata *metadata, if (blob->class_closure >= n_vfuncs) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid class closure index"); return FALSE; } @@ -997,7 +997,7 @@ validate_vfunc_blob (GMetadata *metadata, } static gboolean -validate_struct_blob (GMetadata *metadata, +validate_struct_blob (GTypelib *metadata, guint32 offset, guint16 blob_type, GError **error) @@ -1008,8 +1008,8 @@ validate_struct_blob (GMetadata *metadata, if (metadata->len < offset + sizeof (StructBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -1019,8 +1019,8 @@ validate_struct_blob (GMetadata *metadata, if (blob->blob_type != blob_type) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Wrong blob type"); return FALSE; } @@ -1029,8 +1029,8 @@ validate_struct_blob (GMetadata *metadata, (blob->blob_type == BLOB_TYPE_STRUCT && !blob->unregistered)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Registration/blob type mismatch"); return FALSE; } @@ -1038,8 +1038,8 @@ validate_struct_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid struct name"); return FALSE; } @@ -1049,8 +1049,8 @@ validate_struct_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->gtype_name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid boxed type name"); return FALSE; } @@ -1058,8 +1058,8 @@ validate_struct_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->gtype_init)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid boxed type init"); return FALSE; } @@ -1069,8 +1069,8 @@ validate_struct_blob (GMetadata *metadata, if (blob->gtype_name || blob->gtype_init) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Gtype data in struct"); return FALSE; } @@ -1081,8 +1081,8 @@ validate_struct_blob (GMetadata *metadata, blob->n_methods * sizeof (FunctionBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -1111,7 +1111,7 @@ validate_struct_blob (GMetadata *metadata, } static gboolean -validate_enum_blob (GMetadata *metadata, +validate_enum_blob (GTypelib *metadata, guint32 offset, guint16 blob_type, GError **error) @@ -1123,8 +1123,8 @@ validate_enum_blob (GMetadata *metadata, if (metadata->len < offset + sizeof (EnumBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -1134,8 +1134,8 @@ validate_enum_blob (GMetadata *metadata, if (blob->blob_type != blob_type) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Wrong blob type"); return FALSE; } @@ -1145,8 +1145,8 @@ validate_enum_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->gtype_name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid enum type name"); return FALSE; } @@ -1154,8 +1154,8 @@ validate_enum_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->gtype_init)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid enum type init"); return FALSE; } @@ -1165,8 +1165,8 @@ validate_enum_blob (GMetadata *metadata, if (blob->gtype_name || blob->gtype_init) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Gtype data in unregistered enum"); return FALSE; } @@ -1175,8 +1175,8 @@ validate_enum_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid enum name"); return FALSE; } @@ -1185,8 +1185,8 @@ validate_enum_blob (GMetadata *metadata, blob->n_values * sizeof (ValueBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -1210,8 +1210,8 @@ validate_enum_blob (GMetadata *metadata, { /* FIXME should this be an error ? */ g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Duplicate enum value"); return FALSE; } @@ -1222,7 +1222,7 @@ validate_enum_blob (GMetadata *metadata, } static gboolean -validate_object_blob (GMetadata *metadata, +validate_object_blob (GTypelib *metadata, guint32 offset, GError **error) { @@ -1236,8 +1236,8 @@ validate_object_blob (GMetadata *metadata, if (metadata->len < offset + sizeof (ObjectBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -1247,8 +1247,8 @@ validate_object_blob (GMetadata *metadata, if (blob->blob_type != BLOB_TYPE_OBJECT) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Wrong blob type"); return FALSE; } @@ -1256,8 +1256,8 @@ validate_object_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->gtype_name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid object type name"); return FALSE; } @@ -1265,8 +1265,8 @@ validate_object_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->gtype_init)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid object type init"); return FALSE; } @@ -1274,8 +1274,8 @@ validate_object_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid object name"); return FALSE; } @@ -1283,8 +1283,8 @@ validate_object_blob (GMetadata *metadata, if (blob->parent > header->n_entries) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid parent index"); return FALSE; } @@ -1293,13 +1293,13 @@ validate_object_blob (GMetadata *metadata, { DirEntry *entry; - entry = g_metadata_get_dir_entry (metadata, blob->parent); + entry = g_typelib_get_dir_entry (metadata, blob->parent); if (entry->blob_type != BLOB_TYPE_OBJECT && (entry->local || entry->blob_type != 0)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Parent not object"); return FALSE; } @@ -1316,8 +1316,8 @@ validate_object_blob (GMetadata *metadata, { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -1333,20 +1333,20 @@ validate_object_blob (GMetadata *metadata, if (iface == 0 || iface > header->n_entries) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid interface index"); return FALSE; } - entry = g_metadata_get_dir_entry (metadata, iface); + entry = g_typelib_get_dir_entry (metadata, iface); if (entry->blob_type != BLOB_TYPE_INTERFACE && (entry->local || entry->blob_type != 0)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Not an interface"); return FALSE; } @@ -1394,7 +1394,7 @@ validate_object_blob (GMetadata *metadata, } static gboolean -validate_interface_blob (GMetadata *metadata, +validate_interface_blob (GTypelib *metadata, guint32 offset, GError **error) { @@ -1408,8 +1408,8 @@ validate_interface_blob (GMetadata *metadata, if (metadata->len < offset + sizeof (InterfaceBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -1419,8 +1419,8 @@ validate_interface_blob (GMetadata *metadata, if (blob->blob_type != BLOB_TYPE_INTERFACE) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Wrong blob type"); return FALSE; } @@ -1428,8 +1428,8 @@ validate_interface_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->gtype_name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid interface type name"); return FALSE; } @@ -1437,8 +1437,8 @@ validate_interface_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->gtype_init)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid interface type init"); return FALSE; } @@ -1446,8 +1446,8 @@ validate_interface_blob (GMetadata *metadata, if (!is_name (metadata->data, blob->name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid interface name"); return FALSE; } @@ -1462,8 +1462,8 @@ validate_interface_blob (GMetadata *metadata, { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -1479,20 +1479,20 @@ validate_interface_blob (GMetadata *metadata, if (req == 0 || req > header->n_entries) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Invalid prerequisite index"); return FALSE; } - entry = g_metadata_get_dir_entry (metadata, req); + entry = g_typelib_get_dir_entry (metadata, req); if (entry->blob_type != BLOB_TYPE_INTERFACE && entry->blob_type != BLOB_TYPE_OBJECT && (entry->local || entry->blob_type != 0)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_BLOB, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, "Not an interface or object"); return FALSE; } @@ -1534,7 +1534,7 @@ validate_interface_blob (GMetadata *metadata, } static gboolean -validate_errordomain_blob (GMetadata *metadata, +validate_errordomain_blob (GTypelib *metadata, guint32 offset, GError **error) { @@ -1542,7 +1542,7 @@ validate_errordomain_blob (GMetadata *metadata, } static gboolean -validate_union_blob (GMetadata *metadata, +validate_union_blob (GTypelib *metadata, guint32 offset, GError **error) { @@ -1550,7 +1550,7 @@ validate_union_blob (GMetadata *metadata, } static gboolean -validate_blob (GMetadata *metadata, +validate_blob (GTypelib *metadata, guint32 offset, GError **error) { @@ -1559,8 +1559,8 @@ validate_blob (GMetadata *metadata, if (metadata->len < offset + sizeof (CommonBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -1609,8 +1609,8 @@ validate_blob (GMetadata *metadata, break; default: g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_ENTRY, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_ENTRY, "Invalid blob type"); return FALSE; } @@ -1619,7 +1619,7 @@ validate_blob (GMetadata *metadata, } static gboolean -validate_directory (GMetadata *metadata, +validate_directory (GTypelib *metadata, GError **error) { Header *header = (Header *)metadata->data; @@ -1629,21 +1629,21 @@ validate_directory (GMetadata *metadata, if (metadata->len < header->directory + header->n_entries * sizeof (DirEntry)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } for (i = 0; i < header->n_entries; i++) { - entry = g_metadata_get_dir_entry (metadata, i + 1); + entry = g_typelib_get_dir_entry (metadata, i + 1); if (!is_name (metadata->data, entry->name)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_DIRECTORY, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_DIRECTORY, "Invalid entry name"); return FALSE; } @@ -1652,8 +1652,8 @@ validate_directory (GMetadata *metadata, entry->blob_type > BLOB_TYPE_UNION) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_DIRECTORY, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_DIRECTORY, "Invalid entry type"); return FALSE; } @@ -1663,8 +1663,8 @@ validate_directory (GMetadata *metadata, if (!entry->local) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_DIRECTORY, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_DIRECTORY, "Too few local directory entries"); return FALSE; } @@ -1672,8 +1672,8 @@ validate_directory (GMetadata *metadata, if (!is_aligned (entry->offset)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_DIRECTORY, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_DIRECTORY, "Misaligned entry"); return FALSE; } @@ -1686,8 +1686,8 @@ validate_directory (GMetadata *metadata, if (entry->local) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_DIRECTORY, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_DIRECTORY, "Too many local directory entries"); return FALSE; } @@ -1695,8 +1695,8 @@ validate_directory (GMetadata *metadata, if (!is_name (metadata->data, entry->offset)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID_DIRECTORY, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_DIRECTORY, "Invalid namespace name"); return FALSE; } @@ -1707,7 +1707,7 @@ validate_directory (GMetadata *metadata, } static gboolean -validate_annotations (GMetadata *metadata, +validate_annotations (GTypelib *metadata, GError **error) { Header *header = (Header *)metadata->data; @@ -1715,8 +1715,8 @@ validate_annotations (GMetadata *metadata, if (header->size < header->annotations + header->n_annotations * sizeof (AnnotationBlob)) { g_set_error (error, - G_METADATA_ERROR, - G_METADATA_ERROR_INVALID, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, "The buffer is too short"); return FALSE; } @@ -1725,7 +1725,7 @@ validate_annotations (GMetadata *metadata, } gboolean -g_metadata_validate (GMetadata *metadata, +g_typelib_validate (GTypelib *metadata, GError **error) { if (!validate_header (metadata, error)) @@ -1741,7 +1741,7 @@ g_metadata_validate (GMetadata *metadata, } GQuark -g_metadata_error_quark (void) +g_typelib_error_quark (void) { static GQuark quark = 0; if (quark == 0) @@ -1750,7 +1750,7 @@ g_metadata_error_quark (void) } static const char* -find_some_symbol (GMetadata *metadata) +find_some_symbol (GTypelib *metadata) { Header *header = (Header *) metadata->data; gint i; @@ -1759,7 +1759,7 @@ find_some_symbol (GMetadata *metadata) { DirEntry *entry; - entry = g_metadata_get_dir_entry (metadata, i + 1); + entry = g_typelib_get_dir_entry (metadata, i + 1); switch (entry->blob_type) { @@ -1768,7 +1768,7 @@ find_some_symbol (GMetadata *metadata) FunctionBlob *blob = (FunctionBlob *) &metadata->data[entry->offset]; if (blob->symbol) - return g_metadata_get_string (metadata, blob->symbol); + return g_typelib_get_string (metadata, blob->symbol); } break; case BLOB_TYPE_OBJECT: @@ -1776,7 +1776,7 @@ find_some_symbol (GMetadata *metadata) RegisteredTypeBlob *blob = (RegisteredTypeBlob *) &metadata->data[entry->offset]; if (blob->gtype_init) - return g_metadata_get_string (metadata, blob->gtype_init); + return g_typelib_get_string (metadata, blob->gtype_init); } break; default: @@ -1788,7 +1788,7 @@ find_some_symbol (GMetadata *metadata) } static inline void -_g_metadata_init (GMetadata *metadata) +_g_typelib_init (GTypelib *metadata) { Header *header; @@ -1797,7 +1797,7 @@ _g_metadata_init (GMetadata *metadata) { const gchar *shlib; - shlib = g_metadata_get_string (metadata, header->shared_library); + shlib = g_typelib_get_string (metadata, header->shared_library); /* note that NULL shlib means to open the main app, which is allowed */ /* If we do have a shared lib, first be sure the main app isn't already linked to it */ @@ -1851,81 +1851,81 @@ _g_metadata_init (GMetadata *metadata) } /** - * g_metadata_new_from_memory: + * g_typelib_new_from_memory: * @memory: address of memory chunk containing the metadata * @len: length of memory chunk containing the metadata * - * Creates a new #GMetadata from a memory location. The memory block + * Creates a new #GTypelib from a memory location. The memory block * pointed to by @metadata will be automatically g_free()d when the * repository is destroyed. * - * Return value: the new #GMetadata + * Return value: the new #GTypelib **/ -GMetadata * -g_metadata_new_from_memory (guchar *memory, gsize len) +GTypelib * +g_typelib_new_from_memory (guchar *memory, gsize len) { - GMetadata *meta; + GTypelib *meta; - meta = g_new0 (GMetadata, 1); + meta = g_new0 (GTypelib, 1); meta->data = memory; meta->len = len; meta->owns_memory = TRUE; - _g_metadata_init (meta); + _g_typelib_init (meta); return meta; } /** - * g_metadata_new_from_const_memory: + * g_typelib_new_from_const_memory: * @memory: address of memory chunk containing the metadata * @len: length of memory chunk containing the metadata * - * Creates a new #GMetadata from a memory location. + * Creates a new #GTypelib from a memory location. * - * Return value: the new #GMetadata + * Return value: the new #GTypelib **/ -GMetadata * -g_metadata_new_from_const_memory (const guchar *memory, gsize len) +GTypelib * +g_typelib_new_from_const_memory (const guchar *memory, gsize len) { - GMetadata *meta; + GTypelib *meta; - meta = g_new0 (GMetadata, 1); + meta = g_new0 (GTypelib, 1); meta->data = (guchar *) memory; meta->len = len; meta->owns_memory = FALSE; - _g_metadata_init (meta); + _g_typelib_init (meta); return meta; } /** - * g_metadata_new_from_mapped_file: + * g_typelib_new_from_mapped_file: * @mfile: a #GMappedFile, that will be free'd when the repository is destroyed * - * Creates a new #GMetadata from a #GMappedFile. + * Creates a new #GTypelib from a #GMappedFile. * - * Return value: the new #GMetadata + * Return value: the new #GTypelib **/ -GMetadata * -g_metadata_new_from_mapped_file (GMappedFile *mfile) +GTypelib * +g_typelib_new_from_mapped_file (GMappedFile *mfile) { - GMetadata *meta; + GTypelib *meta; - meta = g_new0 (GMetadata, 1); + meta = g_new0 (GTypelib, 1); meta->mfile = mfile; meta->owns_memory = FALSE; meta->data = (guchar *) g_mapped_file_get_contents (mfile); meta->len = g_mapped_file_get_length (mfile); - _g_metadata_init (meta); + _g_typelib_init (meta); return meta; } /** - * g_metadata_free: - * @metadata: a #GMetadata + * g_typelib_free: + * @metadata: a #GTypelib * - * Free a #GMetadata. + * Free a #GTypelib. **/ void -g_metadata_free (GMetadata *metadata) +g_typelib_free (GTypelib *metadata) { if (metadata->mfile) g_mapped_file_free (metadata->mfile); @@ -1938,14 +1938,14 @@ g_metadata_free (GMetadata *metadata) } /** - * g_metadata_set_module: - * @metadata: a #GMetadata instance + * g_typelib_set_module: + * @metadata: a #GTypelib instance * @module: a #GModule; takes ownership of this module * * Sets the target module for all symbols referenced by the metadata. **/ void -g_metadata_set_module (GMetadata *metadata, GModule *module) +g_typelib_set_module (GTypelib *metadata, GModule *module) { if (metadata->module) g_module_close (metadata->module); @@ -1953,7 +1953,7 @@ g_metadata_set_module (GMetadata *metadata, GModule *module) } const gchar * -g_metadata_get_namespace(GMetadata *metadata) +g_typelib_get_namespace(GTypelib *metadata) { - return g_metadata_get_string (metadata, ((Header *) metadata->data)->namespace); + return g_typelib_get_string (metadata, ((Header *) metadata->data)->namespace); } diff --git a/gmetadata.h b/gtypelib.h similarity index 94% rename from gmetadata.h rename to gtypelib.h index a22ee235e..352c3a8ea 100644 --- a/gmetadata.h +++ b/gtypelib.h @@ -19,8 +19,8 @@ * Boston, MA 02111-1307, USA. */ -#ifndef __G_METADATA_H__ -#define __G_METADATA_H__ +#ifndef __G_TYPELIB_H__ +#define __G_TYPELIB_H__ #include #include "girepository.h" @@ -510,7 +510,7 @@ typedef struct } AnnotationBlob; -struct _GMetadata { +struct _GTypelib { guchar *data; gsize len; gboolean owns_memory; @@ -518,32 +518,32 @@ struct _GMetadata { GModule *module; }; -DirEntry *g_metadata_get_dir_entry (GMetadata *metadata, +DirEntry *g_typelib_get_dir_entry (GTypelib *metadata, guint16 index); -void g_metadata_check_sanity (void); +void g_typelib_check_sanity (void); -#define g_metadata_get_string(metadata,offset) ((const gchar*)&(metadata->data)[(offset)]) +#define g_typelib_get_string(metadata,offset) ((const gchar*)&(metadata->data)[(offset)]) typedef enum { - G_METADATA_ERROR_INVALID, - G_METADATA_ERROR_INVALID_HEADER, - G_METADATA_ERROR_INVALID_DIRECTORY, - G_METADATA_ERROR_INVALID_ENTRY, - G_METADATA_ERROR_INVALID_BLOB -} GMetadataError; + G_TYPELIB_ERROR_INVALID, + G_TYPELIB_ERROR_INVALID_HEADER, + G_TYPELIB_ERROR_INVALID_DIRECTORY, + G_TYPELIB_ERROR_INVALID_ENTRY, + G_TYPELIB_ERROR_INVALID_BLOB +} GTypelibError; -#define G_METADATA_ERROR (g_metadata_error_quark ()) +#define G_TYPELIB_ERROR (g_typelib_error_quark ()) -GQuark g_metadata_error_quark (void); +GQuark g_typelib_error_quark (void); -gboolean g_metadata_validate (GMetadata *metadata, +gboolean g_typelib_validate (GTypelib *metadata, GError **error); G_END_DECLS -#endif /* __G_METADATA_H__ */ +#endif /* __G_TYPELIB_H__ */ From abf9c86431a15345196872909c2027f463e73a55 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 24 Jul 2008 19:20:40 +0000 Subject: [PATCH 020/692] Add environment variable G_IREPOSITORY_VERBOSE so we can print out what 2008-07-24 Colin Walters * girepository/girepository.c (g_irepository_register): Add environment variable G_IREPOSITORY_VERBOSE so we can print out what we're doing. * girepository/girepository.c (g_irepository_register_file): Add GError error message to g_debug call. svn path=/trunk/; revision=296 --- Makefile.am | 7 +++---- girepository.c | 7 ++++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Makefile.am b/Makefile.am index 9dd5e547f..79033637f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,7 +4,7 @@ include $(top_srcdir)/gcov.mak INCLUDES = -DGIREPO_DEFAULT_SEARCH_PATH="\"$(libdir)\"" -noinst_LTLIBRARIES = libgirepository.la +lib_LTLIBRARIES = libgirepository.la libgirepository_la_SOURCES = \ girepository.c \ @@ -15,8 +15,7 @@ libgirepository_la_SOURCES = \ libgirepository_la_CPPFLAGS = $(GIREPO_CFLAGS) libgirepository_la_LIBADD = $(GIREPO_LIBS) -#girepodir = $(includedir)/gobject-introspection-1.0/ -#girepo_HEADERS = girepository.h -noinst_HEADERS = girepository.h +girepodir = $(includedir)/gobject-introspection-1.0/ +girepo_HEADERS = girepository.h GCOVSOURCES = $(libgirepository_la_SOURCES) diff --git a/girepository.c b/girepository.c index c2b119cd7..4da5ffc5f 100644 --- a/girepository.c +++ b/girepository.c @@ -114,6 +114,11 @@ g_irepository_register (GIRepository *repository, if (metadata->module == NULL) metadata->module = g_module_open (NULL, 0); + if (g_getenv ("G_IREPOSITORY_VERBOSE")) + { + g_printerr ("Loaded typelib %s\n", name); + } + return name; } @@ -443,7 +448,7 @@ g_irepository_register_file (GIRepository *repository, full_path = g_build_filename (dir, fname, NULL); mfile = g_mapped_file_new (full_path, FALSE, &error1); if (error1) { - g_debug ("Failed to mmap \"%s\"", full_path); + g_debug ("Failed to mmap \"%s\": %s", full_path, error1->message); g_clear_error (&error1); g_free (full_path); continue; From e1c3498df862f6f76d599f289237087f3f3e77d0 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 8 Aug 2008 19:09:17 +0000 Subject: [PATCH 021/692] Merge in the gir-compiler branch. Thanks to Philip and Colin for their 2008-08-08 Johan Dahlin * girepository/gtypelib.c (validate_header): * girepository/gtypelib.h: * giscanner/ast.py: * giscanner/girwriter.py: * giscanner/sourcescanner.c (gi_source_symbol_ref), (gi_source_symbol_unref): * tests/array.test: * tests/boxed.test: * tests/constant.test: * tests/enum.test: * tests/errors.test: * tests/function.test: * tests/gobject.test: * tests/interface.test: * tests/invoke/Makefile.am: * tests/invoke/testfns.xml: * tests/object.test: * tests/parser/Makefile.am: * tests/roundtrips.sh: * tests/struct.test: * tests/types.test: * tests/union.test: * tests/xref1.test: * tests/xref2.test: * tools/Makefile.am: * tools/compiler.c (main): * tools/generate.c (write_callable_info), (write_function_info), (write_repository): * tools/gidlmodule.c: * tools/gidlmodule.h: * tools/gidlnode.c: * tools/gidlnode.h: * tools/gidlparser.c: * tools/gidlparser.h: * tools/gidlwriter.c: * tools/gidlwriter.h: * tools/scanner.c (create_node_from_gtype), (create_node_from_ctype), (g_igenerator_process_properties), (g_igenerator_process_signals), (g_igenerator_create_object), (g_igenerator_create_interface), (g_igenerator_create_boxed), (g_igenerator_create_enum), (g_igenerator_create_flags), (g_igenerator_process_function_symbol), (g_igenerator_process_unregistered_struct_typedef), (g_igenerator_process_struct_typedef), (g_igenerator_process_union_typedef), (g_igenerator_process_enum_typedef), (g_igenerator_process_function_typedef), (g_igenerator_process_constant), (g_igenerator_process_symbols), (g_igenerator_add_module), (g_igenerator_add_include_idl): Merge in the gir-compiler branch. Thanks to Philip and Colin for their help. svn path=/trunk/; revision=325 --- gtypelib.c | 2 +- gtypelib.h | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/gtypelib.c b/gtypelib.c index 3df1918bf..cc07e96e2 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -113,7 +113,7 @@ validate_header (GTypelib *metadata, header = (Header *)metadata->data; - if (strncmp (header->magic, G_IDL_MAGIC, 16) != 0) + if (strncmp (header->magic, G_IR_MAGIC, 16) != 0) { g_set_error (error, G_TYPELIB_ERROR, diff --git a/gtypelib.h b/gtypelib.h index 352c3a8ea..0152a958d 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -27,7 +27,7 @@ G_BEGIN_DECLS -#define G_IDL_MAGIC "GOBJ\nMETADATA\r\n\032" +#define G_IR_MAGIC "GOBJ\nMETADATA\r\n\032" enum { @@ -126,7 +126,10 @@ typedef enum TYPE_TAG_LIST = 22, TYPE_TAG_SLIST = 23, TYPE_TAG_HASH = 24, - TYPE_TAG_ERROR = 25 + TYPE_TAG_ERROR = 25, + TYPE_TAG_STRING = 26, + TYPE_TAG_SEQUENCE = 27, + TYPE_TAG_ANY = 28 } TypeTag; typedef union From 282a6c644e20467ebc5ce0260daabd576a272a73 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 9 Aug 2008 12:46:48 +0000 Subject: [PATCH 022/692] Move shared *.[ch] files to girepository from tools 2008-08-09 Johan Dahlin * girepository/Makefile.am: * tools/Makefile.am: * tools/girmodule.c: * tools/girmodule.h: * tools/girnode.c: * tools/girnode.h: * tools/girparser.c: * tools/girparser.h: * tools/girwriter.c: * tools/girwriter.h: Move shared *.[ch] files to girepository from tools svn path=/trunk/; revision=337 --- Makefile.am | 19 +- girmodule.c | 215 +++++ girmodule.h | 48 ++ girnode.c | 2217 ++++++++++++++++++++++++++++++++++++++++++++++++ girnode.h | 334 ++++++++ girparser.c | 2314 +++++++++++++++++++++++++++++++++++++++++++++++++++ girparser.h | 38 + girwriter.c | 532 ++++++++++++ girwriter.h | 26 + 9 files changed, 5738 insertions(+), 5 deletions(-) create mode 100644 girmodule.c create mode 100644 girmodule.h create mode 100644 girnode.c create mode 100644 girnode.h create mode 100644 girparser.c create mode 100644 girparser.h create mode 100644 girwriter.c create mode 100644 girwriter.h diff --git a/Makefile.am b/Makefile.am index 79033637f..36e7baf93 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,10 +1,14 @@ -## Process this file with automake to produce Makefile.in - include $(top_srcdir)/gcov.mak +GCOVSOURCES = $(libgirepository_la_SOURCES) + INCLUDES = -DGIREPO_DEFAULT_SEARCH_PATH="\"$(libdir)\"" +girepodir = $(includedir)/gobject-introspection-1.0/ +girepo_HEADERS = girepository.h + lib_LTLIBRARIES = libgirepository.la +noinst_LTLIBRARIES = libgirepository-parser.la libgirepository_la_SOURCES = \ girepository.c \ @@ -15,7 +19,12 @@ libgirepository_la_SOURCES = \ libgirepository_la_CPPFLAGS = $(GIREPO_CFLAGS) libgirepository_la_LIBADD = $(GIREPO_LIBS) -girepodir = $(includedir)/gobject-introspection-1.0/ -girepo_HEADERS = girepository.h +libgirepository_parser_la_SOURCES = \ + girmodule.c \ + girmodule.h \ + girnode.c \ + girnode.h \ + girparser.c \ + girparser.h +libgirepository_parser_la_CFLAGS = $(GIREPO_CFLAGS) -GCOVSOURCES = $(libgirepository_la_SOURCES) diff --git a/girmodule.c b/girmodule.c new file mode 100644 index 000000000..8f09fb4a1 --- /dev/null +++ b/girmodule.c @@ -0,0 +1,215 @@ +/* GObject introspection: Metadata creation + * + * Copyright (C) 2005 Matthias Clasen + * + * 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 "girmodule.h" +#include "girnode.h" + +#define ALIGN_VALUE(this, boundary) \ + (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) + + +GIrModule * +g_ir_module_new (const gchar *name, const gchar *shared_library) +{ + GIrModule *module; + + module = g_new (GIrModule, 1); + + module->name = g_strdup (name); + if (shared_library) + module->shared_library = g_strdup (shared_library); + else + module->shared_library = NULL; + module->entries = NULL; + + return module; +} + +void +g_ir_module_free (GIrModule *module) +{ + GList *e; + + g_free (module->name); + + for (e = module->entries; e; e = e->next) + g_ir_node_free ((GIrNode *)e->data); + + g_list_free (module->entries); + + g_free (module); +} + +GTypelib * +g_ir_module_build_metadata (GIrModule *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) + { + GIrNode *node = e->data; + + size += g_ir_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_IR_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++) + { + GIrNode *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_IR_NODE_XREF) + { + entry->blob_type = 0; + entry->local = FALSE; + entry->offset = write_string (((GIrNodeXRef*)node)->namespace, strings, data, &offset2); + entry->name = write_string (node->name, strings, data, &offset2); + } + else + { + old_offset = offset; + offset2 = offset + g_ir_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_ir_node_build_metadata (node, module, modules, + strings, types, data, &offset, &offset2); + + if (offset2 > old_offset + g_ir_node_get_full_size (node)) + g_error ("left a hole of %d bytes\n", offset2 - old_offset - g_ir_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_typelib_new_from_memory (metadata, length); +} + diff --git a/girmodule.h b/girmodule.h new file mode 100644 index 000000000..a59e99612 --- /dev/null +++ b/girmodule.h @@ -0,0 +1,48 @@ +/* GObject introspection: Parsed IDL + * + * Copyright (C) 2005 Matthias Clasen + * + * 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_IR_MODULE_H__ +#define __G_IR_MODULE_H__ + +#include +#include "gtypelib.h" + +G_BEGIN_DECLS + + +typedef struct _GIrModule GIrModule; + +struct _GIrModule +{ + gchar *name; + gchar *shared_library; + GList *entries; +}; + +GIrModule *g_ir_module_new (const gchar *name, + const gchar *module_filename); +void g_ir_module_free (GIrModule *module); + +GTypelib * g_ir_module_build_metadata (GIrModule *module, + GList *modules); + +G_END_DECLS + +#endif /* __G_IR_MODULE_H__ */ diff --git a/girnode.c b/girnode.c new file mode 100644 index 000000000..0c7819123 --- /dev/null +++ b/girnode.c @@ -0,0 +1,2217 @@ +/* GObject introspection: Metadata creation + * + * Copyright (C) 2005 Matthias Clasen + * + * 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 "girmodule.h" +#include "girnode.h" +#include "gtypelib.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))) + + +static const gchar * +g_ir_node_type_to_string (GIrNodeTypeId type) +{ + switch (type) + { + case G_IR_NODE_FUNCTION: + return "function"; + case G_IR_NODE_CALLBACK: + return "callback"; + case G_IR_NODE_PARAM: + return "param"; + case G_IR_NODE_TYPE: + return "type"; + case G_IR_NODE_OBJECT: + return "object"; + case G_IR_NODE_INTERFACE: + return "interface"; + case G_IR_NODE_SIGNAL: + return "signal"; + case G_IR_NODE_PROPERTY: + return "property"; + case G_IR_NODE_VFUNC: + return "vfunc"; + case G_IR_NODE_FIELD: + return "field"; + case G_IR_NODE_ENUM: + return "enum"; + case G_IR_NODE_FLAGS: + return "flags"; + case G_IR_NODE_BOXED: + return "boxed"; + case G_IR_NODE_STRUCT: + return "struct"; + case G_IR_NODE_VALUE: + return "value"; + case G_IR_NODE_CONSTANT: + return "constant"; + case G_IR_NODE_ERROR_DOMAIN: + return "error-domain"; + case G_IR_NODE_XREF: + return "xref"; + case G_IR_NODE_UNION: + return "union"; + default: + return "unknown"; + } +} + +static const gchar* +gi_type_tag_to_string (GITypeTag type) +{ + switch (type) + { + case GI_TYPE_TAG_VOID: + return "void"; + case GI_TYPE_TAG_BOOLEAN: + return "boolean"; + case GI_TYPE_TAG_INT8: + return "int8"; + case GI_TYPE_TAG_UINT8: + return "uint8"; + case GI_TYPE_TAG_INT16: + return "int16"; + case GI_TYPE_TAG_UINT16: + return "uint16"; + case GI_TYPE_TAG_INT32: + return "int32"; + case GI_TYPE_TAG_UINT32: + return "uint32"; + case GI_TYPE_TAG_INT64: + return "int64"; + case GI_TYPE_TAG_UINT64: + return "uint64"; + case GI_TYPE_TAG_INT: + return "int"; + case GI_TYPE_TAG_UINT: + return "uint"; + case GI_TYPE_TAG_LONG: + return "long"; + case GI_TYPE_TAG_ULONG: + return "ulong"; + case GI_TYPE_TAG_SSIZE: + return "ssize"; + case GI_TYPE_TAG_SIZE: + return "size"; + case GI_TYPE_TAG_FLOAT: + return "float"; + case GI_TYPE_TAG_DOUBLE: + return "double"; + case GI_TYPE_TAG_UTF8: + return "utf8"; + case GI_TYPE_TAG_FILENAME: + return "filename"; + case GI_TYPE_TAG_ARRAY: + return "array"; + case GI_TYPE_TAG_INTERFACE: + return "interface"; + case GI_TYPE_TAG_GLIST: + return "glist"; + case GI_TYPE_TAG_GSLIST: + return "gslist"; + case GI_TYPE_TAG_GHASH: + return "ghash"; + case GI_TYPE_TAG_ERROR: + return "error"; + default: + return "unknown"; + } +} + +GIrNode * +g_ir_node_new (GIrNodeTypeId type) +{ + GIrNode *node = NULL; + + switch (type) + { + case G_IR_NODE_FUNCTION: + case G_IR_NODE_CALLBACK: + node = g_malloc0 (sizeof (GIrNodeFunction)); + break; + + case G_IR_NODE_PARAM: + node = g_malloc0 (sizeof (GIrNodeParam)); + break; + + case G_IR_NODE_TYPE: + node = g_malloc0 (sizeof (GIrNodeType)); + break; + + case G_IR_NODE_OBJECT: + case G_IR_NODE_INTERFACE: + node = g_malloc0 (sizeof (GIrNodeInterface)); + break; + + case G_IR_NODE_SIGNAL: + node = g_malloc0 (sizeof (GIrNodeSignal)); + break; + + case G_IR_NODE_PROPERTY: + node = g_malloc0 (sizeof (GIrNodeProperty)); + break; + + case G_IR_NODE_VFUNC: + node = g_malloc0 (sizeof (GIrNodeFunction)); + break; + + case G_IR_NODE_FIELD: + node = g_malloc0 (sizeof (GIrNodeField)); + break; + + case G_IR_NODE_ENUM: + case G_IR_NODE_FLAGS: + node = g_malloc0 (sizeof (GIrNodeEnum)); + break; + + case G_IR_NODE_BOXED: + node = g_malloc0 (sizeof (GIrNodeBoxed)); + break; + + case G_IR_NODE_STRUCT: + node = g_malloc0 (sizeof (GIrNodeStruct)); + break; + + case G_IR_NODE_VALUE: + node = g_malloc0 (sizeof (GIrNodeValue)); + break; + + case G_IR_NODE_CONSTANT: + node = g_malloc0 (sizeof (GIrNodeConstant)); + break; + + case G_IR_NODE_ERROR_DOMAIN: + node = g_malloc0 (sizeof (GIrNodeErrorDomain)); + break; + + case G_IR_NODE_XREF: + node = g_malloc0 (sizeof (GIrNodeXRef)); + break; + + case G_IR_NODE_UNION: + node = g_malloc0 (sizeof (GIrNodeUnion)); + break; + + default: + g_error ("Unhandled node type %d\n", type); + break; + } + + node->type = type; + + return node; +} + +void +g_ir_node_free (GIrNode *node) +{ + GList *l; + + if (node == NULL) + return; + + switch (node->type) + { + case G_IR_NODE_FUNCTION: + case G_IR_NODE_CALLBACK: + { + GIrNodeFunction *function = (GIrNodeFunction *)node; + + g_free (node->name); + g_free (function->symbol); + g_ir_node_free ((GIrNode *)function->result); + for (l = function->parameters; l; l = l->next) + g_ir_node_free ((GIrNode *)l->data); + g_list_free (function->parameters); + } + break; + + case G_IR_NODE_TYPE: + { + GIrNodeType *type = (GIrNodeType *)node; + + g_free (node->name); + g_ir_node_free ((GIrNode *)type->parameter_type1); + g_ir_node_free ((GIrNode *)type->parameter_type2); + + g_free (type->interface); + g_strfreev (type->errors); + + } + break; + + case G_IR_NODE_PARAM: + { + GIrNodeParam *param = (GIrNodeParam *)node; + + g_free (node->name); + g_ir_node_free ((GIrNode *)param->type); + } + break; + + case G_IR_NODE_PROPERTY: + { + GIrNodeProperty *property = (GIrNodeProperty *)node; + + g_free (node->name); + g_ir_node_free ((GIrNode *)property->type); + } + break; + + case G_IR_NODE_SIGNAL: + { + GIrNodeSignal *signal = (GIrNodeSignal *)node; + + g_free (node->name); + for (l = signal->parameters; l; l = l->next) + g_ir_node_free ((GIrNode *)l->data); + g_list_free (signal->parameters); + g_ir_node_free ((GIrNode *)signal->result); + } + break; + + case G_IR_NODE_VFUNC: + { + GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node; + + g_free (node->name); + for (l = vfunc->parameters; l; l = l->next) + g_ir_node_free ((GIrNode *)l->data); + g_list_free (vfunc->parameters); + g_ir_node_free ((GIrNode *)vfunc->result); + } + break; + + case G_IR_NODE_FIELD: + { + GIrNodeField *field = (GIrNodeField *)node; + + g_free (node->name); + g_ir_node_free ((GIrNode *)field->type); + } + break; + + case G_IR_NODE_OBJECT: + case G_IR_NODE_INTERFACE: + { + GIrNodeInterface *iface = (GIrNodeInterface *)node; + + g_free (node->name); + g_free (iface->gtype_name); + g_free (iface->gtype_init); + + g_free (iface->parent); + + for (l = iface->interfaces; l; l = l->next) + g_free ((GIrNode *)l->data); + g_list_free (iface->interfaces); + + for (l = iface->members; l; l = l->next) + g_ir_node_free ((GIrNode *)l->data); + g_list_free (iface->members); + + } + break; + + case G_IR_NODE_VALUE: + { + g_free (node->name); + } + break; + + case G_IR_NODE_ENUM: + case G_IR_NODE_FLAGS: + { + GIrNodeEnum *enum_ = (GIrNodeEnum *)node; + + g_free (node->name); + g_free (enum_->gtype_name); + g_free (enum_->gtype_init); + + for (l = enum_->values; l; l = l->next) + g_ir_node_free ((GIrNode *)l->data); + g_list_free (enum_->values); + } + break; + + case G_IR_NODE_BOXED: + { + GIrNodeBoxed *boxed = (GIrNodeBoxed *)node; + + g_free (node->name); + g_free (boxed->gtype_name); + g_free (boxed->gtype_init); + + for (l = boxed->members; l; l = l->next) + g_ir_node_free ((GIrNode *)l->data); + g_list_free (boxed->members); + } + break; + + case G_IR_NODE_STRUCT: + { + GIrNodeStruct *struct_ = (GIrNodeStruct *)node; + + g_free (node->name); + for (l = struct_->members; l; l = l->next) + g_ir_node_free ((GIrNode *)l->data); + g_list_free (struct_->members); + } + break; + + case G_IR_NODE_CONSTANT: + { + GIrNodeConstant *constant = (GIrNodeConstant *)node; + + g_free (node->name); + g_free (constant->value); + g_ir_node_free ((GIrNode *)constant->type); + } + break; + + case G_IR_NODE_ERROR_DOMAIN: + { + GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node; + + g_free (node->name); + g_free (domain->getquark); + g_free (domain->codes); + } + break; + + case G_IR_NODE_XREF: + { + GIrNodeXRef *xref = (GIrNodeXRef *)node; + + g_free (node->name); + g_free (xref->namespace); + } + break; + + case G_IR_NODE_UNION: + { + GIrNodeUnion *union_ = (GIrNodeUnion *)node; + + g_free (node->name); + g_free (union_->gtype_name); + g_free (union_->gtype_init); + + g_ir_node_free ((GIrNode *)union_->discriminator_type); + for (l = union_->members; l; l = l->next) + g_ir_node_free ((GIrNode *)l->data); + for (l = union_->discriminators; l; l = l->next) + g_ir_node_free ((GIrNode *)l->data); + } + break; + + default: + g_error ("Unhandled node type %d\n", node->type); + break; + } + + g_free (node); +} + +/* returns the fixed size of the blob */ +guint32 +g_ir_node_get_size (GIrNode *node) +{ + GList *l; + gint size, n; + + switch (node->type) + { + case G_IR_NODE_CALLBACK: + size = 12; + break; + + case G_IR_NODE_FUNCTION: + size = 16; + break; + + case G_IR_NODE_PARAM: + size = 12; + break; + + case G_IR_NODE_TYPE: + size = 4; + break; + + case G_IR_NODE_OBJECT: + { + GIrNodeInterface *iface = (GIrNodeInterface *)node; + + n = g_list_length (iface->interfaces); + size = 32 + 2 * (n + (n % 2)); + + for (l = iface->members; l; l = l->next) + size += g_ir_node_get_size ((GIrNode *)l->data); + } + break; + + case G_IR_NODE_INTERFACE: + { + GIrNodeInterface *iface = (GIrNodeInterface *)node; + + n = g_list_length (iface->prerequisites); + size = 28 + 2 * (n + (n % 2)); + + for (l = iface->members; l; l = l->next) + size += g_ir_node_get_size ((GIrNode *)l->data); + } + break; + + case G_IR_NODE_ENUM: + case G_IR_NODE_FLAGS: + { + GIrNodeEnum *enum_ = (GIrNodeEnum *)node; + + size = 20; + for (l = enum_->values; l; l = l->next) + size += g_ir_node_get_size ((GIrNode *)l->data); + } + break; + + case G_IR_NODE_VALUE: + size = 12; + break; + + case G_IR_NODE_STRUCT: + { + GIrNodeStruct *struct_ = (GIrNodeStruct *)node; + + size = 20; + for (l = struct_->members; l; l = l->next) + size += g_ir_node_get_size ((GIrNode *)l->data); + } + break; + + case G_IR_NODE_BOXED: + { + GIrNodeBoxed *boxed = (GIrNodeBoxed *)node; + + size = 20; + for (l = boxed->members; l; l = l->next) + size += g_ir_node_get_size ((GIrNode *)l->data); + } + break; + + case G_IR_NODE_PROPERTY: + size = 12; + break; + + case G_IR_NODE_SIGNAL: + size = 12; + break; + + case G_IR_NODE_VFUNC: + size = 16; + break; + + case G_IR_NODE_FIELD: + size = 12; + break; + + case G_IR_NODE_CONSTANT: + size = 20; + break; + + case G_IR_NODE_ERROR_DOMAIN: + size = 16; + break; + + case G_IR_NODE_XREF: + size = 0; + break; + + case G_IR_NODE_UNION: + { + GIrNodeUnion *union_ = (GIrNodeUnion *)node; + + size = 28; + for (l = union_->members; l; l = l->next) + size += g_ir_node_get_size ((GIrNode *)l->data); + for (l = union_->discriminators; l; l = l->next) + size += g_ir_node_get_size ((GIrNode *)l->data); + } + break; + + default: + g_error ("Unhandled node type '%s'\n", + g_ir_node_type_to_string (node->type)); + size = 0; + } + + g_debug ("node %p type '%s' size %d", node, + g_ir_node_type_to_string (node->type), size); + + return size; +} + +/* returns the full size of the blob including variable-size parts */ +static guint32 +g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node) +{ + GList *l; + gint size, n; + + if (node == NULL && parent != NULL) + g_error ("Caught NULL node, parent=%s", parent->name); + + g_debug ("node %p type '%s'", node, + g_ir_node_type_to_string (node->type)); + + switch (node->type) + { + case G_IR_NODE_CALLBACK: + { + GIrNodeFunction *function = (GIrNodeFunction *)node; + size = 12; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + for (l = function->parameters; l; l = l->next) + { + size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + } + size += g_ir_node_get_full_size_internal (node, (GIrNode *)function->result); + } + break; + + case G_IR_NODE_FUNCTION: + { + GIrNodeFunction *function = (GIrNodeFunction *)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_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + size += g_ir_node_get_full_size_internal (node, (GIrNode *)function->result); + } + break; + + case G_IR_NODE_PARAM: + { + GIrNodeParam *param = (GIrNodeParam *)node; + + size = 12; + if (node->name) + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += g_ir_node_get_full_size_internal (node, (GIrNode *)param->type); + } + break; + + case G_IR_NODE_TYPE: + { + GIrNodeType *type = (GIrNodeType *)node; + if (type->tag < TYPE_TAG_ARRAY) + size = 4; + else + { + g_debug ("node %p type tag '%s'", node, + gi_type_tag_to_string (type->tag)); + + switch (type->tag) + { + case TYPE_TAG_ARRAY: + size = 4 + 4; + if (type->parameter_type1) + size += g_ir_node_get_full_size_internal (node, (GIrNode *)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_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1); + break; + case TYPE_TAG_HASH: + size = 4 + 4 + 4; + if (type->parameter_type1) + size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1); + if (type->parameter_type2) + size += g_ir_node_get_full_size_internal (node, (GIrNode *)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_IR_NODE_OBJECT: + { + GIrNodeInterface *iface = (GIrNodeInterface *)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_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + } + break; + + case G_IR_NODE_INTERFACE: + { + GIrNodeInterface *iface = (GIrNodeInterface *)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_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + } + break; + + case G_IR_NODE_ENUM: + case G_IR_NODE_FLAGS: + { + GIrNodeEnum *enum_ = (GIrNodeEnum *)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_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + } + break; + + case G_IR_NODE_VALUE: + { + size = 12; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + } + break; + + case G_IR_NODE_STRUCT: + { + GIrNodeStruct *struct_ = (GIrNodeStruct *)node; + + size = 20; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + for (l = struct_->members; l; l = l->next) + size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + } + break; + + case G_IR_NODE_BOXED: + { + GIrNodeBoxed *boxed = (GIrNodeBoxed *)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_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + } + break; + + case G_IR_NODE_PROPERTY: + { + GIrNodeProperty *prop = (GIrNodeProperty *)node; + + size = 12; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += g_ir_node_get_full_size_internal (node, (GIrNode *)prop->type); + } + break; + + case G_IR_NODE_SIGNAL: + { + GIrNodeSignal *signal = (GIrNodeSignal *)node; + + size = 12; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + for (l = signal->parameters; l; l = l->next) + size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + size += g_ir_node_get_full_size_internal (node, (GIrNode *)signal->result); + } + break; + + case G_IR_NODE_VFUNC: + { + GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node; + + size = 16; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + for (l = vfunc->parameters; l; l = l->next) + size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + size += g_ir_node_get_full_size_internal (node, (GIrNode *)vfunc->result); + } + break; + + case G_IR_NODE_FIELD: + { + GIrNodeField *field = (GIrNodeField *)node; + + size = 12; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->type); + } + break; + + case G_IR_NODE_CONSTANT: + { + GIrNodeConstant *constant = (GIrNodeConstant *)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_ir_node_get_full_size_internal (node, (GIrNode *)constant->type); + } + break; + + case G_IR_NODE_ERROR_DOMAIN: + { + GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node; + + size = 16; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += ALIGN_VALUE (strlen (domain->getquark) + 1, 4); + } + break; + + case G_IR_NODE_XREF: + { + GIrNodeXRef *xref = (GIrNodeXRef *)node; + + size = 0; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += ALIGN_VALUE (strlen (xref->namespace) + 1, 4); + } + break; + + case G_IR_NODE_UNION: + { + GIrNodeUnion *union_ = (GIrNodeUnion *)node; + + size = 28; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + for (l = union_->members; l; l = l->next) + size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + for (l = union_->discriminators; l; l = l->next) + size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + } + break; + + default: + g_error ("Unknown type tag %d\n", node->type); + size = 0; + } + + g_debug ("node %p type '%s' full size %d", node, + g_ir_node_type_to_string (node->type), size); + + return size; +} + +guint32 +g_ir_node_get_full_size (GIrNode *node) +{ + return g_ir_node_get_full_size_internal (NULL, node); +} + +int +g_ir_node_cmp (GIrNode *node, + GIrNode *other) +{ + if (node->type < other->type) + return -1; + else if (node->type > other->type) + return 1; + else + return strcmp (node->name, other->name); +} + +gboolean +g_ir_node_can_have_member (GIrNode *node) +{ + switch (node->type) + { + case G_IR_NODE_OBJECT: + case G_IR_NODE_INTERFACE: + case G_IR_NODE_BOXED: + case G_IR_NODE_STRUCT: + case G_IR_NODE_UNION: + return TRUE; + }; + return FALSE; +} + +void +g_ir_node_add_member (GIrNode *node, + GIrNodeFunction *member) +{ + g_return_if_fail (node != NULL); + g_return_if_fail (member != NULL); + + switch (node->type) + { + case G_IR_NODE_OBJECT: + case G_IR_NODE_INTERFACE: + { + GIrNodeInterface *iface = (GIrNodeInterface *)node; + iface->members = + g_list_insert_sorted (iface->members, member, + (GCompareFunc) g_ir_node_cmp); + break; + } + case G_IR_NODE_BOXED: + { + GIrNodeBoxed *boxed = (GIrNodeBoxed *)node; + boxed->members = + g_list_insert_sorted (boxed->members, member, + (GCompareFunc) g_ir_node_cmp); + break; + } + case G_IR_NODE_STRUCT: + { + GIrNodeStruct *struct_ = (GIrNodeStruct *)node; + struct_->members = + g_list_insert_sorted (struct_->members, member, + (GCompareFunc) g_ir_node_cmp); + break; + } + case G_IR_NODE_UNION: + { + GIrNodeUnion *union_ = (GIrNodeUnion *)node; + union_->members = + g_list_insert_sorted (union_->members, member, + (GCompareFunc) g_ir_node_cmp); + break; + } + default: + g_error ("Cannot add a member to unknown type tag type %d\n", + node->type); + break; + } +} + +const gchar * +g_ir_node_param_direction_string (GIrNodeParam * node) +{ + if (node->out) + { + if (node->in) + return "in-out"; + else + return "out"; + } + return "in"; +} + +static gint64 +parse_int_value (const gchar *str) +{ + return strtoll (str, NULL, 0); +} + +static guint64 +parse_uint_value (const gchar *str) +{ + return strtoull (str, NULL, 0); +} + +static gdouble +parse_float_value (const gchar *str) +{ + return strtod (str, NULL); +} + +static gboolean +parse_boolean_value (const gchar *str) +{ + if (strcmp (str, "TRUE") == 0) + return TRUE; + + if (strcmp (str, "FALSE") == 0) + return FALSE; + + return parse_int_value (str) ? TRUE : FALSE; +} + +static GIrNode * +find_entry_node (GIrModule *module, + GList *modules, + const gchar *name, + guint16 *idx) + +{ + GList *l; + gint i; + gchar **names; + gint n_names; + GIrNode *result = NULL; + + names = g_strsplit (name, ".", 0); + n_names = g_strv_length (names); + if (n_names > 2) + g_error ("Too many name parts"); + + for (l = module->entries, i = 1; l; l = l->next, i++) + { + GIrNode *node = (GIrNode *)l->data; + + if (n_names > 1) + { + if (node->type != G_IR_NODE_XREF) + continue; + + if (((GIrNodeXRef *)node)->namespace == NULL || + strcmp (((GIrNodeXRef *)node)->namespace, names[0]) != 0) + continue; + } + + if (strcmp (node->name, names[n_names - 1]) == 0) + { + if (idx) + *idx = i; + + result = node; + goto out; + } + } + + if (n_names > 1) + { + GIrNode *node = g_ir_node_new (G_IR_NODE_XREF); + + ((GIrNodeXRef *)node)->namespace = g_strdup (names[0]); + node->name = g_strdup (names[1]); + + module->entries = g_list_append (module->entries, node); + + if (idx) + *idx = g_list_length (module->entries); + + result = node; + + goto out; + } + + g_warning ("Entry '%s' not found", name); + + out: + + g_strfreev (names); + + return result; +} + +static guint16 +find_entry (GIrModule *module, + GList *modules, + const gchar *name) +{ + guint16 idx = 0; + + find_entry_node (module, modules, name, &idx); + + return idx; +} + +static void +serialize_type (GIrModule *module, + GList *modules, + GIrNodeType *node, + GString *str) +{ + gint i; + const gchar* basic[] = { + "void", + "boolean", + "int8", + "uint8", + "int16", + "uint16", + "int32", + "uint32", + "int64", + "uint64", + "int", + "uint", + "long", + "ulong", + "ssize", + "size", + "float", + "double", + "utf8", + "filename", + "string", + "sequence", + "any" + }; + + 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) + { + GIrNode *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_ir_node_build_metadata (GIrNode *node, + GIrModule *module, + GList *modules, + GHashTable *strings, + GHashTable *types, + guchar *data, + guint32 *offset, + guint32 *offset2) +{ + GList *l; + guint32 old_offset = *offset; + guint32 old_offset2 = *offset2; + + g_assert (node != NULL); + + g_debug ("build_metadata (%s)", + g_ir_node_type_to_string (node->type)); + + switch (node->type) + { + case G_IR_NODE_TYPE: + { + GIrNodeType *type = (GIrNodeType *)node; + SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset]; + + *offset += 4; + + if (type->tag < TYPE_TAG_ARRAY || + type->tag == TYPE_TAG_STRING || + type->tag == TYPE_TAG_ANY) + { + 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_ir_node_build_metadata ((GIrNode *)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_ir_node_build_metadata ((GIrNode *)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_ir_node_build_metadata ((GIrNode *)type->parameter_type1, + module, modules, strings, types, + data, &pos, offset2); + g_ir_node_build_metadata ((GIrNode *)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_IR_NODE_FIELD: + { + GIrNodeField *field = (GIrNodeField *)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_ir_node_build_metadata ((GIrNode *)field->type, + module, modules, strings, types, + data, offset, offset2); + } + break; + + case G_IR_NODE_PROPERTY: + { + GIrNodeProperty *prop = (GIrNodeProperty *)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_ir_node_build_metadata ((GIrNode *)prop->type, + module, modules, strings, types, + data, offset, offset2); + } + break; + + case G_IR_NODE_FUNCTION: + { + FunctionBlob *blob = (FunctionBlob *)&data[*offset]; + SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2]; + GIrNodeFunction *function = (GIrNodeFunction *)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_ir_node_build_metadata ((GIrNode *)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) + { + GIrNode *param = (GIrNode *)l->data; + + g_ir_node_build_metadata (param, + module, modules, strings, types, + data, &signature, offset2); + } + } + break; + + case G_IR_NODE_CALLBACK: + { + CallbackBlob *blob = (CallbackBlob *)&data[*offset]; + SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2]; + GIrNodeFunction *function = (GIrNodeFunction *)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_ir_node_build_metadata ((GIrNode *)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) + { + GIrNode *param = (GIrNode *)l->data; + + g_ir_node_build_metadata (param, + module, modules, strings, types, + data, &signature, offset2); + } + } + break; + + case G_IR_NODE_SIGNAL: + { + SignalBlob *blob = (SignalBlob *)&data[*offset]; + SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2]; + GIrNodeSignal *signal = (GIrNodeSignal *)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_ir_node_build_metadata ((GIrNode *)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) + { + GIrNode *param = (GIrNode *)l->data; + + g_ir_node_build_metadata (param, module, modules, strings, types, + data, &signature, offset2); + } + } + break; + + case G_IR_NODE_VFUNC: + { + VFuncBlob *blob = (VFuncBlob *)&data[*offset]; + SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2]; + GIrNodeVFunc *vfunc = (GIrNodeVFunc *)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_ir_node_build_metadata ((GIrNode *)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) + { + GIrNode *param = (GIrNode *)l->data; + + g_ir_node_build_metadata (param, module, modules, strings, + types, data, &signature, offset2); + } + } + break; + + case G_IR_NODE_PARAM: + { + ArgBlob *blob = (ArgBlob *)&data[*offset]; + GIrNodeParam *param = (GIrNodeParam *)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_ir_node_build_metadata ((GIrNode *)param->type, module, modules, + strings, types, data, offset, offset2); + } + break; + + case G_IR_NODE_STRUCT: + { + StructBlob *blob = (StructBlob *)&data[*offset]; + GIrNodeStruct *struct_ = (GIrNodeStruct *)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) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_FIELD) + { + blob->n_fields++; + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + for (l = struct_->members; l; l = l->next) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_FUNCTION) + { + blob->n_methods++; + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + } + break; + + case G_IR_NODE_BOXED: + { + StructBlob *blob = (StructBlob *)&data[*offset]; + GIrNodeBoxed *boxed = (GIrNodeBoxed *)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) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_FIELD) + { + blob->n_fields++; + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + for (l = boxed->members; l; l = l->next) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_FUNCTION) + { + blob->n_methods++; + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + } + break; + + case G_IR_NODE_UNION: + { + UnionBlob *blob = (UnionBlob *)&data[*offset]; + GIrNodeUnion *union_ = (GIrNodeUnion *)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_ir_node_build_metadata ((GIrNode *)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) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_FIELD) + { + blob->n_fields++; + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + for (l = union_->members; l; l = l->next) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_FUNCTION) + { + blob->n_functions++; + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + if (union_->discriminator_type) + { + for (l = union_->discriminators; l; l = l->next) + { + GIrNode *member = (GIrNode *)l->data; + + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + } + break; + + case G_IR_NODE_ENUM: + case G_IR_NODE_FLAGS: + { + EnumBlob *blob = (EnumBlob *)&data[*offset]; + GIrNodeEnum *enum_ = (GIrNodeEnum *)node; + + *offset += 20; + + if (node->type == G_IR_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) + { + GIrNode *value = (GIrNode *)l->data; + + blob->n_values++; + g_ir_node_build_metadata (value, module, modules, strings, types, + data, offset, offset2); + } + } + break; + + case G_IR_NODE_OBJECT: + { + ObjectBlob *blob = (ObjectBlob *)&data[*offset]; + GIrNodeInterface *object = (GIrNodeInterface *)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) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_FIELD) + { + blob->n_fields++; + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = object->members; l; l = l->next) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_PROPERTY) + { + blob->n_properties++; + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = object->members; l; l = l->next) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_FUNCTION) + { + blob->n_methods++; + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = object->members; l; l = l->next) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_SIGNAL) + { + blob->n_signals++; + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = object->members; l; l = l->next) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_VFUNC) + { + blob->n_vfuncs++; + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = object->members; l; l = l->next) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_CONSTANT) + { + blob->n_constants++; + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + } + break; + + case G_IR_NODE_INTERFACE: + { + InterfaceBlob *blob = (InterfaceBlob *)&data[*offset]; + GIrNodeInterface *iface = (GIrNodeInterface *)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) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_PROPERTY) + { + blob->n_properties++; + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = iface->members; l; l = l->next) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_FUNCTION) + { + blob->n_methods++; + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = iface->members; l; l = l->next) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_SIGNAL) + { + blob->n_signals++; + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = iface->members; l; l = l->next) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_VFUNC) + { + blob->n_vfuncs++; + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = iface->members; l; l = l->next) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_CONSTANT) + { + blob->n_constants++; + g_ir_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + } + break; + + + case G_IR_NODE_VALUE: + { + GIrNodeValue *value = (GIrNodeValue *)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_IR_NODE_ERROR_DOMAIN: + { + GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)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_IR_NODE_CONSTANT: + { + GIrNodeConstant *constant = (GIrNodeConstant *)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_ir_node_build_metadata ((GIrNode *)constant->type, module, modules, + strings, types, data, &pos, offset2); + } + break; + default: + g_assert_not_reached (); + } + + g_debug ("node %p type '%s', offset %d -> %d, offset2 %d -> %d", + node, g_ir_node_type_to_string (node->type), + old_offset, *offset, old_offset2, *offset2); + + if (*offset2 - old_offset2 + *offset - old_offset > g_ir_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/girnode.h b/girnode.h new file mode 100644 index 000000000..66144d38b --- /dev/null +++ b/girnode.h @@ -0,0 +1,334 @@ +/* GObject introspection: Parsed GIR + * + * Copyright (C) 2005 Matthias Clasen + * + * 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_IR_NODE_H__ +#define __G_IR_NODE_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GIrNode GIrNode; +typedef struct _GIrNodeFunction GIrNodeFunction; +typedef struct _GIrNodeParam GIrNodeParam; +typedef struct _GIrNodeType GIrNodeType; +typedef struct _GIrNodeInterface GIrNodeInterface; +typedef struct _GIrNodeSignal GIrNodeSignal; +typedef struct _GIrNodeProperty GIrNodeProperty; +typedef struct _GIrNodeVFunc GIrNodeVFunc; +typedef struct _GIrNodeField GIrNodeField; +typedef struct _GIrNodeValue GIrNodeValue; +typedef struct _GIrNodeEnum GIrNodeEnum; +typedef struct _GIrNodeBoxed GIrNodeBoxed; +typedef struct _GIrNodeStruct GIrNodeStruct; +typedef struct _GIrNodeConstant GIrNodeConstant; +typedef struct _GIrNodeErrorDomain GIrNodeErrorDomain; +typedef struct _GIrNodeXRef GIrNodeXRef; +typedef struct _GIrNodeUnion GIrNodeUnion; + +typedef enum +{ + G_IR_NODE_INVALID = 0, + G_IR_NODE_FUNCTION = 1, + G_IR_NODE_CALLBACK = 2, + G_IR_NODE_STRUCT = 3, + G_IR_NODE_BOXED = 4, + G_IR_NODE_ENUM = 5, + G_IR_NODE_FLAGS = 6, + G_IR_NODE_OBJECT = 7, + G_IR_NODE_INTERFACE = 8, + G_IR_NODE_CONSTANT = 9, + G_IR_NODE_ERROR_DOMAIN = 10, + G_IR_NODE_UNION = 11, + G_IR_NODE_PARAM = 12, + G_IR_NODE_TYPE = 13, + G_IR_NODE_PROPERTY = 14, + G_IR_NODE_SIGNAL = 15, + G_IR_NODE_VALUE = 16, + G_IR_NODE_VFUNC = 17, + G_IR_NODE_FIELD = 18, + G_IR_NODE_XREF = 19 +} GIrNodeTypeId; + +struct _GIrNode +{ + GIrNodeTypeId type; + gchar *name; +}; + +struct _GIrNodeXRef +{ + GIrNode node; + + gchar *namespace; +}; + +struct _GIrNodeFunction +{ + GIrNode node; + + gboolean deprecated; + + gboolean is_method; + gboolean is_setter; + gboolean is_getter; + gboolean is_constructor; + gboolean wraps_vfunc; + + gchar *symbol; + + GIrNodeParam *result; + GList *parameters; +}; + +struct _GIrNodeType +{ + GIrNode node; + + gboolean is_pointer; + gboolean is_basic; + gboolean is_array; + gboolean is_glist; + gboolean is_gslist; + gboolean is_ghashtable; + gboolean is_interface; + gboolean is_error; + gint tag; + + gchar *unparsed; + + gboolean zero_terminated; + gboolean has_length; + gint length; + + GIrNodeType *parameter_type1; + GIrNodeType *parameter_type2; + + gchar *interface; + gchar **errors; +}; + +struct _GIrNodeParam +{ + GIrNode node; + + gboolean in; + gboolean out; + gboolean dipper; + gboolean optional; + gboolean retval; + gboolean null_ok; + gboolean transfer; + gboolean shallow_transfer; + + GIrNodeType *type; +}; + +struct _GIrNodeProperty +{ + GIrNode node; + + gboolean deprecated; + + gchar *name; + gboolean readable; + gboolean writable; + gboolean construct; + gboolean construct_only; + + GIrNodeType *type; +}; + +struct _GIrNodeSignal +{ + GIrNode node; + + gboolean deprecated; + + gboolean run_first; + gboolean run_last; + gboolean run_cleanup; + gboolean no_recurse; + gboolean detailed; + gboolean action; + gboolean no_hooks; + + gboolean has_class_closure; + gboolean true_stops_emit; + + gint class_closure; + + GList *parameters; + GIrNodeParam *result; +}; + +struct _GIrNodeVFunc +{ + GIrNode node; + + gboolean must_chain_up; + gboolean must_be_implemented; + gboolean must_not_be_implemented; + gboolean is_class_closure; + + GList *parameters; + GIrNodeParam *result; + + gint offset; +}; + +struct _GIrNodeField +{ + GIrNode node; + + gboolean readable; + gboolean writable; + gint bits; + gint offset; + + GIrNodeType *type; +}; + +struct _GIrNodeInterface +{ + GIrNode node; + + gboolean deprecated; + + gchar *gtype_name; + gchar *gtype_init; + + gchar *parent; + + GList *interfaces; + GList *prerequisites; + + GList *members; +}; + +struct _GIrNodeValue +{ + GIrNode node; + + gboolean deprecated; + + guint32 value; +}; + +struct _GIrNodeConstant +{ + GIrNode node; + + gboolean deprecated; + + GIrNodeType *type; + + gchar *value; +}; + +struct _GIrNodeEnum +{ + GIrNode node; + + gboolean deprecated; + + gchar *gtype_name; + gchar *gtype_init; + + GList *values; +}; + +struct _GIrNodeBoxed +{ + GIrNode node; + + gboolean deprecated; + + gchar *gtype_name; + gchar *gtype_init; + + GList *members; +}; + +struct _GIrNodeStruct +{ + GIrNode node; + + gboolean deprecated; + + GList *members; +}; + +struct _GIrNodeUnion +{ + GIrNode node; + + gboolean deprecated; + + GList *members; + GList *discriminators; + + gchar *gtype_name; + gchar *gtype_init; + + gint discriminator_offset; + GIrNodeType *discriminator_type; +}; + + +struct _GIrNodeErrorDomain +{ + GIrNode node; + + gboolean deprecated; + + gchar *name; + gchar *getquark; + gchar *codes; +}; + + +GIrNode * g_ir_node_new (GIrNodeTypeId type); +void g_ir_node_free (GIrNode *node); +guint32 g_ir_node_get_size (GIrNode *node); +guint32 g_ir_node_get_full_size (GIrNode *node); +void g_ir_node_build_metadata (GIrNode *node, + GIrModule *module, + GList *modules, + GHashTable *strings, + GHashTable *types, + guchar *data, + guint32 *offset, + guint32 *offset2); +int g_ir_node_cmp (GIrNode *node, + GIrNode *other); +gboolean g_ir_node_can_have_member (GIrNode *node); +void g_ir_node_add_member (GIrNode *node, + GIrNodeFunction *member); +guint32 write_string (const gchar *str, + GHashTable *strings, + guchar *data, + guint32 *offset); + +const gchar * g_ir_node_param_direction_string (GIrNodeParam * node); + +G_END_DECLS + +#endif /* __G_IR_NODE_H__ */ diff --git a/girparser.c b/girparser.c new file mode 100644 index 000000000..565542c4e --- /dev/null +++ b/girparser.c @@ -0,0 +1,2314 @@ +/* GObject introspection: A parser for the XML GIR format + * + * Copyright (C) 2008 Philip Van Hoof + * + * 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 +#include "girmodule.h" +#include "girnode.h" +#include "gtypelib.h" + +typedef enum +{ + STATE_START, + STATE_END, + STATE_REPOSITORY, + STATE_NAMESPACE, + STATE_ENUM, + STATE_BITFIELD, /* 5 */ + STATE_FUNCTION, + STATE_FUNCTION_RETURN, + STATE_FUNCTION_PARAMETERS, + STATE_FUNCTION_PARAMETER, + STATE_CLASS, /* 10 */ + STATE_CLASS_FIELD, + STATE_CLASS_PROPERTY, + STATE_INTERFACE, + STATE_INTERFACE_PROPERTY, + STATE_INTERFACE_FIELD, /* 15 */ + STATE_IMPLEMENTS, + STATE_REQUIRES, + STATE_BOXED, + STATE_BOXED_FIELD, + STATE_STRUCT, /* 20 */ + STATE_STRUCT_FIELD, + STATE_ERRORDOMAIN, + STATE_UNION, + STATE_CONSTANT +} ParseState; + +typedef struct _ParseContext ParseContext; +struct _ParseContext +{ + ParseState state; + ParseState prev_state; + + GList *modules; + + GIrModule *current_module; + GIrNode *current_node; + GIrNode *current_typed; +}; + +#define MISSING_ATTRIBUTE(ctx,error,element,attribute) \ + do { \ + int line_number, char_number; \ + g_markup_parse_context_get_position (context, &line_number, &char_number); \ + g_set_error (error, \ + G_MARKUP_ERROR, \ + G_MARKUP_ERROR_INVALID_CONTENT, \ + "Line %d, character %d: The attribute '%s' on the element '%s' must be specified", \ + line_number, char_number, attribute, element); \ + } while (0) + +static void +backtrace_stderr (void) +{ + void *array[50]; + int size; + char **strings; + size_t i; + + size = backtrace (array, 50); + strings = (char**) backtrace_symbols (array, size); + + fprintf (stderr, "--- BACKTRACE (%zd frames) ---\n", size); + + for (i = 0; i < size; i++) + fprintf (stderr, "%s\n", strings[i]); + + fprintf (stderr, "--- END BACKTRACE ---\n", size); + + free (strings); +} + + +static const gchar * +find_attribute (const gchar *name, + const gchar **attribute_names, + const gchar **attribute_values) +{ + gint i; + + for (i = 0; attribute_names[i] != NULL; i++) + if (strcmp (attribute_names[i], name) == 0) + return attribute_values[i]; + + return 0; +} + +static void +state_switch (ParseContext *ctx, ParseState newstate) +{ + ctx->prev_state = ctx->state; + ctx->state = newstate; +} + +static GIrNodeType * +parse_type_internal (gchar *str, gchar **rest) +{ + gint i; + + static struct { + const gchar *str; + gint tag; + gboolean pointer; + } basic[] = { + { "void", TYPE_TAG_VOID, 0 }, + { "gpointer", TYPE_TAG_VOID, 1 }, + { "bool", TYPE_TAG_BOOLEAN, 0 }, + { "gboolean", TYPE_TAG_BOOLEAN, 0 }, +#if 0 + { "char", TYPE_TAG_INT8, 0 }, + { "gchar", TYPE_TAG_INT8, 0 }, + { "guchar", TYPE_TAG_UINT8, 0 }, +#endif + { "int8_t", TYPE_TAG_INT8, 0 }, + { "int8", TYPE_TAG_INT8, 0 }, + { "gint8", TYPE_TAG_INT8, 0 }, + { "uint8_t", TYPE_TAG_UINT8, 0 }, + { "uint8", TYPE_TAG_UINT8, 0 }, + { "guint8", TYPE_TAG_UINT8, 0 }, + { "int16_t", TYPE_TAG_INT16, 0 }, + { "int16", TYPE_TAG_INT16, 0 }, + { "gint16", TYPE_TAG_INT16, 0 }, + { "uint16_t", TYPE_TAG_UINT16, 0 }, + { "uint16", TYPE_TAG_UINT16, 0 }, + { "guint16", TYPE_TAG_UINT16, 0 }, + { "int32_t", TYPE_TAG_INT32, 0 }, + { "int32", TYPE_TAG_INT32, 0 }, + { "gint32", TYPE_TAG_INT32, 0 }, + { "uint32_t", TYPE_TAG_UINT32, 0 }, + { "uint32", TYPE_TAG_UINT32, 0 }, + { "guint32", TYPE_TAG_UINT32, 0 }, + { "int64_t", TYPE_TAG_INT64, 0 }, + { "int64", TYPE_TAG_INT64, 0 }, + { "gint64", TYPE_TAG_INT64, 0 }, + { "uint64_t", TYPE_TAG_UINT64, 0 }, + { "uint64", TYPE_TAG_UINT64, 0 }, + { "guint64", TYPE_TAG_UINT64, 0 }, + { "int", TYPE_TAG_INT, 0 }, + { "gint", TYPE_TAG_INT, 0 }, + { "uint", TYPE_TAG_UINT, 0 }, + { "guint", TYPE_TAG_UINT, 0 }, + { "long", TYPE_TAG_LONG, 0 }, + { "glong", TYPE_TAG_LONG, 0 }, + { "ulong", TYPE_TAG_ULONG, 0 }, + { "gulong", TYPE_TAG_ULONG, 0 }, + { "ssize_t", TYPE_TAG_SSIZE, 0 }, + { "gssize", TYPE_TAG_SSIZE, 0 }, + { "size_t", TYPE_TAG_SIZE, 0 }, + { "gsize", TYPE_TAG_SIZE, 0 }, + { "float", TYPE_TAG_FLOAT, 0 }, + { "gfloat", TYPE_TAG_FLOAT, 0 }, + { "double", TYPE_TAG_DOUBLE, 0 }, + { "gdouble", TYPE_TAG_DOUBLE, 0 }, + { "utf8", TYPE_TAG_UTF8, 1 }, + { "gchar*", TYPE_TAG_UTF8, 1 }, + { "filename", TYPE_TAG_FILENAME,1 }, + { "string", TYPE_TAG_STRING, 1 } + }; + + gint n_basic = G_N_ELEMENTS (basic); + gchar *start, *end; + + GIrNodeType *type; + + type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE); + + str = g_strstrip (str); + + type->unparsed = g_strdup (str); + + *rest = str; + for (i = 0; i < n_basic; i++) + { + if (g_str_has_prefix (*rest, basic[i].str)) + { + type->is_basic = TRUE; + type->tag = basic[i].tag; + type->is_pointer = basic[i].pointer; + + *rest += strlen(basic[i].str); + *rest = g_strchug (*rest); + if (**rest == '*' && !type->is_pointer) + { + type->is_pointer = TRUE; + (*rest)++; + } + + break; + } + } + + if (i < n_basic) + /* found a basic type */; + else if (g_str_has_prefix (*rest, "GList") || + g_str_has_prefix (*rest, "GSList")) + { + if (g_str_has_prefix (*rest, "GList")) + { + type->tag = TYPE_TAG_LIST; + type->is_glist = TRUE; + type->is_pointer = TRUE; + *rest += strlen ("GList"); + } + else + { + type->tag = TYPE_TAG_SLIST; + type->is_gslist = TRUE; + type->is_pointer = TRUE; + *rest += strlen ("GSList"); + } + + *rest = g_strchug (*rest); + + if (**rest == '<') + { + (*rest)++; + + type->parameter_type1 = parse_type_internal (*rest, rest); + if (type->parameter_type1 == NULL) + goto error; + + *rest = g_strchug (*rest); + + if ((*rest)[0] != '>') + goto error; + (*rest)++; + } + } + else if (g_str_has_prefix (*rest, "GHashTable")) + { + type->tag = TYPE_TAG_HASH; + type->is_ghashtable = TRUE; + type->is_pointer = TRUE; + *rest += strlen ("GHashTable"); + + *rest = g_strchug (*rest); + + if (**rest == '<') + { + (*rest)++; + + type->parameter_type1 = parse_type_internal (*rest, rest); + if (type->parameter_type1 == NULL) + goto error; + + *rest = g_strchug (*rest); + + if ((*rest)[0] != ',') + goto error; + (*rest)++; + + type->parameter_type2 = parse_type_internal (*rest, rest); + if (type->parameter_type2 == NULL) + goto error; + + if ((*rest)[0] != '>') + goto error; + (*rest)++; + } + } + else if (g_str_has_prefix (*rest, "GError")) + { + type->tag = TYPE_TAG_ERROR; + type->is_error = TRUE; + type->is_pointer = TRUE; + *rest += strlen ("GError"); + + *rest = g_strchug (*rest); + + if (**rest == '<') + { + (*rest)++; + + end = strchr (*rest, '>'); + str = g_strndup (*rest, end - *rest); + type->errors = g_strsplit (str, ",", 0); + g_free (str); + + *rest = end + 1; + } + } + else + { + type->tag = TYPE_TAG_INTERFACE; + type->is_interface = TRUE; + start = *rest; + + /* must be an interface type */ + while (g_ascii_isalnum (**rest) || + **rest == '.' || + **rest == '-' || + **rest == '_' || + **rest == ':') + (*rest)++; + + type->interface = g_strndup (start, *rest - start); + + *rest = g_strchug (*rest); + if (**rest == '*') + { + type->is_pointer = TRUE; + (*rest)++; + } + } + + *rest = g_strchug (*rest); + if (g_str_has_prefix (*rest, "[")) + { + GIrNodeType *array; + + array = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE); + + array->tag = TYPE_TAG_ARRAY; + array->is_pointer = TRUE; + array->is_array = TRUE; + + array->parameter_type1 = type; + + array->zero_terminated = FALSE; + array->has_length = FALSE; + array->length = 0; + + if (!g_str_has_prefix (*rest, "[]")) + { + gchar *end, *str, **opts; + + end = strchr (*rest, ']'); + str = g_strndup (*rest + 1, (end - *rest) - 1); + opts = g_strsplit (str, ",", 0); + + *rest = end + 1; + + for (i = 0; opts[i]; i++) + { + gchar **vals; + + vals = g_strsplit (opts[i], "=", 0); + + if (strcmp (vals[0], "zero-terminated") == 0) + array->zero_terminated = (strcmp (vals[1], "1") == 0); + else if (strcmp (vals[0], "length") == 0) + { + array->has_length = TRUE; + array->length = atoi (vals[1]); + } + + g_strfreev (vals); + } + + g_free (str); + g_strfreev (opts); + } + + type = array; + } + + return type; + + error: + g_ir_node_free ((GIrNode *)type); + + return NULL; +} + +static GIrNodeType * +parse_type (const gchar *type) +{ + gchar *str; + gchar *rest; + GIrNodeType *node; + + str = g_strdup (type); + node = parse_type_internal (str, &rest); + g_free (str); + + return node; +} + +static gboolean +start_glib_boxed (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + if (strcmp (element_name, "glib:boxed") == 0 && + ctx->state == STATE_NAMESPACE) + { + const gchar *name; + const gchar *typename; + const gchar *typeinit; + const gchar *deprecated; + + name = find_attribute ("glib:name", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "glib:name"); + else if (typename == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); + else if (typeinit == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); + else + { + GIrNodeBoxed *boxed; + + boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED); + + ((GIrNode *)boxed)->name = g_strdup (name); + boxed->gtype_name = g_strdup (typename); + boxed->gtype_init = g_strdup (typeinit); + if (deprecated && strcmp (deprecated, "1") == 0) + boxed->deprecated = TRUE; + else + boxed->deprecated = FALSE; + + ctx->current_node = (GIrNode *)boxed; + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, boxed); + + state_switch (ctx, STATE_BOXED); + } + + return TRUE; + } + + return FALSE; +} + +static gboolean +start_function (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + if ((ctx->state == STATE_NAMESPACE && + (strcmp (element_name, "function") == 0 || + strcmp (element_name, "callback") == 0)) || + ((ctx->state == STATE_CLASS || + ctx->state == STATE_INTERFACE || + ctx->state == STATE_BOXED || + ctx->state == STATE_UNION) && + (strcmp (element_name, "method") == 0 || + strcmp (element_name, "callback") == 0)) || + ((ctx->state == STATE_CLASS || + ctx->state == STATE_BOXED) && + (strcmp (element_name, "constructor") == 0)) || + (ctx->state == STATE_STRUCT && strcmp (element_name, "callback") == 0)) + { + const gchar *name; + const gchar *symbol; + const gchar *deprecated; + const gchar *type; + + name = find_attribute ("name", attribute_names, attribute_values); + symbol = find_attribute ("c:identifier", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + type = find_attribute ("type", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else if (strcmp (element_name, "callback") != 0 && symbol == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "c:identifier"); + else + { + GIrNodeFunction *function; + + function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION); + + ((GIrNode *)function)->name = g_strdup (name); + function->symbol = g_strdup (symbol); + function->parameters = NULL; + if (deprecated && strcmp (deprecated, "1") == 0) + function->deprecated = TRUE; + else + function->deprecated = FALSE; + + if (strcmp (element_name, "method") == 0 || + strcmp (element_name, "constructor") == 0) + { + function->is_method = TRUE; + + if (type && strcmp (type, "setter") == 0) + function->is_setter = TRUE; + else if (type && strcmp (type, "getter") == 0) + function->is_getter = TRUE; + + if (strcmp (element_name, "constructor") == 0) + function->is_constructor = TRUE; + else + function->is_constructor = FALSE; + } + else + { + function->is_method = FALSE; + function->is_setter = FALSE; + function->is_getter = FALSE; + function->is_constructor = FALSE; + if (strcmp (element_name, "callback") == 0) + ((GIrNode *)function)->type = G_IR_NODE_CALLBACK; + } + + if (ctx->current_node == NULL) + { + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, function); + } + else + switch (ctx->current_node->type) + { + case G_IR_NODE_INTERFACE: + case G_IR_NODE_OBJECT: + { + GIrNodeInterface *iface; + + iface = (GIrNodeInterface *)ctx->current_node; + iface->members = g_list_append (iface->members, function); + } + break; + case G_IR_NODE_BOXED: + { + GIrNodeBoxed *boxed; + + boxed = (GIrNodeBoxed *)ctx->current_node; + boxed->members = g_list_append (boxed->members, function); + } + break; + case G_IR_NODE_STRUCT: + { + GIrNodeStruct *struct_; + + struct_ = (GIrNodeStruct *)ctx->current_node; + struct_->members = g_list_append (struct_->members, function); } + break; + case G_IR_NODE_UNION: + { + GIrNodeUnion *union_; + + union_ = (GIrNodeUnion *)ctx->current_node; + union_->members = g_list_append (union_->members, function); + } + break; + default: + g_assert_not_reached (); + } + + ctx->current_node = (GIrNode *)function; + state_switch (ctx, STATE_FUNCTION); + + return TRUE; + } + } + + return FALSE; +} + +static gboolean +start_parameter (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + const gchar *name; + const gchar *direction; + const gchar *retval; + const gchar *dipper; + const gchar *optional; + const gchar *nullok; + const gchar *transfer; + GIrNodeParam *param; + + if (!(strcmp (element_name, "parameter") == 0 && + ctx->state == STATE_FUNCTION_PARAMETERS)) + return FALSE; + + name = find_attribute ("name", attribute_names, attribute_values); + direction = find_attribute ("direction", attribute_names, attribute_values); + retval = find_attribute ("retval", attribute_names, attribute_values); + dipper = find_attribute ("dipper", attribute_names, attribute_values); + optional = find_attribute ("optional", attribute_names, attribute_values); + nullok = find_attribute ("null-ok", attribute_names, attribute_values); + transfer = find_attribute ("transfer", attribute_names, attribute_values); + + if (name == NULL) + name = "unknown"; + + param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM); + + ctx->current_typed = (GIrNode*) param; + + state_switch (ctx, STATE_FUNCTION_PARAMETER); + + if (direction && strcmp (direction, "out") == 0) + { + param->in = FALSE; + param->out = TRUE; + } + else if (direction && strcmp (direction, "inout") == 0) + { + param->in = TRUE; + param->out = TRUE; + } + else + { + param->in = TRUE; + param->out = FALSE; + } + + if (retval && strcmp (retval, "1") == 0) + param->retval = TRUE; + else + param->retval = FALSE; + + if (dipper && strcmp (dipper, "1") == 0) + param->dipper = TRUE; + else + param->dipper = FALSE; + + if (optional && strcmp (optional, "1") == 0) + param->optional = TRUE; + else + param->optional = FALSE; + + if (nullok && strcmp (nullok, "1") == 0) + param->null_ok = TRUE; + else + param->null_ok = FALSE; + + if (transfer && strcmp (transfer, "none") == 0) + { + param->transfer = FALSE; + param->shallow_transfer = FALSE; + } + else if (transfer && strcmp (transfer, "shallow") == 0) + { + param->transfer = FALSE; + param->shallow_transfer = TRUE; + } + else + { + param->transfer = TRUE; + param->shallow_transfer = FALSE; + } + + ((GIrNode *)param)->name = g_strdup (name); + + switch (ctx->current_node->type) + { + case G_IR_NODE_FUNCTION: + case G_IR_NODE_CALLBACK: + { + GIrNodeFunction *func; + + func = (GIrNodeFunction *)ctx->current_node; + func->parameters = g_list_append (func->parameters, param); + } + break; + case G_IR_NODE_SIGNAL: + { + GIrNodeSignal *signal; + + signal = (GIrNodeSignal *)ctx->current_node; + signal->parameters = g_list_append (signal->parameters, param); + } + break; + case G_IR_NODE_VFUNC: + { + GIrNodeVFunc *vfunc; + + vfunc = (GIrNodeVFunc *)ctx->current_node; + vfunc->parameters = g_list_append (vfunc->parameters, param); + } + break; + default: + g_assert_not_reached (); + } + + return TRUE; +} + +static gboolean +start_field (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + if (strcmp (element_name, "field") == 0 && + (ctx->state == STATE_CLASS || + ctx->state == STATE_BOXED || + ctx->state == STATE_STRUCT || + ctx->state == STATE_UNION || + ctx->state == STATE_INTERFACE)) + { + const gchar *name; + const gchar *type; + const gchar *readable; + const gchar *writable; + const gchar *bits; + const gchar *branch; + const gchar *offset; + + name = find_attribute ("name", attribute_names, attribute_values); + type = find_attribute ("c:type", attribute_names, attribute_values); + readable = find_attribute ("readable", attribute_names, attribute_values); + writable = find_attribute ("writable", attribute_names, attribute_values); + bits = find_attribute ("bits", attribute_names, attribute_values); + branch = find_attribute ("branch", attribute_names, attribute_values); + offset = find_attribute ("offset", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeField *field; + + field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD); + ctx->current_typed = (GIrNode*) field; + ((GIrNode *)field)->name = g_strdup (name); + if (readable && strcmp (readable, "1") == 0) + field->readable = TRUE; + else + field->readable = FALSE; + + if (writable && strcmp (writable, "1") == 0) + field->writable = TRUE; + else + field->writable = FALSE; + + if (bits) + field->bits = atoi (bits); + else + field->bits = 0; + + if (offset) + field->offset = atoi (offset); + else + field->offset = 0; + + switch (ctx->current_node->type) + { + case G_IR_NODE_OBJECT: + { + GIrNodeInterface *iface; + + iface = (GIrNodeInterface *)ctx->current_node; + iface->members = g_list_append (iface->members, field); + state_switch (ctx, STATE_CLASS_FIELD); + } + break; + case G_IR_NODE_INTERFACE: + { + GIrNodeInterface *iface; + + iface = (GIrNodeInterface *)ctx->current_node; + iface->members = g_list_append (iface->members, field); + state_switch (ctx, STATE_INTERFACE_FIELD); + } + break; + case G_IR_NODE_BOXED: + { + GIrNodeBoxed *boxed; + + boxed = (GIrNodeBoxed *)ctx->current_node; + boxed->members = g_list_append (boxed->members, field); + state_switch (ctx, STATE_BOXED_FIELD); + } + break; + case G_IR_NODE_STRUCT: + { + GIrNodeStruct *struct_; + + struct_ = (GIrNodeStruct *)ctx->current_node; + struct_->members = g_list_append (struct_->members, field); + state_switch (ctx, STATE_STRUCT_FIELD); + } + break; + case G_IR_NODE_UNION: + { + GIrNodeUnion *union_; + + union_ = (GIrNodeUnion *)ctx->current_node; + union_->members = g_list_append (union_->members, field); + if (branch) + { + GIrNodeConstant *constant; + + constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT); + ((GIrNode *)constant)->name = g_strdup (name); + constant->value = g_strdup (branch); + constant->type = union_->discriminator_type; + constant->deprecated = FALSE; + + union_->discriminators = g_list_append (union_->discriminators, constant); + } + } + break; + default: + g_assert_not_reached (); + } + } + return TRUE; + } + + return FALSE; +} + +static gboolean +start_enum (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + if ((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) || + (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE)) + { + const gchar *name; + const gchar *typename; + const gchar *typeinit; + const gchar *deprecated; + + name = find_attribute ("name", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeEnum *enum_; + + if (strcmp (element_name, "enumeration") == 0) + enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM); + else + enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS); + ((GIrNode *)enum_)->name = g_strdup (name); + enum_->gtype_name = g_strdup (typename); + enum_->gtype_init = g_strdup (typeinit); + if (deprecated && strcmp (deprecated, "1") == 0) + enum_->deprecated = TRUE; + else + enum_->deprecated = FALSE; + + ctx->current_node = (GIrNode *) enum_; + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, enum_); + + state_switch (ctx, STATE_ENUM); + } + + return TRUE; + } + return FALSE; +} + +static gboolean +start_property (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + if (strcmp (element_name, "property") == 0 && + (ctx->state == STATE_CLASS || + ctx->state == STATE_INTERFACE)) + { + const gchar *name; + const gchar *readable; + const gchar *writable; + const gchar *construct; + const gchar *construct_only; + + name = find_attribute ("name", attribute_names, attribute_values); + readable = find_attribute ("readable", attribute_names, attribute_values); + writable = find_attribute ("writable", attribute_names, attribute_values); + construct = find_attribute ("construct", attribute_names, attribute_values); + construct_only = find_attribute ("construct-only", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeProperty *property; + GIrNodeInterface *iface; + + property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY); + ctx->current_typed = (GIrNode*) property; + + ((GIrNode *)property)->name = g_strdup (name); + + if (readable && strcmp (readable, "1") == 0) + property->readable = TRUE; + else + property->readable = FALSE; + if (writable && strcmp (writable, "1") == 0) + property->writable = TRUE; + else + property->writable = FALSE; + if (construct && strcmp (construct, "1") == 0) + property->construct = TRUE; + else + property->construct = FALSE; + if (construct_only && strcmp (construct_only, "1") == 0) + property->construct_only = TRUE; + else + property->construct_only = FALSE; + + iface = (GIrNodeInterface *)ctx->current_node; + iface->members = g_list_append (iface->members, property); + + if (ctx->state == STATE_CLASS) + state_switch (ctx, STATE_CLASS_PROPERTY); + else if (ctx->state == STATE_INTERFACE) + state_switch (ctx, STATE_INTERFACE_PROPERTY); + else + g_assert_not_reached (); + } + + return TRUE; + } + return FALSE; +} + +static gint +parse_value (const gchar *str) +{ + gchar *shift_op; + + /* FIXME just a quick hack */ + shift_op = strstr (str, "<<"); + + if (shift_op) + { + gint base, shift; + + base = strtol (str, NULL, 10); + shift = strtol (shift_op + 3, NULL, 10); + + return base << shift; + } + else + return strtol (str, NULL, 10); + + return 0; +} + +static gboolean +start_member (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + if (strcmp (element_name, "member") == 0 && + ctx->state == STATE_ENUM) + { + const gchar *name; + const gchar *value; + const gchar *deprecated; + + name = find_attribute ("name", attribute_names, attribute_values); + value = find_attribute ("value", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeEnum *enum_; + GIrNodeValue *value_; + + value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE); + + ((GIrNode *)value_)->name = g_strdup (name); + + value_->value = parse_value (value); + + if (deprecated && strcmp (deprecated, "1") == 0) + value_->deprecated = TRUE; + else + value_->deprecated = FALSE; + + enum_ = (GIrNodeEnum *)ctx->current_node; + enum_->values = g_list_append (enum_->values, value_); + } + + return TRUE; + } + return FALSE; +} + +static gboolean +start_constant (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + if (strcmp (element_name, "constant") == 0 && + (ctx->state == STATE_NAMESPACE || + ctx->state == STATE_CLASS || + ctx->state == STATE_INTERFACE)) + { + const gchar *name; + const gchar *type; + const gchar *value; + const gchar *deprecated; + + name = find_attribute ("name", attribute_names, attribute_values); + type = find_attribute ("c:type", attribute_names, attribute_values); + value = find_attribute ("value", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else if (type == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "c:type"); + else if (value == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "value"); + else + { + GIrNodeConstant *constant; + + constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT); + + ((GIrNode *)constant)->name = g_strdup (name); + constant->value = g_strdup (value); + + constant->type = parse_type (type); + + if (deprecated && strcmp (deprecated, "1") == 0) + constant->deprecated = TRUE; + else + constant->deprecated = FALSE; + + if (ctx->state == STATE_NAMESPACE) + { + ctx->current_node = (GIrNode *) constant; + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, constant); + } + else + { + GIrNodeInterface *iface; + + iface = (GIrNodeInterface *)ctx->current_node; + iface->members = g_list_append (iface->members, constant); + } + state_switch (ctx, STATE_CONSTANT); + } + + return TRUE; + } + return FALSE; +} + +static gboolean +start_errordomain (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + if (strcmp (element_name, "errordomain") == 0 && + ctx->state == STATE_NAMESPACE) + { + const gchar *name; + const gchar *getquark; + const gchar *codes; + const gchar *deprecated; + + name = find_attribute ("name", attribute_names, attribute_values); + getquark = find_attribute ("get-quark", attribute_names, attribute_values); + codes = find_attribute ("codes", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else if (getquark == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "getquark"); + else if (codes == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "codes"); + else + { + GIrNodeErrorDomain *domain; + + domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN); + + ((GIrNode *)domain)->name = g_strdup (name); + domain->getquark = g_strdup (getquark); + domain->codes = g_strdup (codes); + + if (deprecated && strcmp (deprecated, "1") == 0) + domain->deprecated = TRUE; + else + domain->deprecated = FALSE; + + ctx->current_node = (GIrNode *) domain; + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, domain); + + state_switch (ctx, STATE_ERRORDOMAIN); + } + + return TRUE; + } + return FALSE; +} + +static gboolean +start_interface (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + if (strcmp (element_name, "interface") == 0 && + ctx->state == STATE_NAMESPACE) + { + const gchar *name; + const gchar *typename; + const gchar *typeinit; + const gchar *deprecated; + + name = find_attribute ("name", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else if (typename == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); + else if (typeinit == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); + else + { + GIrNodeInterface *iface; + + iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE); + ((GIrNode *)iface)->name = g_strdup (name); + iface->gtype_name = g_strdup (typename); + iface->gtype_init = g_strdup (typeinit); + if (deprecated && strcmp (deprecated, "1") == 0) + iface->deprecated = TRUE; + else + iface->deprecated = FALSE; + + ctx->current_node = (GIrNode *) iface; + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, iface); + + state_switch (ctx, STATE_INTERFACE); + + } + + return TRUE; + } + return FALSE; +} + +static gboolean +start_class (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + if (strcmp (element_name, "class") == 0 && + ctx->state == STATE_NAMESPACE) + { + const gchar *name; + const gchar *parent; + const gchar *typename; + const gchar *typeinit; + const gchar *deprecated; + + name = find_attribute ("name", attribute_names, attribute_values); + parent = find_attribute ("parent", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else if (typename == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); + else if (typeinit == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); + else + { + GIrNodeInterface *iface; + + iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT); + ((GIrNode *)iface)->name = g_strdup (name); + iface->gtype_name = g_strdup (typename); + iface->gtype_init = g_strdup (typeinit); + iface->parent = g_strdup (parent); + if (deprecated && strcmp (deprecated, "1") == 0) + iface->deprecated = TRUE; + else + iface->deprecated = FALSE; + + ctx->current_node = (GIrNode *) iface; + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, iface); + + state_switch (ctx, STATE_CLASS); + } + + return TRUE; + } + return FALSE; +} + +static gboolean +start_type (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + const gchar *name; + const gchar *ctype; + + if (strcmp (element_name, "type") != 0 || + !(ctx->state == STATE_FUNCTION_PARAMETER || + ctx->state == STATE_FUNCTION_RETURN || + ctx->state == STATE_STRUCT_FIELD || + ctx->state == STATE_CLASS_PROPERTY || + ctx->state == STATE_CLASS_FIELD || + ctx->state == STATE_INTERFACE_FIELD || + ctx->state == STATE_BOXED_FIELD + )) + return FALSE; + + if (!ctx->current_typed) + { + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "The element is invalid here"); + return FALSE; + } + + name = find_attribute ("name", attribute_names, attribute_values); + ctype = find_attribute ("c:type", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + if (ctype == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "c:type"); + + switch (ctx->current_typed->type) + { + case G_IR_NODE_PARAM: + { + GIrNodeParam *param; + param = (GIrNodeParam *)ctx->current_typed; + param->type = parse_type (name); + } + break; + case G_IR_NODE_FIELD: + { + GIrNodeField *field = (GIrNodeField *)ctx->current_typed; + field->type = parse_type (name); + } + break; + case G_IR_NODE_PROPERTY: + { + GIrNodeProperty *property = (GIrNodeProperty *) ctx->current_typed; + property->type = parse_type (name); + } + break; + default: + g_printerr("current node is %d\n", ctx->current_node->type); + g_assert_not_reached (); + } + + ctx->current_typed = NULL; + return TRUE; +} + +static gboolean +start_return_value (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + if (strcmp (element_name, "return-value") == 0 && + ctx->state == STATE_FUNCTION) + { + GIrNodeParam *param; + + param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM); + param->in = FALSE; + param->out = FALSE; + param->retval = TRUE; + + ctx->current_typed = (GIrNode*) param; + + state_switch (ctx, STATE_FUNCTION_RETURN); + + switch (ctx->current_node->type) + { + case G_IR_NODE_FUNCTION: + case G_IR_NODE_CALLBACK: + { + GIrNodeFunction *func = (GIrNodeFunction *)ctx->current_node; + func->result = param; + } + break; + case G_IR_NODE_SIGNAL: + { + GIrNodeSignal *signal = (GIrNodeSignal *)ctx->current_node; + signal->result = param; + } + break; + case G_IR_NODE_VFUNC: + { + GIrNodeVFunc *vfunc = (GIrNodeVFunc *)ctx->current_node; + vfunc->result = param; + } + break; + default: + g_assert_not_reached (); + } + + return TRUE; + } + + return FALSE; +} + +static gboolean +start_glib_signal (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + if (strcmp (element_name, "glib:signal") == 0 && + (ctx->state == STATE_CLASS || + ctx->state == STATE_INTERFACE)) + { + const gchar *name; + const gchar *when; + const gchar *no_recurse; + const gchar *detailed; + const gchar *action; + const gchar *no_hooks; + const gchar *has_class_closure; + + name = find_attribute ("name", attribute_names, attribute_values); + when = find_attribute ("when", attribute_names, attribute_values); + no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values); + detailed = find_attribute ("detailed", attribute_names, attribute_values); + action = find_attribute ("action", attribute_names, attribute_values); + no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values); + has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeInterface *iface; + GIrNodeSignal *signal; + + signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL); + + ((GIrNode *)signal)->name = g_strdup (name); + + signal->run_first = FALSE; + signal->run_last = FALSE; + signal->run_cleanup = FALSE; + if (when == NULL || strcmp (when, "LAST") == 0) + signal->run_last = TRUE; + else if (strcmp (when, "FIRST") == 0) + signal->run_first = TRUE; + else + signal->run_cleanup = TRUE; + + if (no_recurse && strcmp (no_recurse, "1") == 0) + signal->no_recurse = TRUE; + else + signal->no_recurse = FALSE; + if (detailed && strcmp (detailed, "1") == 0) + signal->detailed = TRUE; + else + signal->detailed = FALSE; + if (action && strcmp (action, "1") == 0) + signal->action = TRUE; + else + signal->action = FALSE; + if (no_hooks && strcmp (no_hooks, "1") == 0) + signal->no_hooks = TRUE; + else + signal->no_hooks = FALSE; + if (has_class_closure && strcmp (has_class_closure, "1") == 0) + signal->has_class_closure = TRUE; + else + signal->has_class_closure = FALSE; + + iface = (GIrNodeInterface *)ctx->current_node; + iface->members = g_list_append (iface->members, signal); + + ctx->current_node = (GIrNode *)signal; + state_switch (ctx, STATE_FUNCTION); + } + + return TRUE; + } + return FALSE; +} + +static gboolean +start_vfunc (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + if (strcmp (element_name, "vfunc") == 0 && + (ctx->state == STATE_CLASS || + ctx->state == STATE_INTERFACE)) + { + const gchar *name; + const gchar *must_chain_up; + const gchar *override; + const gchar *is_class_closure; + const gchar *offset; + + name = find_attribute ("name", attribute_names, attribute_values); + must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values); + override = find_attribute ("override", attribute_names, attribute_values); + is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values); + offset = find_attribute ("offset", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeInterface *iface; + GIrNodeVFunc *vfunc; + + vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC); + + ((GIrNode *)vfunc)->name = g_strdup (name); + + if (must_chain_up && strcmp (must_chain_up, "1") == 0) + vfunc->must_chain_up = TRUE; + else + vfunc->must_chain_up = FALSE; + + if (override && strcmp (override, "always") == 0) + { + vfunc->must_be_implemented = TRUE; + vfunc->must_not_be_implemented = FALSE; + } + else if (override && strcmp (override, "never") == 0) + { + vfunc->must_be_implemented = FALSE; + vfunc->must_not_be_implemented = TRUE; + } + else + { + vfunc->must_be_implemented = FALSE; + vfunc->must_not_be_implemented = FALSE; + } + + if (is_class_closure && strcmp (is_class_closure, "1") == 0) + vfunc->is_class_closure = TRUE; + else + vfunc->is_class_closure = FALSE; + + if (offset) + vfunc->offset = atoi (offset); + else + vfunc->offset = 0; + + iface = (GIrNodeInterface *)ctx->current_node; + iface->members = g_list_append (iface->members, vfunc); + + ctx->current_node = (GIrNode *)vfunc; + state_switch (ctx, STATE_FUNCTION); + } + + return TRUE; + } + return FALSE; +} + + +static gboolean +start_struct (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + if (strcmp (element_name, "record") == 0 && + ctx->state == STATE_NAMESPACE) + { + const gchar *name; + const gchar *deprecated; + + name = find_attribute ("name", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeStruct *struct_; + + struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT); + + ((GIrNode *)struct_)->name = g_strdup (name); + if (deprecated && strcmp (deprecated, "1") == 0) + struct_->deprecated = TRUE; + else + struct_->deprecated = FALSE; + + ctx->current_node = (GIrNode *)struct_; + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, struct_); + + state_switch (ctx, STATE_STRUCT); + } + return TRUE; + } + return FALSE; +} + + +static gboolean +start_union (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + if (strcmp (element_name, "union") == 0 && + ctx->state == STATE_NAMESPACE) + { + const gchar *name; + const gchar *deprecated; + const gchar *typename; + const gchar *typeinit; + + name = find_attribute ("name", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeUnion *union_; + + union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION); + + ((GIrNode *)union_)->name = g_strdup (name); + union_->gtype_name = g_strdup (typename); + union_->gtype_init = g_strdup (typeinit); + if (deprecated && strcmp (deprecated, "1") == 0) + union_->deprecated = TRUE; + else + union_->deprecated = FALSE; + + ctx->current_node = (GIrNode *)union_; + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, union_); + + state_switch (ctx, STATE_UNION); + } + return TRUE; + } + return FALSE; +} + +static gboolean +start_discriminator (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + if (strcmp (element_name, "discriminator") == 0 && + ctx->state == STATE_UNION) + { + const gchar *type; + const gchar *offset; + + type = find_attribute ("type", attribute_names, attribute_values); + offset = find_attribute ("offset", attribute_names, attribute_values); + if (type == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "type"); + else if (offset == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "offset"); + { + ((GIrNodeUnion *)ctx->current_node)->discriminator_type + = parse_type (type); + ((GIrNodeUnion *)ctx->current_node)->discriminator_offset + = atoi (offset); + } + + return TRUE; + } + + return FALSE; +} + +extern GLogLevelFlags logged_levels; + +static void +start_element_handler (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + ParseContext *ctx = user_data; + gint line_number, char_number; + + if (logged_levels & G_LOG_LEVEL_DEBUG) + { + GString *tags = g_string_new (""); + int i; + for (i = 0; attribute_names[i]; i++) + g_string_append_printf (tags, "%s=\"%s\" ", + attribute_names[i], + attribute_values[i]); + + if (i) + { + g_string_insert_c (tags, 0, ' '); + g_string_truncate (tags, tags->len - 1); + } + g_debug ("<%s%s>", element_name, tags->str); + g_string_free (tags, TRUE); + } + + switch (element_name[0]) + { + case 'b': + if (start_enum (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + break; + case 'c': + if (start_function (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + else if (start_constant (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + else if (start_class (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + else if (strcmp (element_name, "class") == 0 && + ctx->state == STATE_REQUIRES) + { + const gchar *name; + + name = find_attribute ("name", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeInterface *iface; + + iface = (GIrNodeInterface *)ctx->current_node; + iface ->prerequisites = g_list_append (iface->prerequisites, g_strdup (name)); + } + + goto out; + } + break; + + case 'd': + if (start_discriminator (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + break; + + case 'e': + if (start_enum (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + else if (start_errordomain (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + break; + + case 'f': + if (start_function (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + else if (start_field (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + break; + + case 'g': + if (start_glib_boxed (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + else if (start_glib_signal (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + else if (start_glib_boxed (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + break; + + case 'i': + if (start_interface (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + if (strcmp (element_name, "implements") == 0 && + ctx->state == STATE_CLASS) + { + state_switch (ctx, STATE_IMPLEMENTS); + + goto out; + } + else if (strcmp (element_name, "interface") == 0 && + ctx->state == STATE_IMPLEMENTS) + { + const gchar *name; + + name = find_attribute ("name", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeInterface *iface; + + iface = (GIrNodeInterface *)ctx->current_node; + iface ->interfaces = g_list_append (iface->interfaces, g_strdup (name)); + } + + goto out; + } + else if (strcmp (element_name, "interface") == 0 && + ctx->state == STATE_REQUIRES) + { + const gchar *name; + + name = find_attribute ("name", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeInterface *iface; + + iface = (GIrNodeInterface *)ctx->current_node; + iface ->prerequisites = g_list_append (iface->prerequisites, g_strdup (name)); + } + + goto out; + } + break; + + case 'm': + if (start_function (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + else if (start_member (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + break; + + case 'n': + if (strcmp (element_name, "namespace") == 0 && ctx->state == STATE_REPOSITORY) + { + const gchar *name, *shared_library; + + name = find_attribute ("name", attribute_names, attribute_values); + shared_library = find_attribute ("shared-library", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + ctx->current_module = g_ir_module_new (name, shared_library); + ctx->modules = g_list_append (ctx->modules, ctx->current_module); + + state_switch (ctx, STATE_NAMESPACE); + } + + goto out; + } + break; + + case 'p': + if (start_property (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + else if (strcmp (element_name, "parameters") == 0 && + ctx->state == STATE_FUNCTION) + { + state_switch (ctx, STATE_FUNCTION_PARAMETERS); + + goto out; + } + else if (start_parameter (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + + break; + + case 'r': + if (strcmp (element_name, "repository") == 0 && ctx->state == STATE_START) + { + const gchar *version; + + version = find_attribute ("version", attribute_names, attribute_values); + + if (version == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "version"); + else if (strcmp (version, "1.0") != 0) + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Unsupported version '%s'", + version); + else + state_switch (ctx, STATE_REPOSITORY); + + goto out; + } + else if (start_return_value (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + else if (strcmp (element_name, "requires") == 0 && + ctx->state == STATE_INTERFACE) + { + state_switch (ctx, STATE_REQUIRES); + + goto out; + } + else if (start_struct (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + break; + + case 'u': + if (start_union (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + break; + + case 't': + if (start_type (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + break; + + case 'v': + if (start_vfunc (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; + break; + } + + g_markup_parse_context_get_position (context, &line_number, &char_number); + + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Unexpected start tag '%s' on line %d char %d", + element_name, + line_number, char_number); + + out: ; + if (*error) + { + g_markup_parse_context_get_position (context, &line_number, &char_number); + + fprintf (stderr, "Error at line %d, character %d: %s\n", line_number, char_number, (*error)->message); + backtrace_stderr (); + } +} + +static gboolean +require_one_of_end_elements (GMarkupParseContext *context, + const char *actual_name, + GError **error, + ...) +{ + va_list args; + int line_number, char_number; + const char *expected; + gboolean matched = FALSE; + + va_start (args, error); + + while ((expected = va_arg (args, const char*)) != NULL) + { + if (strcmp (expected, actual_name) == 0) + { + matched = TRUE; + break; + } + } + + va_end (args); + + if (matched) + return TRUE; + + g_markup_parse_context_get_position (context, &line_number, &char_number); + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Unexpected end tag '%s' on line %d char %d", + actual_name, + line_number, char_number); + backtrace_stderr(); + return FALSE; +} + +static gboolean +require_end_element (GMarkupParseContext *context, + const char *expected_name, + const char *actual_name, + GError **error) +{ + return require_one_of_end_elements (context, actual_name, error, expected_name, NULL); +} + +static void +end_element_handler (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + ParseContext *ctx = user_data; + + g_debug ("", element_name); + + switch (ctx->state) + { + case STATE_START: + case STATE_END: + /* no need to GError here, GMarkup already catches this */ + break; + + case STATE_REPOSITORY: + state_switch (ctx, STATE_END); + break; + + case STATE_NAMESPACE: + if (require_end_element (context, "namespace", element_name, error)) + { + ctx->current_module = NULL; + state_switch (ctx, STATE_REPOSITORY); + } + break; + + case STATE_FUNCTION_RETURN: + if (strcmp ("type", element_name) == 0) + break; + if (require_end_element (context, "return-value", element_name, error)) + { + state_switch (ctx, STATE_FUNCTION); + } + break; + + case STATE_FUNCTION_PARAMETERS: + if (require_end_element (context, "parameters", element_name, error)) + { + state_switch (ctx, STATE_FUNCTION); + } + break; + + case STATE_FUNCTION_PARAMETER: + if (strcmp ("type", element_name) == 0) + break; + if (require_end_element (context, "parameter", element_name, error)) + { + state_switch (ctx, STATE_FUNCTION_PARAMETERS); + } + break; + + case STATE_FUNCTION: + if (ctx->current_node == g_list_last (ctx->current_module->entries)->data) + { + ctx->current_node = NULL; + state_switch (ctx, STATE_NAMESPACE); + } + else + { + ctx->current_node = g_list_last (ctx->current_module->entries)->data; + if (ctx->current_node->type == G_IR_NODE_INTERFACE) + state_switch (ctx, STATE_INTERFACE); + else if (ctx->current_node->type == G_IR_NODE_OBJECT) + state_switch (ctx, STATE_CLASS); + else if (ctx->current_node->type == G_IR_NODE_BOXED) + state_switch (ctx, STATE_BOXED); + else if (ctx->current_node->type == G_IR_NODE_STRUCT) + state_switch (ctx, STATE_STRUCT); + else if (ctx->current_node->type == G_IR_NODE_UNION) + state_switch (ctx, STATE_UNION); + else + { + int line_number, char_number; + g_markup_parse_context_get_position (context, &line_number, &char_number); + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Unexpected end tag '%s' on line %d char %d", + element_name, + line_number, char_number); + } + } + break; + + case STATE_CLASS_FIELD: + if (strcmp ("type", element_name) == 0) + break; + if (require_end_element (context, "field", element_name, error)) + { + state_switch (ctx, STATE_CLASS); + } + break; + + case STATE_CLASS_PROPERTY: + if (strcmp ("type", element_name) == 0) + break; + if (require_end_element (context, "property", element_name, error)) + { + state_switch (ctx, STATE_CLASS); + } + break; + + case STATE_CLASS: + if (require_end_element (context, "class", element_name, error)) + { + ctx->current_node = NULL; + state_switch (ctx, STATE_NAMESPACE); + } + break; + + case STATE_ERRORDOMAIN: + if (require_end_element (context, "errordomain", element_name, error)) + { + ctx->current_node = NULL; + state_switch (ctx, STATE_NAMESPACE); + } + break; + + case STATE_INTERFACE_PROPERTY: + if (require_end_element (context, "property", element_name, error)) + { + state_switch (ctx, STATE_INTERFACE); + } + break; + + case STATE_INTERFACE_FIELD: + if (strcmp ("type", element_name) == 0) + break; + if (require_end_element (context, "field", element_name, error)) + { + state_switch (ctx, STATE_INTERFACE); + } + break; + + case STATE_INTERFACE: + if (require_end_element (context, "interface", element_name, error)) + { + ctx->current_node = NULL; + state_switch (ctx, STATE_NAMESPACE); + } + break; + + case STATE_ENUM: + if (strcmp ("member", element_name) == 0) + break; + else if (require_one_of_end_elements (context, element_name, error, "enumeration", "bitfield", NULL)) + { + ctx->current_node = NULL; + state_switch (ctx, STATE_NAMESPACE); + } + break; + + case STATE_BOXED: + if (require_end_element (context, "glib:boxed", element_name, error)) + { + ctx->current_node = NULL; + state_switch (ctx, STATE_NAMESPACE); + } + break; + + case STATE_BOXED_FIELD: + if (strcmp ("type", element_name) == 0) + break; + if (require_end_element (context, "field", element_name, error)) + { + state_switch (ctx, STATE_BOXED); + } + break; + + case STATE_STRUCT_FIELD: + if (strcmp ("type", element_name) == 0) + break; + if (require_end_element (context, "field", element_name, error)) + { + state_switch (ctx, STATE_STRUCT); + } + break; + + case STATE_STRUCT: + if (require_end_element (context, "record", element_name, error)) + { + ctx->current_node = NULL; + state_switch (ctx, STATE_NAMESPACE); + } + break; + case STATE_UNION: + if (require_end_element (context, "union", element_name, error)) + { + ctx->current_node = NULL; + state_switch (ctx, STATE_NAMESPACE); + } + break; + case STATE_IMPLEMENTS: + if (strcmp ("interface", element_name) == 0) + break; + if (require_end_element (context, "implements", element_name, error)) + state_switch (ctx, STATE_CLASS); + break; + case STATE_REQUIRES: + if (require_end_element (context, "requires", element_name, error)) + state_switch (ctx, STATE_INTERFACE); + break; + case STATE_CONSTANT: + if (require_end_element (context, "constant", element_name, error)) + { + ctx->current_node = NULL; + state_switch (ctx, STATE_NAMESPACE); + } + break; + default: + g_error ("Unhandled state %d in end_element_handler\n", ctx->state); + } +} + +static void +text_handler (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error) +{ + /* FIXME warn about non-whitespace text */ +} + +static void +cleanup (GMarkupParseContext *context, + GError *error, + gpointer user_data) +{ + ParseContext *ctx = user_data; + GList *m; + int line_number, char_number; + + for (m = ctx->modules; m; m = m->next) + g_ir_module_free (m->data); + g_list_free (ctx->modules); + ctx->modules = NULL; + + ctx->current_module = NULL; +} + +static GMarkupParser parser = +{ + start_element_handler, + end_element_handler, + text_handler, + NULL, + cleanup +}; + +GList * +g_ir_parse_string (const gchar *buffer, + gssize length, + GError **error) +{ + ParseContext ctx = { 0 }; + GMarkupParseContext *context; + + ctx.state = STATE_START; + + context = g_markup_parse_context_new (&parser, 0, &ctx, NULL); + if (!g_markup_parse_context_parse (context, buffer, length, error)) + goto out; + + if (!g_markup_parse_context_end_parse (context, error)) + goto out; + + out: + + g_markup_parse_context_free (context); + + return ctx.modules; +} + +GList * +g_ir_parse_file (const gchar *filename, + GError **error) +{ + gchar *buffer; + gsize length; + GList *modules; + + g_debug ("[parsing] filename %s", filename); + + if (!g_file_get_contents (filename, &buffer, &length, error)) + return NULL; + + modules = g_ir_parse_string (buffer, length, error); + + g_free (buffer); + + return modules; +} + + diff --git a/girparser.h b/girparser.h new file mode 100644 index 000000000..ed9e6cebf --- /dev/null +++ b/girparser.h @@ -0,0 +1,38 @@ +/* GObject introspection: A parser for the XML GIR format + * + * Copyright (C) 2005 Matthias Clasen + * + * 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_GIR_PARSER_H__ +#define __G_GIR_PARSER_H__ + +#include + +G_BEGIN_DECLS + + +GList *g_ir_parse_string (const gchar *buffer, + gssize length, + GError **error); +GList *g_ir_parse_file (const gchar *filename, + GError **error); + + +G_END_DECLS + +#endif /* __G_GIR_PARSER_H__ */ diff --git a/girwriter.c b/girwriter.c new file mode 100644 index 000000000..d4d550631 --- /dev/null +++ b/girwriter.c @@ -0,0 +1,532 @@ +/* GObject introspection: gen-introspect + * + * Copyright (C) 2007 Jürg Billeter + * Copyright (C) 2007 Johan Dahlin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 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. + * + * Author: + * Jürg Billeter + */ + +#include +#include +#include "scanner.h" +#include "gidlnode.h" + +typedef struct { + int indent; + FILE *output; +} GIdlWriter; + +static void node_generate (GIdlWriter * writer, GIdlNode * node); + +static void +g_writer_write_inline (GIdlWriter * writer, const char *s) +{ + fprintf (writer->output, "%s", s); +} + +static void +g_writer_write (GIdlWriter * writer, const char *s) +{ + int i; + for (i = 0; i < writer->indent; i++) + { + fprintf (writer->output, "\t"); + } + + g_writer_write_inline (writer, s); +} + +static void +g_writer_write_indent (GIdlWriter * writer, const char *s) +{ + g_writer_write (writer, s); + writer->indent++; +} + +static void +g_writer_write_unindent (GIdlWriter * writer, const char *s) +{ + writer->indent--; + g_writer_write (writer, s); +} + +static void +field_generate (GIdlWriter * writer, GIdlNodeField * node) +{ + char *markup = + g_markup_printf_escaped ("\n", + node->node.name, node->type->unparsed); + g_writer_write (writer, markup); + g_free (markup); +} + +static void +value_generate (GIdlWriter * writer, GIdlNodeValue * node) +{ + char *markup = + g_markup_printf_escaped ("\n", + node->node.name, node->value); + g_writer_write (writer, markup); + g_free (markup); +} + +static void +constant_generate (GIdlWriter * writer, GIdlNodeConstant * node) +{ + char *markup = + g_markup_printf_escaped + ("\n", node->node.name, + node->type->unparsed, node->value); + g_writer_write (writer, markup); + g_free (markup); +} + +static void +property_generate (GIdlWriter * writer, GIdlNodeProperty * node) +{ + char *markup = + g_markup_printf_escaped ("\n", + node->node.name, + node->type->unparsed, + node->readable ? "1" : "0", + node->writable ? "1" : "0", + node->construct ? "1" : "0", + node->construct_only ? "1" : "0"); + g_writer_write (writer, markup); + g_free (markup); +} + +static void +function_generate (GIdlWriter * writer, GIdlNodeFunction * node) +{ + const char *tag_name; + GString *markup_s; + gchar *markup; + + if (node->node.type == G_IR_NODE_CALLBACK) + tag_name = "callback"; + else if (node->is_constructor) + tag_name = "constructor"; + else if (node->is_method) + tag_name = "method"; + else + tag_name = "function"; + + markup_s = g_string_new ("<"); + g_string_append_printf (markup_s, + "%s name=\"%s\"", + tag_name, node->node.name); + + if (node->node.type != G_IR_NODE_CALLBACK) + g_string_append_printf (markup_s, + g_markup_printf_escaped (" symbol=\"%s\"", node->symbol)); + + if (node->deprecated) + g_string_append_printf (markup_s, " deprecated=\"1\""); + + g_string_append (markup_s, ">\n"); + + g_writer_write_indent (writer, markup_s->str); + g_string_free (markup_s, TRUE); + + markup_s = + g_string_new (g_markup_printf_escaped ("result->type->unparsed)); + + if (node->result->transfer) + g_string_append (markup_s, g_markup_printf_escaped (" transfer=\"full\"/>\n")); + else + g_string_append (markup_s, "/>\n"); + + g_writer_write (writer, markup_s->str); + g_string_free (markup_s, TRUE); + + if (node->parameters != NULL) + { + GList *l; + g_writer_write_indent (writer, "\n"); + for (l = node->parameters; l != NULL; l = l->next) + { + GIdlNodeParam *param = l->data; + const gchar *direction = g_idl_node_param_direction_string (param); + + markup_s = g_string_new ("node.name); + + g_string_append (markup_s, + g_markup_printf_escaped (" type=\"%s\"", + param->type->unparsed)); + + if (param->transfer) + g_string_append (markup_s, + g_markup_printf_escaped (" transfer=\"full\"")); + + if (param->null_ok) + g_string_append (markup_s, + g_markup_printf_escaped (" null-ok=\"1\"")); + + if (strcmp (direction, "in") != 0) + g_string_append (markup_s, + g_markup_printf_escaped (" direction=\"%s\"", + direction)); + + g_string_append (markup_s, "/>\n"); + + g_writer_write (writer, markup_s->str); + g_string_free (markup_s, TRUE); + } + g_writer_write_unindent (writer, "\n"); + } + markup = g_strdup_printf ("\n", tag_name); + g_writer_write_unindent (writer, markup); + g_free (markup); +} + +static void +vfunc_generate (GIdlWriter * writer, GIdlNodeVFunc * node) +{ + char *markup = + g_markup_printf_escaped ("\n", node->node.name); + g_writer_write_indent (writer, markup); + g_free (markup); + markup = + g_markup_printf_escaped ("\n", + node->result->type->unparsed); + g_writer_write (writer, markup); + g_free (markup); + if (node->parameters != NULL) + { + GList *l; + g_writer_write_indent (writer, "\n"); + for (l = node->parameters; l != NULL; l = l->next) + { + GIdlNodeParam *param = l->data; + markup = + g_markup_printf_escaped ("\n", + param->node.name, param->type->unparsed); + g_writer_write (writer, markup); + g_free (markup); + } + g_writer_write_unindent (writer, "\n"); + } + g_writer_write_unindent (writer, "\n"); +} + +static void +signal_generate (GIdlWriter * writer, GIdlNodeSignal * node) +{ + char *markup; + const char *when = "LAST"; + if (node->run_first) + { + when = "FIRST"; + } + else if (node->run_cleanup) + { + when = "CLEANUP"; + } + markup = + g_markup_printf_escaped ("\n", + node->node.name, when); + g_writer_write_indent (writer, markup); + g_free (markup); + markup = + g_markup_printf_escaped ("\n", + node->result->type->unparsed); + g_writer_write (writer, markup); + g_free (markup); + if (node->parameters != NULL) + { + GList *l; + g_writer_write_indent (writer, "\n"); + for (l = node->parameters; l != NULL; l = l->next) + { + GIdlNodeParam *param = l->data; + markup = + g_markup_printf_escaped ("\n", + param->node.name, param->type->unparsed); + g_writer_write (writer, markup); + g_free (markup); + } + g_writer_write_unindent (writer, "\n"); + } + g_writer_write_unindent (writer, "\n"); +} + +static void +interface_generate (GIdlWriter * writer, GIdlNodeInterface * node) +{ + GList *l; + char *markup; + if (node->node.type == G_IR_NODE_OBJECT) + { + markup = + g_markup_printf_escaped ("\n", + node->node.name, + node->parent, + node->gtype_name, + node->gtype_init); + } + else if (node->node.type == G_IR_NODE_INTERFACE) + { + markup = + g_markup_printf_escaped + ("\n", + node->node.name, node->gtype_name, node->gtype_init); + } + + g_writer_write_indent (writer, markup); + g_free (markup); + if (node->node.type == G_IR_NODE_OBJECT && node->interfaces != NULL) + { + GList *l; + g_writer_write_indent (writer, "\n"); + for (l = node->interfaces; l != NULL; l = l->next) + { + markup = + g_markup_printf_escaped ("\n", + (char *) l->data); + g_writer_write (writer, markup); + g_free (markup); + } + g_writer_write_unindent (writer, "\n"); + } + else if (node->node.type == G_IR_NODE_INTERFACE + && node->prerequisites != NULL) + { + GList *l; + g_writer_write_indent (writer, "\n"); + for (l = node->prerequisites; l != NULL; l = l->next) + { + markup = + g_markup_printf_escaped ("\n", + (char *) l->data); + g_writer_write (writer, markup); + g_free (markup); + } + g_writer_write_unindent (writer, "\n"); + } + + for (l = node->members; l != NULL; l = l->next) + { + node_generate (writer, l->data); + } + + if (node->node.type == G_IR_NODE_OBJECT) + { + g_writer_write_unindent (writer, "\n"); + } + else if (node->node.type == G_IR_NODE_INTERFACE) + { + g_writer_write_unindent (writer, "\n"); + } +} + +static void +struct_generate (GIdlWriter * writer, GIdlNodeStruct * node) +{ + GList *l; + char *markup = + g_markup_printf_escaped ("\n", node->node.name); + g_writer_write_indent (writer, markup); + g_free (markup); + for (l = node->members; l != NULL; l = l->next) + { + node_generate (writer, l->data); + } + g_writer_write_unindent (writer, "\n"); +} + +static void +union_generate (GIdlWriter * writer, GIdlNodeUnion * node) +{ + GList *l; + char *markup = + g_markup_printf_escaped ("\n", node->node.name); + g_writer_write_indent (writer, markup); + g_free (markup); + for (l = node->members; l != NULL; l = l->next) + { + node_generate (writer, l->data); + } + g_writer_write_unindent (writer, "\n"); +} + +static void +boxed_generate (GIdlWriter * writer, GIdlNodeBoxed * node) +{ + GList *l; + char *markup = + g_markup_printf_escaped + ("\n", + node->node.name, node->gtype_name, node->gtype_init); + g_writer_write_indent (writer, markup); + g_free (markup); + for (l = node->members; l != NULL; l = l->next) + { + node_generate (writer, l->data); + } + g_writer_write_unindent (writer, "\n"); +} + +static void +enum_generate (GIdlWriter * writer, GIdlNodeEnum * node) +{ + GList *l; + GString *markup_s; + char *markup; + const char *tag_name = NULL; + + if (node->node.type == G_IR_NODE_ENUM) + { + tag_name = "enum"; + } + else if (node->node.type == G_IR_NODE_FLAGS) + { + tag_name = "flags"; + } + + markup_s = g_string_new ("<"); + g_string_append_printf (markup_s, + "%s name=\"%s\"", + tag_name, node->node.name); + + if (node->gtype_name != NULL) + g_string_append_printf (markup_s, + g_markup_printf_escaped (" type-name=\"%s\"", node->gtype_name)); + + if (node->gtype_init != NULL) + g_string_append_printf (markup_s, + g_markup_printf_escaped (" get-type=\"%s\"", node->gtype_init)); + + if (node->deprecated) + g_string_append_printf (markup_s, " deprecated=\"1\""); + + g_string_append (markup_s, ">\n"); + + g_writer_write_indent (writer, markup_s->str); + g_string_free (markup_s, TRUE); + + for (l = node->values; l != NULL; l = l->next) + { + node_generate (writer, l->data); + } + + markup = g_strdup_printf ("\n", tag_name); + g_writer_write_unindent (writer, markup); + g_free (markup); +} + +static void +node_generate (GIdlWriter * writer, GIdlNode * node) +{ + switch (node->type) + { + case G_IR_NODE_FUNCTION: + case G_IR_NODE_CALLBACK: + function_generate (writer, (GIdlNodeFunction *) node); + break; + case G_IR_NODE_VFUNC: + vfunc_generate (writer, (GIdlNodeVFunc *) node); + break; + case G_IR_NODE_OBJECT: + case G_IR_NODE_INTERFACE: + interface_generate (writer, (GIdlNodeInterface *) node); + break; + case G_IR_NODE_STRUCT: + struct_generate (writer, (GIdlNodeStruct *) node); + break; + case G_IR_NODE_UNION: + union_generate (writer, (GIdlNodeUnion *) node); + break; + case G_IR_NODE_BOXED: + boxed_generate (writer, (GIdlNodeBoxed *) node); + break; + case G_IR_NODE_ENUM: + case G_IR_NODE_FLAGS: + enum_generate (writer, (GIdlNodeEnum *) node); + break; + case G_IR_NODE_PROPERTY: + property_generate (writer, (GIdlNodeProperty *) node); + break; + case G_IR_NODE_FIELD: + field_generate (writer, (GIdlNodeField *) node); + break; + case G_IR_NODE_SIGNAL: + signal_generate (writer, (GIdlNodeSignal *) node); + break; + case G_IR_NODE_VALUE: + value_generate (writer, (GIdlNodeValue *) node); + break; + case G_IR_NODE_CONSTANT: + constant_generate (writer, (GIdlNodeConstant *) node); + break; + default: + g_assert_not_reached (); + } +} + +static void +g_writer_write_module (GIdlWriter * writer, GIdlModule * module) +{ + GList *l; + char *markup = + g_markup_printf_escaped ("\n", module->name); + g_writer_write_indent (writer, markup); + g_free (markup); + for (l = module->entries; l != NULL; l = l->next) + { + node_generate (writer, l->data); + } + g_writer_write_unindent (writer, "\n"); +} + +void +g_idl_writer_save_file (GIdlModule *module, + const gchar *filename) +{ + GIdlWriter *writer; + + writer = g_new0 (GIdlWriter, 1); + + if (!filename) + writer->output = stdout; + else + writer->output = fopen (filename, "w"); + + g_writer_write (writer, "\n"); + g_writer_write_indent (writer, ""); + g_writer_write_module (writer, module); + g_writer_write_unindent (writer, "\n"); + + if (filename) + fclose (writer->output); +} diff --git a/girwriter.h b/girwriter.h new file mode 100644 index 000000000..5d41a0c6a --- /dev/null +++ b/girwriter.h @@ -0,0 +1,26 @@ +/* GObject introspection: IDL writer + * + * Copyright (C) 2007 Johan Dahlin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __G_IDL_WRITER_H__ +#define __G_IDL_WRITER_H__ + +void g_idl_writer_save_file (GIdlModule *module, const gchar *filename); + +#endif /* __G_IDL_WRITER_H__ */ From 33455bc3efd85916841049a2ce9a4b7f8240c30f Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 9 Aug 2008 12:55:32 +0000 Subject: [PATCH 023/692] Rename metadata to typelib in variable names, comments and apis. 2008-08-09 Johan Dahlin * *.[ch]: Rename metadata to typelib in variable names, comments and apis. svn path=/trunk/; revision=339 --- ginfo.c | 414 +++++++++++++++++++++++------------------------ ginvoke.c | 6 +- girepository.c | 152 +++++++++--------- girepository.h | 20 +-- girmodule.c | 12 +- girmodule.h | 2 +- girnode.c | 194 +++++++++++----------- girnode.h | 28 ++-- gtypelib.c | 424 ++++++++++++++++++++++++------------------------- gtypelib.h | 12 +- 10 files changed, 632 insertions(+), 632 deletions(-) diff --git a/ginfo.c b/ginfo.c index c54b39283..492d660ea 100644 --- a/ginfo.c +++ b/ginfo.c @@ -32,7 +32,7 @@ struct _GIBaseInfo gint ref_count; GIBaseInfo *container; - GTypelib *metadata; + GTypelib *typelib; guint32 offset; }; @@ -136,7 +136,7 @@ struct _GIUnionInfo GIBaseInfo * g_info_new (GIInfoType type, GIBaseInfo *container, - GTypelib *metadata, + GTypelib *typelib, guint32 offset) { GIBaseInfo *info; @@ -146,7 +146,7 @@ g_info_new (GIInfoType type, info->ref_count = 1; info->type = type; - info->metadata = metadata; + info->typelib = typelib; info->offset = offset; if (container) @@ -156,18 +156,18 @@ g_info_new (GIInfoType type, } static GIBaseInfo * -g_info_from_entry (GTypelib *metadata, +g_info_from_entry (GTypelib *typelib, guint16 index) { GIBaseInfo *result; - DirEntry *entry = g_typelib_get_dir_entry (metadata, index); + DirEntry *entry = g_typelib_get_dir_entry (typelib, index); if (entry->local) - result = g_info_new (entry->blob_type, NULL, metadata, entry->offset); + result = g_info_new (entry->blob_type, NULL, typelib, entry->offset); else { - const gchar *namespace = g_typelib_get_string (metadata, entry->offset); - const gchar *name = g_typelib_get_string (metadata, entry->name); + const gchar *namespace = g_typelib_get_string (typelib, entry->offset); + const gchar *name = g_typelib_get_string (typelib, entry->name); GIRepository *repository = g_irepository_get_default (); @@ -238,57 +238,57 @@ g_base_info_get_name (GIBaseInfo *info) case GI_INFO_TYPE_ERROR_DOMAIN: case GI_INFO_TYPE_UNION: { - CommonBlob *blob = (CommonBlob *)&info->metadata->data[info->offset]; + CommonBlob *blob = (CommonBlob *)&info->typelib->data[info->offset]; - return g_typelib_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->typelib, blob->name); } break; case GI_INFO_TYPE_VALUE: { - ValueBlob *blob = (ValueBlob *)&info->metadata->data[info->offset]; + ValueBlob *blob = (ValueBlob *)&info->typelib->data[info->offset]; - return g_typelib_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->typelib, blob->name); } break; case GI_INFO_TYPE_SIGNAL: { - SignalBlob *blob = (SignalBlob *)&info->metadata->data[info->offset]; + SignalBlob *blob = (SignalBlob *)&info->typelib->data[info->offset]; - return g_typelib_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->typelib, blob->name); } break; case GI_INFO_TYPE_PROPERTY: { - PropertyBlob *blob = (PropertyBlob *)&info->metadata->data[info->offset]; + PropertyBlob *blob = (PropertyBlob *)&info->typelib->data[info->offset]; - return g_typelib_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->typelib, blob->name); } break; case GI_INFO_TYPE_VFUNC: { - VFuncBlob *blob = (VFuncBlob *)&info->metadata->data[info->offset]; + VFuncBlob *blob = (VFuncBlob *)&info->typelib->data[info->offset]; - return g_typelib_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->typelib, blob->name); } break; case GI_INFO_TYPE_FIELD: { - FieldBlob *blob = (FieldBlob *)&info->metadata->data[info->offset]; + FieldBlob *blob = (FieldBlob *)&info->typelib->data[info->offset]; - return g_typelib_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->typelib, blob->name); } break; case GI_INFO_TYPE_ARG: { - ArgBlob *blob = (ArgBlob *)&info->metadata->data[info->offset]; + ArgBlob *blob = (ArgBlob *)&info->typelib->data[info->offset]; - return g_typelib_get_string (info->metadata, blob->name); + return g_typelib_get_string (info->typelib, blob->name); } break; @@ -311,7 +311,7 @@ g_base_info_get_name (GIBaseInfo *info) const gchar * g_base_info_get_namespace (GIBaseInfo *info) { - Header *header = (Header *)info->metadata->data; + Header *header = (Header *)info->typelib->data; if (info->type == GI_INFO_TYPE_UNRESOLVED) { @@ -320,7 +320,7 @@ g_base_info_get_namespace (GIBaseInfo *info) return unresolved->namespace; } - return g_typelib_get_string (info->metadata, header->namespace); + return g_typelib_get_string (info->typelib, header->namespace); } gboolean @@ -339,7 +339,7 @@ g_base_info_is_deprecated (GIBaseInfo *info) case GI_INFO_TYPE_CONSTANT: case GI_INFO_TYPE_ERROR_DOMAIN: { - CommonBlob *blob = (CommonBlob *)&info->metadata->data[info->offset]; + CommonBlob *blob = (CommonBlob *)&info->typelib->data[info->offset]; return blob->deprecated; } @@ -347,7 +347,7 @@ g_base_info_is_deprecated (GIBaseInfo *info) case GI_INFO_TYPE_VALUE: { - ValueBlob *blob = (ValueBlob *)&info->metadata->data[info->offset]; + ValueBlob *blob = (ValueBlob *)&info->typelib->data[info->offset]; return blob->deprecated; } @@ -355,7 +355,7 @@ g_base_info_is_deprecated (GIBaseInfo *info) case GI_INFO_TYPE_SIGNAL: { - SignalBlob *blob = (SignalBlob *)&info->metadata->data[info->offset]; + SignalBlob *blob = (SignalBlob *)&info->typelib->data[info->offset]; return blob->deprecated; } @@ -363,7 +363,7 @@ g_base_info_is_deprecated (GIBaseInfo *info) case GI_INFO_TYPE_PROPERTY: { - PropertyBlob *blob = (PropertyBlob *)&info->metadata->data[info->offset]; + PropertyBlob *blob = (PropertyBlob *)&info->typelib->data[info->offset]; return blob->deprecated; } @@ -401,14 +401,14 @@ g_base_info_get_annotation (GIBaseInfo *info, const gchar *name) { GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; + Header *header = (Header *)base->typelib->data; AnnotationBlob blob, *first, *after, *res, *next; const gchar *rname; blob.offset = base->offset; - first = (AnnotationBlob *) &base->metadata->data[header->annotations]; - after = (AnnotationBlob *) &base->metadata->data[header->annotations + + first = (AnnotationBlob *) &base->typelib->data[header->annotations]; + after = (AnnotationBlob *) &base->typelib->data[header->annotations + header->n_annotations * header->annotation_blob_size]; res = bsearch (&blob, first, header->n_annotations, @@ -430,9 +430,9 @@ g_base_info_get_annotation (GIBaseInfo *info, { res = next; - rname = g_typelib_get_string (base->metadata, res->name); + rname = g_typelib_get_string (base->typelib, res->name); if (strcmp (name, rname) == 0) - return g_typelib_get_string (base->metadata, res->value); + return g_typelib_get_string (base->typelib, res->value); next = res += header->annotation_blob_size; } @@ -448,9 +448,9 @@ g_base_info_get_container (GIBaseInfo *info) } GTypelib * -g_base_info_get_metadata (GIBaseInfo *info) +g_base_info_get_typelib (GIBaseInfo *info) { - return info->metadata; + return info->typelib; } /* GIFunctionInfo functions */ @@ -458,9 +458,9 @@ const gchar * g_function_info_get_symbol (GIFunctionInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - FunctionBlob *blob = (FunctionBlob *)&base->metadata->data[base->offset]; + FunctionBlob *blob = (FunctionBlob *)&base->typelib->data[base->offset]; - return g_typelib_get_string (base->metadata, blob->symbol); + return g_typelib_get_string (base->typelib, blob->symbol); } GIFunctionInfoFlags @@ -468,7 +468,7 @@ g_function_info_get_flags (GIFunctionInfo *info) { GIFunctionInfoFlags flags; GIBaseInfo *base = (GIBaseInfo *)info; - FunctionBlob *blob = (FunctionBlob *)&base->metadata->data[base->offset]; + FunctionBlob *blob = (FunctionBlob *)&base->typelib->data[base->offset]; flags = 0; @@ -494,7 +494,7 @@ GIPropertyInfo * g_function_info_get_property (GIFunctionInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - FunctionBlob *blob = (FunctionBlob *)&base->metadata->data[base->offset]; + FunctionBlob *blob = (FunctionBlob *)&base->typelib->data[base->offset]; GIInterfaceInfo *container = (GIInterfaceInfo *)base->container; return g_interface_info_get_property (container, blob->index); @@ -504,7 +504,7 @@ GIVFuncInfo * g_function_info_get_vfunc (GIFunctionInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - FunctionBlob *blob = (FunctionBlob *)&base->metadata->data[base->offset]; + FunctionBlob *blob = (FunctionBlob *)&base->typelib->data[base->offset]; GIInterfaceInfo *container = (GIInterfaceInfo *)base->container; return g_interface_info_get_vfunc (container, blob->index); @@ -519,10 +519,10 @@ signature_offset (GICallableInfo *info) { case GI_INFO_TYPE_FUNCTION: case GI_INFO_TYPE_VFUNC: - return *(guint32 *)&info->base.metadata->data[info->base.offset + 12]; + return *(guint32 *)&info->base.typelib->data[info->base.offset + 12]; case GI_INFO_TYPE_CALLBACK: case GI_INFO_TYPE_SIGNAL: - return *(guint32 *)&info->base.metadata->data[info->base.offset + 8]; + return *(guint32 *)&info->base.typelib->data[info->base.offset + 8]; } return 0; @@ -530,12 +530,12 @@ signature_offset (GICallableInfo *info) GITypeInfo * g_type_info_new (GIBaseInfo *container, - GTypelib *metadata, + GTypelib *typelib, guint32 offset) { - SimpleTypeBlob *type = (SimpleTypeBlob *)&metadata->data[offset]; + SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset]; - return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, metadata, + return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, typelib, type->reserved == 0 ? offset : type->offset); } @@ -557,7 +557,7 @@ g_callable_info_get_return_type (GICallableInfo *info) offset = signature_offset (info); - return g_type_info_new (base, base->metadata, offset); + return g_type_info_new (base, base->typelib, offset); } /** @@ -572,7 +572,7 @@ gboolean g_callable_info_may_return_null (GICallableInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SignatureBlob *blob = (SignatureBlob *)&base->metadata->data[signature_offset (info)]; + SignatureBlob *blob = (SignatureBlob *)&base->typelib->data[signature_offset (info)]; return blob->may_return_null; } @@ -590,7 +590,7 @@ GITransfer g_callable_info_get_caller_owns (GICallableInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SignatureBlob *blob = (SignatureBlob *)&base->metadata->data[signature_offset (info)]; + SignatureBlob *blob = (SignatureBlob *)&base->typelib->data[signature_offset (info)]; if (blob->caller_owns_return_value) return GI_TRANSFER_EVERYTHING; @@ -616,7 +616,7 @@ g_callable_info_get_n_args (GICallableInfo *info) SignatureBlob *blob; offset = signature_offset (info); - blob = (SignatureBlob *)&base->metadata->data[offset]; + blob = (SignatureBlob *)&base->typelib->data[offset]; return blob->n_arguments; } @@ -627,19 +627,19 @@ g_callable_info_get_n_args (GICallableInfo *info) * * Get information about a particular argument of this callable. * - * Returns: A #GIArgInfo indexing the metadata on the given argument. + * Returns: A #GIArgInfo indexing the typelib on the given argument. */ GIArgInfo * g_callable_info_get_arg (GICallableInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; + Header *header = (Header *)base->typelib->data; gint offset; offset = signature_offset (info); - return (GIArgInfo *) g_info_new (GI_INFO_TYPE_ARG, base, base->metadata, + return (GIArgInfo *) g_info_new (GI_INFO_TYPE_ARG, base, base->typelib, offset + header->signature_blob_size + n * header->arg_blob_size); } @@ -648,7 +648,7 @@ GIDirection g_arg_info_get_direction (GIArgInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ArgBlob *blob = (ArgBlob *)&base->metadata->data[base->offset]; + ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; if (blob->in && blob->out) return GI_DIRECTION_INOUT; @@ -662,7 +662,7 @@ gboolean g_arg_info_is_return_value (GIArgInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ArgBlob *blob = (ArgBlob *)&base->metadata->data[base->offset]; + ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; return blob->return_value; } @@ -671,7 +671,7 @@ gboolean g_arg_info_is_dipper (GIArgInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ArgBlob *blob = (ArgBlob *)&base->metadata->data[base->offset]; + ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; return blob->dipper; } @@ -680,7 +680,7 @@ gboolean g_arg_info_is_optional (GIArgInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ArgBlob *blob = (ArgBlob *)&base->metadata->data[base->offset]; + ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; return blob->optional; } @@ -689,7 +689,7 @@ gboolean g_arg_info_may_be_null (GIArgInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ArgBlob *blob = (ArgBlob *)&base->metadata->data[base->offset]; + ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; return blob->null_ok; } @@ -698,7 +698,7 @@ GITransfer g_arg_info_get_ownership_transfer (GIArgInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ArgBlob *blob = (ArgBlob *)&base->metadata->data[base->offset]; + ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; if (blob->transfer_ownership) return GI_TRANSFER_EVERYTHING; @@ -713,7 +713,7 @@ g_arg_info_get_type (GIArgInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - return g_type_info_new (base, base->metadata, base->offset + 8); + return g_type_info_new (base, base->typelib, base->offset + 8); } /* GITypeInfo functions */ @@ -721,13 +721,13 @@ gboolean g_type_info_is_pointer (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; if (type->reserved == 0) return type->pointer; else { - InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->metadata->data[base->offset]; + InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->typelib->data[base->offset]; return iface->pointer; } @@ -737,13 +737,13 @@ GITypeTag g_type_info_get_tag (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; if (type->reserved == 0) return type->tag; else { - InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->metadata->data[base->offset]; + InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->typelib->data[base->offset]; return iface->tag; } @@ -754,11 +754,11 @@ g_type_info_get_param_type (GITypeInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; if (type->reserved != 0) { - ParamTypeBlob *param = (ParamTypeBlob *)&base->metadata->data[base->offset]; + ParamTypeBlob *param = (ParamTypeBlob *)&base->typelib->data[base->offset]; switch (param->tag) { @@ -766,7 +766,7 @@ g_type_info_get_param_type (GITypeInfo *info, 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); + return g_type_info_new (base, base->typelib, base->offset + 4 + 4 * n); break; default: ; @@ -780,14 +780,14 @@ GIBaseInfo * g_type_info_get_interface (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; if (type->reserved != 0) { - InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->metadata->data[base->offset]; + InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->typelib->data[base->offset]; if (blob->tag == GI_TYPE_TAG_INTERFACE) - return g_info_from_entry (base->metadata, blob->interface); + return g_info_from_entry (base->typelib, blob->interface); } return NULL; @@ -797,11 +797,11 @@ gint g_type_info_get_array_length (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; if (type->reserved != 0) { - ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->metadata->data[base->offset]; + ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset]; if (blob->tag == GI_TYPE_TAG_ARRAY) { @@ -817,11 +817,11 @@ gboolean g_type_info_is_zero_terminated (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; if (type->reserved != 0) { - ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->metadata->data[base->offset]; + ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset]; if (blob->tag == GI_TYPE_TAG_ARRAY) return blob->zero_terminated; @@ -834,11 +834,11 @@ gint g_type_info_get_n_error_domains (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; if (type->reserved != 0) { - ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->metadata->data[base->offset]; + ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->typelib->data[base->offset]; if (blob->tag == GI_TYPE_TAG_ERROR) return blob->n_domains; @@ -852,14 +852,14 @@ g_type_info_get_error_domain (GITypeInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->metadata->data[base->offset]; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; if (type->reserved != 0) { - ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->metadata->data[base->offset]; + ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->typelib->data[base->offset]; if (blob->tag == GI_TYPE_TAG_ERROR) - return (GIErrorDomainInfo *) g_info_from_entry (base->metadata, + return (GIErrorDomainInfo *) g_info_from_entry (base->typelib, blob->domains[n]); } @@ -872,18 +872,18 @@ const gchar * g_error_domain_info_get_quark (GIErrorDomainInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset]; + ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->typelib->data[base->offset]; - return g_typelib_get_string (base->metadata, blob->get_quark); + return g_typelib_get_string (base->typelib, blob->get_quark); } GIInterfaceInfo * g_error_domain_info_get_codes (GIErrorDomainInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->metadata->data[base->offset]; + ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->typelib->data[base->offset]; - return (GIInterfaceInfo *) g_info_from_entry (base->metadata, blob->error_codes); + return (GIInterfaceInfo *) g_info_from_entry (base->typelib, blob->error_codes); } @@ -892,7 +892,7 @@ glong g_value_info_get_value (GIValueInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ValueBlob *blob = (ValueBlob *)&base->metadata->data[base->offset]; + ValueBlob *blob = (ValueBlob *)&base->typelib->data[base->offset]; return (glong)blob->value; } @@ -904,7 +904,7 @@ g_field_info_get_flags (GIFieldInfo *info) GIFieldInfoFlags flags; GIBaseInfo *base = (GIBaseInfo *)info; - FieldBlob *blob = (FieldBlob *)&base->metadata->data[base->offset]; + FieldBlob *blob = (FieldBlob *)&base->typelib->data[base->offset]; flags = 0; @@ -921,7 +921,7 @@ gint g_field_info_get_size (GIFieldInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - FieldBlob *blob = (FieldBlob *)&base->metadata->data[base->offset]; + FieldBlob *blob = (FieldBlob *)&base->typelib->data[base->offset]; return blob->bits; } @@ -930,7 +930,7 @@ gint g_field_info_get_offset (GIFieldInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - FieldBlob *blob = (FieldBlob *)&base->metadata->data[base->offset]; + FieldBlob *blob = (FieldBlob *)&base->typelib->data[base->offset]; return blob->struct_offset; } @@ -940,7 +940,7 @@ g_field_info_get_type (GIFieldInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - return g_type_info_new (base, base->metadata, base->offset + 8); + return g_type_info_new (base, base->typelib, base->offset + 8); } /* GIRegisteredTypeInfo functions */ @@ -948,10 +948,10 @@ const gchar * g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->metadata->data[base->offset]; + RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->typelib->data[base->offset]; if (blob->gtype_name) - return g_typelib_get_string (base->metadata, blob->gtype_name); + return g_typelib_get_string (base->typelib, blob->gtype_name); return NULL; } @@ -960,10 +960,10 @@ const gchar * g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->metadata->data[base->offset]; + RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->typelib->data[base->offset]; if (blob->gtype_init) - return g_typelib_get_string (base->metadata, blob->gtype_init); + return g_typelib_get_string (base->typelib, blob->gtype_init); return NULL; } @@ -980,7 +980,7 @@ g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info) return G_TYPE_NONE; get_type_func = NULL; - if (!g_module_symbol (((GIBaseInfo*)info)->metadata->module, + if (!g_module_symbol (((GIBaseInfo*)info)->typelib->module, type_init, (void**) &get_type_func)) return G_TYPE_NONE; @@ -993,7 +993,7 @@ gint g_struct_info_get_n_fields (GIStructInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - StructBlob *blob = (StructBlob *)&base->metadata->data[base->offset]; + StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset]; return blob->n_fields; } @@ -1003,9 +1003,9 @@ g_struct_info_get_field (GIStructInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; + Header *header = (Header *)base->typelib->data; - return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->metadata, + return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->typelib, base->offset + header->struct_blob_size + n * header->field_blob_size); } @@ -1014,7 +1014,7 @@ gint g_struct_info_get_n_methods (GIStructInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - StructBlob *blob = (StructBlob *)&base->metadata->data[base->offset]; + StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset]; return blob->n_methods; } @@ -1024,15 +1024,15 @@ g_struct_info_get_method (GIStructInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - StructBlob *blob = (StructBlob *)&base->metadata->data[base->offset]; - Header *header = (Header *)base->metadata->data; + StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset]; + Header *header = (Header *)base->typelib->data; gint offset; offset = base->offset + header->struct_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); + base->typelib, offset); } static GIFunctionInfo * @@ -1042,17 +1042,17 @@ find_method (GIBaseInfo *base, const gchar *name) { /* FIXME hash */ - Header *header = (Header *)base->metadata->data; + Header *header = (Header *)base->typelib->data; gint i; for (i = 0; i < n_methods; i++) { - FunctionBlob *fblob = (FunctionBlob *)&base->metadata->data[offset]; - const gchar *fname = (const gchar *)&base->metadata->data[fblob->name]; + FunctionBlob *fblob = (FunctionBlob *)&base->typelib->data[offset]; + const gchar *fname = (const gchar *)&base->typelib->data[fblob->name]; if (strcmp (name, fname) == 0) return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, - base->metadata, offset); + base->typelib, offset); offset += header->function_blob_size; } @@ -1066,8 +1066,8 @@ g_struct_info_find_method (GIStructInfo *info, { gint offset; GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; - StructBlob *blob = (StructBlob *)&base->metadata->data[base->offset]; + Header *header = (Header *)base->typelib->data; + StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset]; offset = base->offset + header->struct_blob_size + blob->n_fields * header->field_blob_size; @@ -1079,7 +1079,7 @@ gint g_enum_info_get_n_values (GIEnumInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - EnumBlob *blob = (EnumBlob *)&base->metadata->data[base->offset]; + EnumBlob *blob = (EnumBlob *)&base->typelib->data[base->offset]; return blob->n_values; } @@ -1089,12 +1089,12 @@ g_enum_info_get_value (GIEnumInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; + Header *header = (Header *)base->typelib->data; gint offset; 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->typelib, offset); } /* GIObjectInfo functions */ @@ -1102,10 +1102,10 @@ GIObjectInfo * g_object_info_get_parent (GIObjectInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; if (blob->parent) - return (GIObjectInfo *) g_info_from_entry (base->metadata, blob->parent); + return (GIObjectInfo *) g_info_from_entry (base->typelib, blob->parent); else return NULL; } @@ -1114,25 +1114,25 @@ const gchar * g_object_info_get_type_name (GIObjectInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; - return g_typelib_get_string (base->metadata, blob->gtype_name); + return g_typelib_get_string (base->typelib, blob->gtype_name); } const gchar * g_object_info_get_type_init (GIObjectInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; - return g_typelib_get_string (base->metadata, blob->gtype_init); + return g_typelib_get_string (base->typelib, blob->gtype_init); } gint g_object_info_get_n_interfaces (GIObjectInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; return blob->n_interfaces; } @@ -1142,16 +1142,16 @@ g_object_info_get_interface (GIObjectInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; - return (GIInterfaceInfo *) g_info_from_entry (base->metadata, blob->interfaces[n]); + return (GIInterfaceInfo *) g_info_from_entry (base->typelib, blob->interfaces[n]); } gint g_object_info_get_n_fields (GIObjectInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; return blob->n_fields; } @@ -1162,21 +1162,21 @@ g_object_info_get_field (GIObjectInfo *info, { gint offset; GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + Header *header = (Header *)base->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; offset = base->offset + header->object_blob_size + (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->typelib, offset); } gint g_object_info_get_n_properties (GIObjectInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; return blob->n_properties; } @@ -1187,8 +1187,8 @@ g_object_info_get_property (GIObjectInfo *info, { gint offset; GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + Header *header = (Header *)base->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; offset = base->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 @@ -1196,14 +1196,14 @@ g_object_info_get_property (GIObjectInfo *info, + n * header->property_blob_size; return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, base, - base->metadata, offset); + base->typelib, offset); } gint g_object_info_get_n_methods (GIObjectInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; return blob->n_methods; } @@ -1214,8 +1214,8 @@ g_object_info_get_method (GIObjectInfo *info, { gint offset; GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + Header *header = (Header *)base->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; offset = base->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 @@ -1224,7 +1224,7 @@ g_object_info_get_method (GIObjectInfo *info, + n * header->function_blob_size; return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, - base->metadata, offset); + base->typelib, offset); } GIFunctionInfo * @@ -1233,8 +1233,8 @@ g_object_info_find_method (GIObjectInfo *info, { gint offset; GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + Header *header = (Header *)base->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; offset = base->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 @@ -1248,7 +1248,7 @@ gint g_object_info_get_n_signals (GIObjectInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; return blob->n_signals; } @@ -1259,8 +1259,8 @@ g_object_info_get_signal (GIObjectInfo *info, { gint offset; GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + Header *header = (Header *)base->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; offset = base->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 @@ -1270,14 +1270,14 @@ g_object_info_get_signal (GIObjectInfo *info, + n * header->signal_blob_size; return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, base, - base->metadata, offset); + base->typelib, offset); } gint g_object_info_get_n_vfuncs (GIObjectInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; return blob->n_vfuncs; } @@ -1288,8 +1288,8 @@ g_object_info_get_vfunc (GIObjectInfo *info, { gint offset; GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + Header *header = (Header *)base->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; offset = base->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 @@ -1300,14 +1300,14 @@ g_object_info_get_vfunc (GIObjectInfo *info, + n * header->vfunc_blob_size; return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, base, - base->metadata, offset); + base->typelib, offset); } gint g_object_info_get_n_constants (GIObjectInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; return blob->n_constants; } @@ -1318,8 +1318,8 @@ g_object_info_get_constant (GIObjectInfo *info, { gint offset; GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; - ObjectBlob *blob = (ObjectBlob *)&base->metadata->data[base->offset]; + Header *header = (Header *)base->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; offset = base->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 @@ -1331,7 +1331,7 @@ g_object_info_get_constant (GIObjectInfo *info, + n * header->constant_blob_size; return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, base, - base->metadata, offset); + base->typelib, offset); } @@ -1340,7 +1340,7 @@ gint g_interface_info_get_n_prerequisites (GIInterfaceInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; return blob->n_prerequisites; } @@ -1350,9 +1350,9 @@ g_interface_info_get_prerequisite (GIInterfaceInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; - return g_info_from_entry (base->metadata, blob->prerequisites[n]); + return g_info_from_entry (base->typelib, blob->prerequisites[n]); } @@ -1360,7 +1360,7 @@ gint g_interface_info_get_n_properties (GIInterfaceInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; return blob->n_properties; } @@ -1371,22 +1371,22 @@ g_interface_info_get_property (GIInterfaceInfo *info, { gint offset; GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; - InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + Header *header = (Header *)base->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; offset = base->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + n * header->property_blob_size; return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, base, - base->metadata, offset); + base->typelib, offset); } gint g_interface_info_get_n_methods (GIInterfaceInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; return blob->n_methods; } @@ -1397,8 +1397,8 @@ g_interface_info_get_method (GIInterfaceInfo *info, { gint offset; GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; - InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + Header *header = (Header *)base->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; offset = base->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 @@ -1406,7 +1406,7 @@ g_interface_info_get_method (GIInterfaceInfo *info, + n * header->function_blob_size; return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, - base->metadata, offset); + base->typelib, offset); } GIFunctionInfo * @@ -1415,8 +1415,8 @@ g_interface_info_find_method (GIInterfaceInfo *info, { gint offset; GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; - InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + Header *header = (Header *)base->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; offset = base->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 @@ -1429,7 +1429,7 @@ gint g_interface_info_get_n_signals (GIInterfaceInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; return blob->n_signals; } @@ -1440,8 +1440,8 @@ g_interface_info_get_signal (GIInterfaceInfo *info, { gint offset; GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; - InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + Header *header = (Header *)base->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; offset = base->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 @@ -1450,14 +1450,14 @@ g_interface_info_get_signal (GIInterfaceInfo *info, + n * header->signal_blob_size; return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, base, - base->metadata, offset); + base->typelib, offset); } gint g_interface_info_get_n_vfuncs (GIInterfaceInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; return blob->n_vfuncs; } @@ -1468,8 +1468,8 @@ g_interface_info_get_vfunc (GIInterfaceInfo *info, { gint offset; GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; - InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + Header *header = (Header *)base->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; offset = base->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 @@ -1479,14 +1479,14 @@ g_interface_info_get_vfunc (GIInterfaceInfo *info, + n * header->vfunc_blob_size; return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, base, - base->metadata, offset); + base->typelib, offset); } gint g_interface_info_get_n_constants (GIInterfaceInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; return blob->n_constants; } @@ -1497,8 +1497,8 @@ g_interface_info_get_constant (GIInterfaceInfo *info, { gint offset; GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; - InterfaceBlob *blob = (InterfaceBlob *)&base->metadata->data[base->offset]; + Header *header = (Header *)base->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; offset = base->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 @@ -1509,7 +1509,7 @@ g_interface_info_get_constant (GIInterfaceInfo *info, + n * header->constant_blob_size; return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, base, - base->metadata, offset); + base->typelib, offset); } @@ -1521,7 +1521,7 @@ g_property_info_get_flags (GIPropertyInfo *info) { GParamFlags flags; GIBaseInfo *base = (GIBaseInfo *)info; - PropertyBlob *blob = (PropertyBlob *)&base->metadata->data[base->offset]; + PropertyBlob *blob = (PropertyBlob *)&base->typelib->data[base->offset]; flags = 0; @@ -1545,7 +1545,7 @@ g_property_info_get_type (GIPropertyInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - return g_type_info_new (base, base->metadata, base->offset + 8); + return g_type_info_new (base, base->typelib, base->offset + 8); } @@ -1556,7 +1556,7 @@ g_signal_info_get_flags (GISignalInfo *info) GSignalFlags flags; GIBaseInfo *base = (GIBaseInfo *)info; - SignalBlob *blob = (SignalBlob *)&base->metadata->data[base->offset]; + SignalBlob *blob = (SignalBlob *)&base->typelib->data[base->offset]; flags = 0; @@ -1588,7 +1588,7 @@ GIVFuncInfo * g_signal_info_get_class_closure (GISignalInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SignalBlob *blob = (SignalBlob *)&base->metadata->data[base->offset]; + SignalBlob *blob = (SignalBlob *)&base->typelib->data[base->offset]; if (blob->has_class_closure) return g_interface_info_get_vfunc ((GIInterfaceInfo *)base->container, blob->class_closure); @@ -1600,7 +1600,7 @@ gboolean g_signal_info_true_stops_emit (GISignalInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - SignalBlob *blob = (SignalBlob *)&base->metadata->data[base->offset]; + SignalBlob *blob = (SignalBlob *)&base->typelib->data[base->offset]; return blob->true_stops_emit; } @@ -1612,7 +1612,7 @@ g_vfunc_info_get_flags (GIVFuncInfo *info) GIVFuncInfoFlags flags; GIBaseInfo *base = (GIBaseInfo *)info; - VFuncBlob *blob = (VFuncBlob *)&base->metadata->data[base->offset]; + VFuncBlob *blob = (VFuncBlob *)&base->typelib->data[base->offset]; flags = 0; @@ -1632,7 +1632,7 @@ gint g_vfunc_info_get_offset (GIVFuncInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - VFuncBlob *blob = (VFuncBlob *)&base->metadata->data[base->offset]; + VFuncBlob *blob = (VFuncBlob *)&base->typelib->data[base->offset]; return blob->struct_offset; } @@ -1641,7 +1641,7 @@ GISignalInfo * g_vfunc_info_get_signal (GIVFuncInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - VFuncBlob *blob = (VFuncBlob *)&base->metadata->data[base->offset]; + VFuncBlob *blob = (VFuncBlob *)&base->typelib->data[base->offset]; if (blob->class_closure) return g_interface_info_get_signal ((GIInterfaceInfo *)base->container, blob->signal); @@ -1656,7 +1656,7 @@ g_constant_info_get_type (GIConstantInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - return g_type_info_new (base, base->metadata, base->offset + 8); + return g_type_info_new (base, base->typelib, base->offset + 8); } gint @@ -1664,61 +1664,61 @@ g_constant_info_get_value (GIConstantInfo *info, GArgument *value) { GIBaseInfo *base = (GIBaseInfo *)info; - ConstantBlob *blob = (ConstantBlob *)&base->metadata->data[base->offset]; + ConstantBlob *blob = (ConstantBlob *)&base->typelib->data[base->offset]; /* FIXME non-basic types ? */ if (blob->type.reserved == 0) { if (blob->type.pointer) - value->v_pointer = g_memdup (&base->metadata->data[blob->offset], blob->size); + value->v_pointer = g_memdup (&base->typelib->data[blob->offset], blob->size); else { switch (blob->type.tag) { case GI_TYPE_TAG_BOOLEAN: - value->v_boolean = *(gboolean*)&base->metadata->data[blob->offset]; + value->v_boolean = *(gboolean*)&base->typelib->data[blob->offset]; break; case GI_TYPE_TAG_INT8: - value->v_int8 = *(gint8*)&base->metadata->data[blob->offset]; + value->v_int8 = *(gint8*)&base->typelib->data[blob->offset]; break; case GI_TYPE_TAG_UINT8: - value->v_uint8 = *(guint8*)&base->metadata->data[blob->offset]; + value->v_uint8 = *(guint8*)&base->typelib->data[blob->offset]; break; case GI_TYPE_TAG_INT16: - value->v_int16 = *(gint16*)&base->metadata->data[blob->offset]; + value->v_int16 = *(gint16*)&base->typelib->data[blob->offset]; break; case GI_TYPE_TAG_UINT16: - value->v_uint16 = *(guint16*)&base->metadata->data[blob->offset]; + value->v_uint16 = *(guint16*)&base->typelib->data[blob->offset]; break; case GI_TYPE_TAG_INT32: - value->v_int32 = *(gint32*)&base->metadata->data[blob->offset]; + value->v_int32 = *(gint32*)&base->typelib->data[blob->offset]; break; case GI_TYPE_TAG_UINT32: - value->v_uint32 = *(guint32*)&base->metadata->data[blob->offset]; + value->v_uint32 = *(guint32*)&base->typelib->data[blob->offset]; break; case GI_TYPE_TAG_INT64: - value->v_int64 = *(gint64*)&base->metadata->data[blob->offset]; + value->v_int64 = *(gint64*)&base->typelib->data[blob->offset]; break; case GI_TYPE_TAG_UINT64: - value->v_uint64 = *(guint64*)&base->metadata->data[blob->offset]; + value->v_uint64 = *(guint64*)&base->typelib->data[blob->offset]; break; case GI_TYPE_TAG_FLOAT: - value->v_float = *(gfloat*)&base->metadata->data[blob->offset]; + value->v_float = *(gfloat*)&base->typelib->data[blob->offset]; break; case GI_TYPE_TAG_DOUBLE: - value->v_double = *(gdouble*)&base->metadata->data[blob->offset]; + value->v_double = *(gdouble*)&base->typelib->data[blob->offset]; break; case GI_TYPE_TAG_INT: - value->v_int = *(gint*)&base->metadata->data[blob->offset]; + value->v_int = *(gint*)&base->typelib->data[blob->offset]; break; case GI_TYPE_TAG_UINT: - value->v_uint = *(guint*)&base->metadata->data[blob->offset]; + value->v_uint = *(guint*)&base->typelib->data[blob->offset]; break; case GI_TYPE_TAG_LONG: - value->v_long = *(glong*)&base->metadata->data[blob->offset]; + value->v_long = *(glong*)&base->typelib->data[blob->offset]; break; case GI_TYPE_TAG_ULONG: - value->v_ulong = *(gulong*)&base->metadata->data[blob->offset]; + value->v_ulong = *(gulong*)&base->typelib->data[blob->offset]; break; } } @@ -1732,7 +1732,7 @@ gint g_union_info_get_n_fields (GIUnionInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - UnionBlob *blob = (UnionBlob *)&base->metadata->data[base->offset]; + UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; return blob->n_fields; } @@ -1742,9 +1742,9 @@ g_union_info_get_field (GIUnionInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->metadata->data; + Header *header = (Header *)base->typelib->data; - return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->metadata, + return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->typelib, base->offset + header->union_blob_size + n * header->field_blob_size); } @@ -1753,7 +1753,7 @@ gint g_union_info_get_n_methods (GIUnionInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - UnionBlob *blob = (UnionBlob *)&base->metadata->data[base->offset]; + UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; return blob->n_functions; } @@ -1763,22 +1763,22 @@ g_union_info_get_method (GIUnionInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - UnionBlob *blob = (UnionBlob *)&base->metadata->data[base->offset]; - Header *header = (Header *)base->metadata->data; + UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; + Header *header = (Header *)base->typelib->data; gint offset; offset = base->offset + header->union_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); + base->typelib, offset); } gboolean g_union_info_is_discriminated (GIUnionInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - UnionBlob *blob = (UnionBlob *)&base->metadata->data[base->offset]; + UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; return blob->discriminated; } @@ -1787,7 +1787,7 @@ gint g_union_info_get_discriminator_offset (GIUnionInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - UnionBlob *blob = (UnionBlob *)&base->metadata->data[base->offset]; + UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; return blob->discriminator_offset; } @@ -1797,7 +1797,7 @@ g_union_info_get_discriminator_type (GIUnionInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - return g_type_info_new (base, base->metadata, base->offset + 24); + return g_type_info_new (base, base->typelib, base->offset + 24); } GIConstantInfo * @@ -1805,11 +1805,11 @@ g_union_info_get_discriminator (GIUnionInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - UnionBlob *blob = (UnionBlob *)&base->metadata->data[base->offset]; + UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; if (blob->discriminated) { - Header *header = (Header *)base->metadata->data; + Header *header = (Header *)base->typelib->data; gint offset; offset = base->offset + header->union_blob_size @@ -1818,7 +1818,7 @@ g_union_info_get_discriminator (GIUnionInfo *info, + n * header->constant_blob_size; return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, base, - base->metadata, offset); + base->typelib, offset); } return NULL; diff --git a/ginvoke.c b/ginvoke.c index d283b69f0..919ca8884 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -163,7 +163,7 @@ g_function_info_invoke (GIFunctionInfo *info, symbol = g_function_info_get_symbol (info); - if (!g_module_symbol (g_base_info_get_metadata((GIBaseInfo *) info)->module, + if (!g_module_symbol (g_base_info_get_typelib((GIBaseInfo *) info)->module, symbol, &func)) { GModule *entire_app; @@ -172,7 +172,7 @@ g_function_info_invoke (GIFunctionInfo *info, * We want to be able to add symbols to an app or an auxiliary * library to fill in gaps in an introspected library. However, * normally we would only look for symbols in the main library - * (metadata->module). + * (typelib->module). * * A more elaborate solution is probably possible, but as a * simple approach for now, if we fail to find a symbol we look @@ -180,7 +180,7 @@ g_function_info_invoke (GIFunctionInfo *info, * * This would not be very efficient if it happened often, since * we always do the failed lookup above first, but very few - * symbols should be outside of metadata->module so it doesn't + * symbols should be outside of typelib->module so it doesn't * matter. */ entire_app = g_module_open (NULL, 0); diff --git a/girepository.c b/girepository.c index 4da5ffc5f..b65d1b40d 100644 --- a/girepository.c +++ b/girepository.c @@ -29,12 +29,12 @@ #include "gtypelib.h" static GIRepository *default_repository = NULL; -static GHashTable *default_metadata = NULL; +static GHashTable *default_typelib = NULL; static GSList *search_path = NULL; struct _GIRepositoryPrivate { - GHashTable *metadata; /* (string) namespace -> GTypelib */ + GHashTable *typelib; /* (string) namespace -> GTypelib */ }; G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT); @@ -51,7 +51,7 @@ g_irepository_finalize (GObject *object) { GIRepository *repository = G_IREPOSITORY (object); - g_hash_table_destroy (repository->priv->metadata); + g_hash_table_destroy (repository->priv->typelib); (* G_OBJECT_CLASS (g_irepository_parent_class)->finalize) (G_OBJECT (repository)); } @@ -70,49 +70,49 @@ g_irepository_class_init (GIRepositoryClass *class) const gchar * g_irepository_register (GIRepository *repository, - GTypelib *metadata) + GTypelib *typelib) { Header *header; const gchar *name; GHashTable *table; GError *error = NULL; - g_return_val_if_fail (metadata != NULL, NULL); + g_return_val_if_fail (typelib != NULL, NULL); - header = (Header *)metadata->data; + header = (Header *)typelib->data; g_return_val_if_fail (header != NULL, NULL); if (repository != NULL) { - if (repository->priv->metadata == NULL) - repository->priv->metadata = g_hash_table_new_full (g_str_hash, g_str_equal, + if (repository->priv->typelib == NULL) + repository->priv->typelib = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) NULL, (GDestroyNotify) g_typelib_free); - table = repository->priv->metadata; + table = repository->priv->typelib; } else { - if (default_metadata == NULL) - default_metadata = g_hash_table_new_full (g_str_hash, g_str_equal, + if (default_typelib == NULL) + default_typelib = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) NULL, (GDestroyNotify) g_typelib_free); - table = default_metadata; + table = default_typelib; } - name = g_typelib_get_string (metadata, header->namespace); + name = g_typelib_get_string (typelib, header->namespace); if (g_hash_table_lookup (table, name)) { - g_printerr ("metadata (%p) for '%s' already registered\n", - metadata, name); + g_printerr ("typelib (%p) for '%s' already registered\n", + typelib, name); return NULL; } - g_hash_table_insert (table, g_strdup(name), (void *)metadata); + g_hash_table_insert (table, g_strdup(name), (void *)typelib); - if (metadata->module == NULL) - metadata->module = g_module_open (NULL, 0); + if (typelib->module == NULL) + typelib->module = g_module_open (NULL, 0); if (g_getenv ("G_IREPOSITORY_VERBOSE")) { @@ -130,9 +130,9 @@ g_irepository_unregister (GIRepository *repository, GHashTable *table; if (repository != NULL) - table = repository->priv->metadata; + table = repository->priv->typelib; else - table = default_metadata; + table = default_typelib; if (!g_hash_table_remove (table, namespace)) { @@ -147,9 +147,9 @@ g_irepository_is_registered (GIRepository *repository, GHashTable *table; if (repository != NULL) - table = repository->priv->metadata; + table = repository->priv->typelib; else - table = default_metadata; + table = default_typelib; return g_hash_table_lookup (table, namespace) != NULL; } @@ -160,11 +160,11 @@ g_irepository_get_default (void) if (default_repository == NULL) { default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL); - if (default_metadata == NULL) - default_metadata = g_hash_table_new_full (g_str_hash, g_str_equal, + if (default_typelib == NULL) + default_typelib = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) NULL, (GDestroyNotify) g_typelib_free); - default_repository->priv->metadata = default_metadata; + default_repository->priv->typelib = default_typelib; } return default_repository; @@ -175,10 +175,10 @@ count_interfaces (gpointer key, gpointer value, gpointer data) { - guchar *metadata = ((GTypelib *) value)->data; + guchar *typelib = ((GTypelib *) value)->data; gint *n_interfaces = (gint *)data; - *n_interfaces += ((Header *)metadata)->n_local_entries; + *n_interfaces += ((Header *)typelib)->n_local_entries; } gint @@ -189,16 +189,16 @@ g_irepository_get_n_infos (GIRepository *repository, if (namespace) { - GTypelib *metadata; + GTypelib *typelib; - metadata = g_hash_table_lookup (repository->priv->metadata, namespace); + typelib = g_hash_table_lookup (repository->priv->typelib, namespace); - if (metadata) - n_interfaces = ((Header *)metadata->data)->n_local_entries; + if (typelib) + n_interfaces = ((Header *)typelib->data)->n_local_entries; } else { - g_hash_table_foreach (repository->priv->metadata, + g_hash_table_foreach (repository->priv->typelib, count_interfaces, &n_interfaces); } @@ -219,7 +219,7 @@ find_interface (gpointer key, gpointer data) { gint i; - GTypelib *metadata = (GTypelib *)value; + GTypelib *typelib = (GTypelib *)value; IfaceData *iface_data = (IfaceData *)data; gint index; gint n_entries; @@ -229,14 +229,14 @@ find_interface (gpointer key, DirEntry *entry; index = 0; - n_entries = ((Header *)metadata->data)->n_local_entries; + n_entries = ((Header *)typelib->data)->n_local_entries; if (iface_data->name) { for (i = 1; i <= n_entries; i++) { - entry = g_typelib_get_dir_entry (metadata, i); - name = g_typelib_get_string (metadata, entry->name); + entry = g_typelib_get_dir_entry (typelib, i); + name = g_typelib_get_string (typelib, entry->name); if (strcmp (name, iface_data->name) == 0) { index = i; @@ -248,12 +248,12 @@ find_interface (gpointer key, { for (i = 1; i <= n_entries; i++) { - entry = g_typelib_get_dir_entry (metadata, i); + entry = g_typelib_get_dir_entry (typelib, i); if (entry->blob_type < 4) continue; - offset = *(guint32*)&metadata->data[entry->offset + 8]; - type = g_typelib_get_string (metadata, offset); + offset = *(guint32*)&typelib->data[entry->offset + 8]; + type = g_typelib_get_string (typelib, offset); if (strcmp (type, iface_data->type) == 0) { index = i; @@ -271,9 +271,9 @@ find_interface (gpointer key, if (index != 0) { - entry = g_typelib_get_dir_entry (metadata, index); + entry = g_typelib_get_dir_entry (typelib, index); iface_data->iface = g_info_new (entry->blob_type, NULL, - metadata, entry->offset); + typelib, entry->offset); } } @@ -291,15 +291,15 @@ g_irepository_get_info (GIRepository *repository, if (namespace) { - GTypelib *metadata; + GTypelib *typelib; - metadata = g_hash_table_lookup (repository->priv->metadata, namespace); + typelib = g_hash_table_lookup (repository->priv->typelib, namespace); - if (metadata) - find_interface ((void *)namespace, metadata, &data); + if (typelib) + find_interface ((void *)namespace, typelib, &data); } else - g_hash_table_foreach (repository->priv->metadata, find_interface, &data); + g_hash_table_foreach (repository->priv->typelib, find_interface, &data); return data.iface; } @@ -315,7 +315,7 @@ g_irepository_find_by_gtype (GIRepository *repository, data.index = -1; data.iface = NULL; - g_hash_table_foreach (repository->priv->metadata, find_interface, &data); + g_hash_table_foreach (repository->priv->typelib, find_interface, &data); return data.iface; } @@ -334,15 +334,15 @@ g_irepository_find_by_name (GIRepository *repository, if (namespace) { - GTypelib *metadata; + GTypelib *typelib; - metadata = g_hash_table_lookup (repository->priv->metadata, namespace); + typelib = g_hash_table_lookup (repository->priv->typelib, namespace); - if (metadata) - find_interface ((void *)namespace, metadata, &data); + if (typelib) + find_interface ((void *)namespace, typelib, &data); } else - g_hash_table_foreach (repository->priv->metadata, find_interface, &data); + g_hash_table_foreach (repository->priv->typelib, find_interface, &data); return data.iface; } @@ -364,7 +364,7 @@ g_irepository_get_namespaces (GIRepository *repository) gchar **names; gint i; - g_hash_table_foreach (repository->priv->metadata, collect_namespaces, &list); + g_hash_table_foreach (repository->priv->typelib, collect_namespaces, &list); names = g_malloc0 (sizeof (gchar *) * (g_list_length (list) + 1)); i = 0; @@ -379,15 +379,15 @@ const gchar * g_irepository_get_shared_library (GIRepository *repository, const gchar *namespace) { - GTypelib *metadata; + GTypelib *typelib; Header *header; - metadata = g_hash_table_lookup (repository->priv->metadata, namespace); - if (!metadata) + typelib = g_hash_table_lookup (repository->priv->typelib, namespace); + if (!typelib) return NULL; - header = (Header *) metadata->data; + header = (Header *) typelib->data; if (header->shared_library) - return g_typelib_get_string (metadata, header->shared_library); + return g_typelib_get_string (typelib, header->shared_library); else return NULL; } @@ -423,16 +423,16 @@ g_irepository_register_file (GIRepository *repository, gchar *fname, *full_path; GMappedFile *mfile; GError *error1 = NULL; - GTypelib *metadata = NULL; - const gchar *metadata_namespace, *shlib_fname; + GTypelib *typelib = NULL; + const gchar *typelib_namespace, *shlib_fname; GModule *module; guint32 shlib; GHashTable *table; if (repository != NULL) - table = repository->priv->metadata; + table = repository->priv->typelib; else - table = default_metadata; + table = default_typelib; /* don't bother loading a namespace if already registered */ if (g_hash_table_lookup (table, namespace)) @@ -454,35 +454,35 @@ g_irepository_register_file (GIRepository *repository, continue; } g_free (full_path); - metadata = g_typelib_new_from_mapped_file (mfile); - metadata_namespace = g_typelib_get_string (metadata, ((Header *) metadata->data)->namespace); - if (strcmp (metadata_namespace, namespace) != 0) { + typelib = g_typelib_new_from_mapped_file (mfile); + typelib_namespace = g_typelib_get_string (typelib, ((Header *) typelib->data)->namespace); + if (strcmp (typelib_namespace, namespace) != 0) { g_set_error (error, G_IREPOSITORY_ERROR, G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH, - "Metadata file %s for namespace '%s' contains namespace '%s'" + "Typelib file %s for namespace '%s' contains namespace '%s'" " which doesn't match the file name", - full_path, namespace, metadata_namespace); + full_path, namespace, typelib_namespace); return NULL; } break; } g_free (fname); - if (metadata == NULL) { + if (typelib == NULL) { g_set_error (error, G_IREPOSITORY_ERROR, - G_IREPOSITORY_ERROR_METADATA_NOT_FOUND, - "Metadata file for namespace '%s' was not found in search" + G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, + "Typelib file for namespace '%s' was not found in search" " path or could not be openened", namespace); return NULL; } - /* optionally load shared library and attach it to the metadata */ - shlib = ((Header *) metadata->data)->shared_library; + /* optionally load shared library and attach it to the typelib */ + shlib = ((Header *) typelib->data)->shared_library; if (shlib) { - shlib_fname = g_typelib_get_string (metadata, shlib); + shlib_fname = g_typelib_get_string (typelib, shlib); module = g_module_open (shlib_fname, G_MODULE_BIND_LAZY|G_MODULE_BIND_LOCAL); if (module == NULL) { g_set_error (error, G_IREPOSITORY_ERROR, - G_IREPOSITORY_ERROR_METADATA_NOT_FOUND, - "Metadata for namespace '%s' references shared library %s," + G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, + "Typelib for namespace '%s' references shared library %s," " but it could not be openened (%s)", namespace, shlib_fname, g_module_error ()); return NULL; @@ -490,7 +490,7 @@ g_irepository_register_file (GIRepository *repository, } g_hash_table_remove (table, namespace); - return g_irepository_register (repository, metadata); + return g_irepository_register (repository, typelib); } diff --git a/girepository.h b/girepository.h index ae5e2c583..010712e78 100644 --- a/girepository.h +++ b/girepository.h @@ -73,7 +73,7 @@ struct _GIRepositoryClass GType g_irepository_get_type (void) G_GNUC_CONST; GIRepository *g_irepository_get_default (void); const gchar * g_irepository_register (GIRepository *repository, - GTypelib *metadata); + GTypelib *typelib); void g_irepository_unregister (GIRepository *repository, const gchar *namespace); const gchar * g_irepository_register_file (GIRepository *repository, @@ -94,21 +94,21 @@ GIBaseInfo * g_irepository_get_info (GIRepository *repository, gint index); const gchar * g_irepository_get_shared_library (GIRepository *repository, const gchar *namespace); -/* Metadata */ +/* Typelib */ GTypelib * g_typelib_new_from_memory (guchar *memory, gsize len); GTypelib * g_typelib_new_from_const_memory (const guchar *memory, gsize len); GTypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile); -void g_typelib_free (GTypelib *metadata); -void g_typelib_set_module (GTypelib *metadata, +void g_typelib_free (GTypelib *typelib); +void g_typelib_set_module (GTypelib *typelib, GModule *module); -const gchar * g_typelib_get_namespace (GTypelib *metadata); +const gchar * g_typelib_get_namespace (GTypelib *typelib); typedef enum { - G_IREPOSITORY_ERROR_METADATA_NOT_FOUND, + G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH, G_IREPOSITORY_ERROR_LIBRARY_NOT_FOUND } GIRepositoryError; @@ -156,11 +156,11 @@ gboolean g_base_info_is_deprecated (GIBaseInfo *info); const gchar * g_base_info_get_annotation (GIBaseInfo *info, const gchar *name); GIBaseInfo * g_base_info_get_container (GIBaseInfo *info); -GTypelib * g_base_info_get_metadata (GIBaseInfo *info); +GTypelib * g_base_info_get_typelib (GIBaseInfo *info); -GIBaseInfo * g_info_new (GIInfoType type, - GIBaseInfo *container, - GTypelib *metadata, +GIBaseInfo * g_info_new (GIInfoType type, + GIBaseInfo *container, + GTypelib *typelib, guint32 offset); diff --git a/girmodule.c b/girmodule.c index 8f09fb4a1..46e70f686 100644 --- a/girmodule.c +++ b/girmodule.c @@ -1,4 +1,4 @@ -/* GObject introspection: Metadata creation +/* GObject introspection: Typelib creation * * Copyright (C) 2005 Matthias Clasen * @@ -61,10 +61,10 @@ g_ir_module_free (GIrModule *module) } GTypelib * -g_ir_module_build_metadata (GIrModule *module, +g_ir_module_build_typelib (GIrModule *module, GList *modules) { - guchar *metadata; + guchar *typelib; gsize length; gint i; GList *e; @@ -190,7 +190,7 @@ g_ir_module_build_metadata (GIrModule *module, entry->offset = offset; entry->name = write_string (node->name, strings, data, &offset2); - g_ir_node_build_metadata (node, module, modules, + g_ir_node_build_typelib (node, module, modules, strings, types, data, &offset, &offset2); if (offset2 > old_offset + g_ir_node_get_full_size (node)) @@ -208,8 +208,8 @@ g_ir_module_build_metadata (GIrModule *module, g_message ("reallocating to %d bytes", offset2); - metadata = g_realloc (data, offset2); + typelib = g_realloc (data, offset2); length = header->size = offset2; - return g_typelib_new_from_memory (metadata, length); + return g_typelib_new_from_memory (typelib, length); } diff --git a/girmodule.h b/girmodule.h index a59e99612..67c6ef7a0 100644 --- a/girmodule.h +++ b/girmodule.h @@ -40,7 +40,7 @@ GIrModule *g_ir_module_new (const gchar *name, const gchar *module_filename); void g_ir_module_free (GIrModule *module); -GTypelib * g_ir_module_build_metadata (GIrModule *module, +GTypelib * g_ir_module_build_typelib (GIrModule *module, GList *modules); G_END_DECLS diff --git a/girnode.c b/girnode.c index 0c7819123..7734bf968 100644 --- a/girnode.c +++ b/girnode.c @@ -1,4 +1,4 @@ -/* GObject introspection: Metadata creation +/* GObject introspection: Typelib creation * * Copyright (C) 2005 Matthias Clasen * @@ -1209,14 +1209,14 @@ serialize_type (GIrModule *module, } void -g_ir_node_build_metadata (GIrNode *node, - GIrModule *module, - GList *modules, - GHashTable *strings, - GHashTable *types, - guchar *data, - guint32 *offset, - guint32 *offset2) +g_ir_node_build_typelib (GIrNode *node, + GIrModule *module, + GList *modules, + GHashTable *strings, + GHashTable *types, + guchar *data, + guint32 *offset, + guint32 *offset2) { GList *l; guint32 old_offset = *offset; @@ -1224,7 +1224,7 @@ g_ir_node_build_metadata (GIrNode *node, g_assert (node != NULL); - g_debug ("build_metadata (%s)", + g_debug ("build_typelib (%s)", g_ir_node_type_to_string (node->type)); switch (node->type) @@ -1287,9 +1287,9 @@ g_ir_node_build_metadata (GIrNode *node, pos = *offset2 + 4; *offset2 += 8; - g_ir_node_build_metadata ((GIrNode *)type->parameter_type1, - module, modules, strings, types, - data, &pos, offset2); + g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, + module, modules, strings, types, + data, &pos, offset2); } break; @@ -1322,9 +1322,9 @@ g_ir_node_build_metadata (GIrNode *node, pos = *offset2 + 4; *offset2 += 8; - g_ir_node_build_metadata ((GIrNode *)type->parameter_type1, - module, modules, strings, types, - data, &pos, offset2); + g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, + module, modules, strings, types, + data, &pos, offset2); } break; @@ -1342,12 +1342,12 @@ g_ir_node_build_metadata (GIrNode *node, pos = *offset2 + 4; *offset2 += 12; - g_ir_node_build_metadata ((GIrNode *)type->parameter_type1, - module, modules, strings, types, - data, &pos, offset2); - g_ir_node_build_metadata ((GIrNode *)type->parameter_type2, - module, modules, strings, types, - data, &pos, offset2); + g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, + module, modules, strings, types, + data, &pos, offset2); + g_ir_node_build_typelib ((GIrNode *)type->parameter_type2, + module, modules, strings, types, + data, &pos, offset2); } break; @@ -1395,9 +1395,9 @@ g_ir_node_build_metadata (GIrNode *node, blob->bits = 0; blob->struct_offset = field->offset; - g_ir_node_build_metadata ((GIrNode *)field->type, - module, modules, strings, types, - data, offset, offset2); + g_ir_node_build_typelib ((GIrNode *)field->type, + module, modules, strings, types, + data, offset, offset2); } break; @@ -1415,9 +1415,9 @@ g_ir_node_build_metadata (GIrNode *node, blob->construct_only = prop->construct_only; blob->reserved = 0; - g_ir_node_build_metadata ((GIrNode *)prop->type, - module, modules, strings, types, - data, offset, offset2); + g_ir_node_build_typelib ((GIrNode *)prop->type, + module, modules, strings, types, + data, offset, offset2); } break; @@ -1447,9 +1447,9 @@ g_ir_node_build_metadata (GIrNode *node, blob->symbol = write_string (function->symbol, strings, data, offset2); blob->signature = signature; - g_ir_node_build_metadata ((GIrNode *)function->result->type, - module, modules, strings, types, - data, &signature, offset2); + g_ir_node_build_typelib ((GIrNode *)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; @@ -1463,9 +1463,9 @@ g_ir_node_build_metadata (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - g_ir_node_build_metadata (param, - module, modules, strings, types, - data, &signature, offset2); + g_ir_node_build_typelib (param, + module, modules, strings, types, + data, &signature, offset2); } } break; @@ -1490,9 +1490,9 @@ g_ir_node_build_metadata (GIrNode *node, blob->name = write_string (node->name, strings, data, offset2); blob->signature = signature; - g_ir_node_build_metadata ((GIrNode *)function->result->type, - module, modules, strings, types, - data, &signature, offset2); + g_ir_node_build_typelib ((GIrNode *)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; @@ -1506,9 +1506,9 @@ g_ir_node_build_metadata (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - g_ir_node_build_metadata (param, - module, modules, strings, types, - data, &signature, offset2); + g_ir_node_build_typelib (param, + module, modules, strings, types, + data, &signature, offset2); } } break; @@ -1542,9 +1542,9 @@ g_ir_node_build_metadata (GIrNode *node, blob->name = write_string (node->name, strings, data, offset2); blob->signature = signature; - g_ir_node_build_metadata ((GIrNode *)signal->result->type, - module, modules, strings, types, - data, &signature, offset2); + g_ir_node_build_typelib ((GIrNode *)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; @@ -1558,8 +1558,8 @@ g_ir_node_build_metadata (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - g_ir_node_build_metadata (param, module, modules, strings, types, - data, &signature, offset2); + g_ir_node_build_typelib (param, module, modules, strings, types, + data, &signature, offset2); } } break; @@ -1589,9 +1589,9 @@ g_ir_node_build_metadata (GIrNode *node, blob->reserved2 = 0; blob->signature = signature; - g_ir_node_build_metadata ((GIrNode *)vfunc->result->type, - module, modules, strings, types, - data, &signature, offset2); + g_ir_node_build_typelib ((GIrNode *)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; @@ -1605,8 +1605,8 @@ g_ir_node_build_metadata (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - g_ir_node_build_metadata (param, module, modules, strings, - types, data, &signature, offset2); + g_ir_node_build_typelib (param, module, modules, strings, + types, data, &signature, offset2); } } break; @@ -1629,8 +1629,8 @@ g_ir_node_build_metadata (GIrNode *node, blob->return_value = param->retval; blob->reserved = 0; - g_ir_node_build_metadata ((GIrNode *)param->type, module, modules, - strings, types, data, offset, offset2); + g_ir_node_build_typelib ((GIrNode *)param->type, module, modules, + strings, types, data, offset, offset2); } break; @@ -1658,8 +1658,8 @@ g_ir_node_build_metadata (GIrNode *node, if (member->type == G_IR_NODE_FIELD) { blob->n_fields++; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } @@ -1670,8 +1670,8 @@ g_ir_node_build_metadata (GIrNode *node, if (member->type == G_IR_NODE_FUNCTION) { blob->n_methods++; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } } @@ -1701,8 +1701,8 @@ g_ir_node_build_metadata (GIrNode *node, if (member->type == G_IR_NODE_FIELD) { blob->n_fields++; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } @@ -1713,8 +1713,8 @@ g_ir_node_build_metadata (GIrNode *node, if (member->type == G_IR_NODE_FUNCTION) { blob->n_methods++; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } } @@ -1751,9 +1751,9 @@ g_ir_node_build_metadata (GIrNode *node, { *offset += 24; blob->discriminated = TRUE; - g_ir_node_build_metadata ((GIrNode *)union_->discriminator_type, - module, modules, strings, types, - data, offset, offset2); + g_ir_node_build_typelib ((GIrNode *)union_->discriminator_type, + module, modules, strings, types, + data, offset, offset2); } else { @@ -1770,8 +1770,8 @@ g_ir_node_build_metadata (GIrNode *node, if (member->type == G_IR_NODE_FIELD) { blob->n_fields++; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } @@ -1782,8 +1782,8 @@ g_ir_node_build_metadata (GIrNode *node, if (member->type == G_IR_NODE_FUNCTION) { blob->n_functions++; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } @@ -1793,8 +1793,8 @@ g_ir_node_build_metadata (GIrNode *node, { GIrNode *member = (GIrNode *)l->data; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } } @@ -1837,8 +1837,8 @@ g_ir_node_build_metadata (GIrNode *node, GIrNode *value = (GIrNode *)l->data; blob->n_values++; - g_ir_node_build_metadata (value, module, modules, strings, types, - data, offset, offset2); + g_ir_node_build_typelib (value, module, modules, strings, types, + data, offset, offset2); } } break; @@ -1883,8 +1883,8 @@ g_ir_node_build_metadata (GIrNode *node, if (member->type == G_IR_NODE_FIELD) { blob->n_fields++; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } @@ -1896,8 +1896,8 @@ g_ir_node_build_metadata (GIrNode *node, if (member->type == G_IR_NODE_PROPERTY) { blob->n_properties++; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } @@ -1909,8 +1909,8 @@ g_ir_node_build_metadata (GIrNode *node, if (member->type == G_IR_NODE_FUNCTION) { blob->n_methods++; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } @@ -1922,8 +1922,8 @@ g_ir_node_build_metadata (GIrNode *node, if (member->type == G_IR_NODE_SIGNAL) { blob->n_signals++; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } @@ -1935,8 +1935,8 @@ g_ir_node_build_metadata (GIrNode *node, if (member->type == G_IR_NODE_VFUNC) { blob->n_vfuncs++; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } @@ -1948,8 +1948,8 @@ g_ir_node_build_metadata (GIrNode *node, if (member->type == G_IR_NODE_CONSTANT) { blob->n_constants++; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } } @@ -1989,8 +1989,8 @@ g_ir_node_build_metadata (GIrNode *node, if (member->type == G_IR_NODE_PROPERTY) { blob->n_properties++; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } @@ -2002,8 +2002,8 @@ g_ir_node_build_metadata (GIrNode *node, if (member->type == G_IR_NODE_FUNCTION) { blob->n_methods++; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } @@ -2015,8 +2015,8 @@ g_ir_node_build_metadata (GIrNode *node, if (member->type == G_IR_NODE_SIGNAL) { blob->n_signals++; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } @@ -2028,8 +2028,8 @@ g_ir_node_build_metadata (GIrNode *node, if (member->type == G_IR_NODE_VFUNC) { blob->n_vfuncs++; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } @@ -2041,8 +2041,8 @@ g_ir_node_build_metadata (GIrNode *node, if (member->type == G_IR_NODE_CONSTANT) { blob->n_constants++; - g_ir_node_build_metadata (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); } } } @@ -2165,8 +2165,8 @@ g_ir_node_build_metadata (GIrNode *node, } *offset2 += ALIGN_VALUE (blob->size, 4); - g_ir_node_build_metadata ((GIrNode *)constant->type, module, modules, - strings, types, data, &pos, offset2); + g_ir_node_build_typelib ((GIrNode *)constant->type, module, modules, + strings, types, data, &pos, offset2); } break; default: @@ -2182,8 +2182,8 @@ g_ir_node_build_metadata (GIrNode *node, } /* 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. + * to the typelib at offset, put it in the pool and update offset. If the + * typelib is not large enough to hold the string, reallocate it. */ guint32 write_string (const gchar *str, diff --git a/girnode.h b/girnode.h index 66144d38b..a01e01f38 100644 --- a/girnode.h +++ b/girnode.h @@ -309,23 +309,23 @@ GIrNode * g_ir_node_new (GIrNodeTypeId type); void g_ir_node_free (GIrNode *node); guint32 g_ir_node_get_size (GIrNode *node); guint32 g_ir_node_get_full_size (GIrNode *node); -void g_ir_node_build_metadata (GIrNode *node, - GIrModule *module, - GList *modules, - GHashTable *strings, - GHashTable *types, - guchar *data, - guint32 *offset, - guint32 *offset2); +void g_ir_node_build_typelib (GIrNode *node, + GIrModule *module, + GList *modules, + GHashTable *strings, + GHashTable *types, + guchar *data, + guint32 *offset, + guint32 *offset2); int g_ir_node_cmp (GIrNode *node, - GIrNode *other); + GIrNode *other); gboolean g_ir_node_can_have_member (GIrNode *node); void g_ir_node_add_member (GIrNode *node, - GIrNodeFunction *member); -guint32 write_string (const gchar *str, - GHashTable *strings, - guchar *data, - guint32 *offset); + GIrNodeFunction *member); +guint32 write_string (const gchar *str, + GHashTable *strings, + guchar *data, + guint32 *offset); const gchar * g_ir_node_param_direction_string (GIrNodeParam * node); diff --git a/gtypelib.c b/gtypelib.c index cc07e96e2..ca149f0d6 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1,5 +1,5 @@ -/* GObject introspection: metadata validation, auxiliary functions - * related to the binary metadata format +/* GObject introspection: typelib validation, auxiliary functions + * related to the binary typelib format * * Copyright (C) 2005 Matthias Clasen * @@ -32,12 +32,12 @@ DirEntry * -g_typelib_get_dir_entry (GTypelib *metadata, +g_typelib_get_dir_entry (GTypelib *typelib, guint16 index) { - Header *header = (Header *)metadata->data; + Header *header = (Header *)typelib->data; - return (DirEntry *)&metadata->data[header->directory + (index - 1) * header->entry_blob_size]; + return (DirEntry *)&typelib->data[header->directory + (index - 1) * header->entry_blob_size]; } void @@ -97,12 +97,12 @@ is_name (const guchar *data, guint32 offset) } static gboolean -validate_header (GTypelib *metadata, +validate_header (GTypelib *typelib, GError **error) { Header *header; - if (metadata->len < sizeof (Header)) + if (typelib->len < sizeof (Header)) { g_set_error (error, G_TYPELIB_ERROR, @@ -111,7 +111,7 @@ validate_header (GTypelib *metadata, return FALSE; } - header = (Header *)metadata->data; + header = (Header *)typelib->data; if (strncmp (header->magic, G_IR_MAGIC, 16) != 0) { @@ -142,12 +142,12 @@ validate_header (GTypelib *metadata, return FALSE; } - if (header->size != metadata->len) + if (header->size != typelib->len) { g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_HEADER, - "Metadata size mismatch"); + "Typelib size mismatch"); return FALSE; } @@ -204,7 +204,7 @@ validate_header (GTypelib *metadata, return FALSE; } - if (!is_name (metadata->data, header->namespace)) + if (!is_name (typelib->data, header->namespace)) { g_set_error (error, G_TYPELIB_ERROR, @@ -216,14 +216,14 @@ validate_header (GTypelib *metadata, return TRUE; } -static gboolean validate_type_blob (GTypelib *metadata, +static gboolean validate_type_blob (GTypelib *typelib, guint32 offset, guint32 signature_offset, gboolean return_type, GError **error); static gboolean -validate_array_type_blob (GTypelib *metadata, +validate_array_type_blob (GTypelib *typelib, guint32 offset, guint32 signature_offset, gboolean return_type, @@ -231,7 +231,7 @@ validate_array_type_blob (GTypelib *metadata, { ArrayTypeBlob *blob; - blob = (ArrayTypeBlob*)&metadata->data[offset]; + blob = (ArrayTypeBlob*)&typelib->data[offset]; if (!blob->pointer) { @@ -244,7 +244,7 @@ validate_array_type_blob (GTypelib *metadata, /* FIXME validate length */ - if (!validate_type_blob (metadata, + if (!validate_type_blob (typelib, offset + G_STRUCT_OFFSET (ArrayTypeBlob, type), 0, FALSE, error)) return FALSE; @@ -253,7 +253,7 @@ validate_array_type_blob (GTypelib *metadata, } static gboolean -validate_iface_type_blob (GTypelib *metadata, +validate_iface_type_blob (GTypelib *typelib, guint32 offset, guint32 signature_offset, gboolean return_type, @@ -262,9 +262,9 @@ validate_iface_type_blob (GTypelib *metadata, InterfaceTypeBlob *blob; Header *header; - header = (Header *)metadata->data; + header = (Header *)typelib->data; - blob = (InterfaceTypeBlob*)&metadata->data[offset]; + blob = (InterfaceTypeBlob*)&typelib->data[offset]; if (blob->interface == 0 || blob->interface > header->n_entries) { @@ -279,7 +279,7 @@ validate_iface_type_blob (GTypelib *metadata, } static gboolean -validate_param_type_blob (GTypelib *metadata, +validate_param_type_blob (GTypelib *typelib, guint32 offset, guint32 signature_offset, gboolean return_type, @@ -289,7 +289,7 @@ validate_param_type_blob (GTypelib *metadata, ParamTypeBlob *blob; gint i; - blob = (ParamTypeBlob*)&metadata->data[offset]; + blob = (ParamTypeBlob*)&typelib->data[offset]; if (!blob->pointer) { @@ -311,7 +311,7 @@ validate_param_type_blob (GTypelib *metadata, for (i = 0; i < n_params; i++) { - if (!validate_type_blob (metadata, + if (!validate_type_blob (typelib, offset + sizeof (ParamTypeBlob) + i * sizeof (SimpleTypeBlob), 0, FALSE, error)) @@ -322,7 +322,7 @@ validate_param_type_blob (GTypelib *metadata, } static gboolean -validate_error_type_blob (GTypelib *metadata, +validate_error_type_blob (GTypelib *typelib, guint32 offset, guint32 signature_offset, gboolean return_type, @@ -333,9 +333,9 @@ validate_error_type_blob (GTypelib *metadata, gint i; DirEntry *entry; - blob = (ErrorTypeBlob*)&metadata->data[offset]; + blob = (ErrorTypeBlob*)&typelib->data[offset]; - header = (Header *)metadata->data; + header = (Header *)typelib->data; if (!blob->pointer) { @@ -357,7 +357,7 @@ validate_error_type_blob (GTypelib *metadata, return FALSE; } - entry = g_typelib_get_dir_entry (metadata, blob->domains[i]); + entry = g_typelib_get_dir_entry (typelib, blob->domains[i]); if (entry->blob_type != BLOB_TYPE_ERROR_DOMAIN && (entry->local || entry->blob_type != BLOB_TYPE_INVALID)) @@ -374,7 +374,7 @@ validate_error_type_blob (GTypelib *metadata, } static gboolean -validate_type_blob (GTypelib *metadata, +validate_type_blob (GTypelib *typelib, guint32 offset, guint32 signature_offset, gboolean return_type, @@ -383,7 +383,7 @@ validate_type_blob (GTypelib *metadata, SimpleTypeBlob *simple; InterfaceTypeBlob *iface; - simple = (SimpleTypeBlob *)&metadata->data[offset]; + simple = (SimpleTypeBlob *)&typelib->data[offset]; if (simple->reserved == 0 && simple->reserved2 == 0) @@ -410,33 +410,33 @@ validate_type_blob (GTypelib *metadata, return TRUE; } - iface = (InterfaceTypeBlob*)&metadata->data[simple->offset]; + iface = (InterfaceTypeBlob*)&typelib->data[simple->offset]; switch (iface->tag) { case TYPE_TAG_ARRAY: - if (!validate_array_type_blob (metadata, simple->offset, + if (!validate_array_type_blob (typelib, simple->offset, signature_offset, return_type, error)) return FALSE; break; case TYPE_TAG_INTERFACE: - if (!validate_iface_type_blob (metadata, simple->offset, + if (!validate_iface_type_blob (typelib, simple->offset, signature_offset, return_type, error)) return FALSE; break; case TYPE_TAG_LIST: case TYPE_TAG_SLIST: - if (!validate_param_type_blob (metadata, simple->offset, + if (!validate_param_type_blob (typelib, simple->offset, signature_offset, return_type, 1, error)) return FALSE; break; case TYPE_TAG_HASH: - if (!validate_param_type_blob (metadata, simple->offset, + if (!validate_param_type_blob (typelib, simple->offset, signature_offset, return_type, 2, error)) return FALSE; break; case TYPE_TAG_ERROR: - if (!validate_error_type_blob (metadata, simple->offset, + if (!validate_error_type_blob (typelib, simple->offset, signature_offset, return_type, error)) return FALSE; break; @@ -452,14 +452,14 @@ validate_type_blob (GTypelib *metadata, } static gboolean -validate_arg_blob (GTypelib *metadata, +validate_arg_blob (GTypelib *typelib, guint32 offset, guint32 signature_offset, GError **error) { ArgBlob *blob; - if (metadata->len < offset + sizeof (ArgBlob)) + if (typelib->len < offset + sizeof (ArgBlob)) { g_set_error (error, G_TYPELIB_ERROR, @@ -468,9 +468,9 @@ validate_arg_blob (GTypelib *metadata, return FALSE; } - blob = (ArgBlob*) &metadata->data[offset]; + blob = (ArgBlob*) &typelib->data[offset]; - if (!is_name (metadata->data, blob->name)) + if (!is_name (typelib->data, blob->name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -479,7 +479,7 @@ validate_arg_blob (GTypelib *metadata, return FALSE; } - if (!validate_type_blob (metadata, + if (!validate_type_blob (typelib, offset + G_STRUCT_OFFSET (ArgBlob, arg_type), signature_offset, FALSE, error)) return FALSE; @@ -488,14 +488,14 @@ validate_arg_blob (GTypelib *metadata, } static gboolean -validate_signature_blob (GTypelib *metadata, +validate_signature_blob (GTypelib *typelib, guint32 offset, GError **error) { SignatureBlob *blob; gint i; - if (metadata->len < offset + sizeof (SignatureBlob)) + if (typelib->len < offset + sizeof (SignatureBlob)) { g_set_error (error, G_TYPELIB_ERROR, @@ -504,11 +504,11 @@ validate_signature_blob (GTypelib *metadata, return FALSE; } - blob = (SignatureBlob*) &metadata->data[offset]; + blob = (SignatureBlob*) &typelib->data[offset]; if (blob->return_type.offset != 0) { - if (!validate_type_blob (metadata, + if (!validate_type_blob (typelib, offset + G_STRUCT_OFFSET (SignatureBlob, return_type), offset, TRUE, error)) return FALSE; @@ -516,7 +516,7 @@ validate_signature_blob (GTypelib *metadata, for (i = 0; i < blob->n_arguments; i++) { - if (!validate_arg_blob (metadata, + if (!validate_arg_blob (typelib, offset + sizeof (SignatureBlob) + i * sizeof (ArgBlob), offset, @@ -530,14 +530,14 @@ validate_signature_blob (GTypelib *metadata, } static gboolean -validate_function_blob (GTypelib *metadata, +validate_function_blob (GTypelib *typelib, guint32 offset, guint16 container_type, GError **error) { FunctionBlob *blob; - if (metadata->len < offset + sizeof (FunctionBlob)) + if (typelib->len < offset + sizeof (FunctionBlob)) { g_set_error (error, G_TYPELIB_ERROR, @@ -546,7 +546,7 @@ validate_function_blob (GTypelib *metadata, return FALSE; } - blob = (FunctionBlob*) &metadata->data[offset]; + blob = (FunctionBlob*) &typelib->data[offset]; if (blob->blob_type != BLOB_TYPE_FUNCTION) { @@ -557,7 +557,7 @@ validate_function_blob (GTypelib *metadata, return FALSE; } - if (!is_name (metadata->data, blob->name)) + if (!is_name (typelib->data, blob->name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -566,7 +566,7 @@ validate_function_blob (GTypelib *metadata, return FALSE; } - if (!is_name (metadata->data, blob->symbol)) + if (!is_name (typelib->data, blob->symbol)) { g_set_error (error, G_TYPELIB_ERROR, @@ -624,20 +624,20 @@ validate_function_blob (GTypelib *metadata, /* FIXME: validate "this" argument for methods */ /* FIXME: validate return type for constructors */ - if (!validate_signature_blob (metadata, blob->signature, error)) + if (!validate_signature_blob (typelib, blob->signature, error)) return FALSE; return TRUE; } static gboolean -validate_callback_blob (GTypelib *metadata, +validate_callback_blob (GTypelib *typelib, guint32 offset, GError **error) { CallbackBlob *blob; - if (metadata->len < offset + sizeof (CallbackBlob)) + if (typelib->len < offset + sizeof (CallbackBlob)) { g_set_error (error, G_TYPELIB_ERROR, @@ -646,7 +646,7 @@ validate_callback_blob (GTypelib *metadata, return FALSE; } - blob = (CallbackBlob*) &metadata->data[offset]; + blob = (CallbackBlob*) &typelib->data[offset]; if (blob->blob_type != BLOB_TYPE_CALLBACK) { @@ -657,7 +657,7 @@ validate_callback_blob (GTypelib *metadata, return FALSE; } - if (!is_name (metadata->data, blob->name)) + if (!is_name (typelib->data, blob->name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -666,14 +666,14 @@ validate_callback_blob (GTypelib *metadata, return FALSE; } - if (!validate_signature_blob (metadata, blob->signature, error)) + if (!validate_signature_blob (typelib, blob->signature, error)) return FALSE; return TRUE; } static gboolean -validate_constant_blob (GTypelib *metadata, +validate_constant_blob (GTypelib *typelib, guint32 offset, GError **error) { @@ -688,7 +688,7 @@ validate_constant_blob (GTypelib *metadata, ConstantBlob *blob; SimpleTypeBlob *type; - if (metadata->len < offset + sizeof (ConstantBlob)) + if (typelib->len < offset + sizeof (ConstantBlob)) { g_set_error (error, G_TYPELIB_ERROR, @@ -697,7 +697,7 @@ validate_constant_blob (GTypelib *metadata, return FALSE; } - blob = (ConstantBlob*) &metadata->data[offset]; + blob = (ConstantBlob*) &typelib->data[offset]; if (blob->blob_type != BLOB_TYPE_CONSTANT) { @@ -708,7 +708,7 @@ validate_constant_blob (GTypelib *metadata, return FALSE; } - if (!is_name (metadata->data, blob->name)) + if (!is_name (typelib->data, blob->name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -717,7 +717,7 @@ validate_constant_blob (GTypelib *metadata, return FALSE; } - if (!validate_type_blob (metadata, offset + G_STRUCT_OFFSET (ConstantBlob, type), + if (!validate_type_blob (typelib, offset + G_STRUCT_OFFSET (ConstantBlob, type), 0, FALSE, error)) return FALSE; @@ -730,7 +730,7 @@ validate_constant_blob (GTypelib *metadata, return FALSE; } - type = (SimpleTypeBlob *)&metadata->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)]; + type = (SimpleTypeBlob *)&typelib->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)]; if (type->reserved == 0) { if (type->tag == 0) @@ -758,13 +758,13 @@ validate_constant_blob (GTypelib *metadata, } static gboolean -validate_value_blob (GTypelib *metadata, +validate_value_blob (GTypelib *typelib, guint32 offset, GError **error) { ValueBlob *blob; - if (metadata->len < offset + sizeof (ValueBlob)) + if (typelib->len < offset + sizeof (ValueBlob)) { g_set_error (error, G_TYPELIB_ERROR, @@ -773,9 +773,9 @@ validate_value_blob (GTypelib *metadata, return FALSE; } - blob = (ValueBlob*) &metadata->data[offset]; + blob = (ValueBlob*) &typelib->data[offset]; - if (!is_name (metadata->data, blob->name)) + if (!is_name (typelib->data, blob->name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -788,13 +788,13 @@ validate_value_blob (GTypelib *metadata, } static gboolean -validate_field_blob (GTypelib *metadata, +validate_field_blob (GTypelib *typelib, guint32 offset, GError **error) { FieldBlob *blob; - if (metadata->len < offset + sizeof (FieldBlob)) + if (typelib->len < offset + sizeof (FieldBlob)) { g_set_error (error, G_TYPELIB_ERROR, @@ -803,9 +803,9 @@ validate_field_blob (GTypelib *metadata, return FALSE; } - blob = (FieldBlob*) &metadata->data[offset]; + blob = (FieldBlob*) &typelib->data[offset]; - if (!is_name (metadata->data, blob->name)) + if (!is_name (typelib->data, blob->name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -814,7 +814,7 @@ validate_field_blob (GTypelib *metadata, return FALSE; } - if (!validate_type_blob (metadata, + if (!validate_type_blob (typelib, offset + G_STRUCT_OFFSET (FieldBlob, type), 0, FALSE, error)) return FALSE; @@ -823,13 +823,13 @@ validate_field_blob (GTypelib *metadata, } static gboolean -validate_property_blob (GTypelib *metadata, +validate_property_blob (GTypelib *typelib, guint32 offset, GError **error) { PropertyBlob *blob; - if (metadata->len < offset + sizeof (PropertyBlob)) + if (typelib->len < offset + sizeof (PropertyBlob)) { g_set_error (error, G_TYPELIB_ERROR, @@ -838,9 +838,9 @@ validate_property_blob (GTypelib *metadata, return FALSE; } - blob = (PropertyBlob*) &metadata->data[offset]; + blob = (PropertyBlob*) &typelib->data[offset]; - if (!is_name (metadata->data, blob->name)) + if (!is_name (typelib->data, blob->name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -849,7 +849,7 @@ validate_property_blob (GTypelib *metadata, return FALSE; } - if (!validate_type_blob (metadata, + if (!validate_type_blob (typelib, offset + G_STRUCT_OFFSET (PropertyBlob, type), 0, FALSE, error)) return FALSE; @@ -858,7 +858,7 @@ validate_property_blob (GTypelib *metadata, } static gboolean -validate_signal_blob (GTypelib *metadata, +validate_signal_blob (GTypelib *typelib, guint32 offset, guint32 container_offset, GError **error) @@ -866,7 +866,7 @@ validate_signal_blob (GTypelib *metadata, SignalBlob *blob; gint n_signals; - if (metadata->len < offset + sizeof (SignalBlob)) + if (typelib->len < offset + sizeof (SignalBlob)) { g_set_error (error, G_TYPELIB_ERROR, @@ -875,9 +875,9 @@ validate_signal_blob (GTypelib *metadata, return FALSE; } - blob = (SignalBlob*) &metadata->data[offset]; + blob = (SignalBlob*) &typelib->data[offset]; - if (!is_name (metadata->data, blob->name)) + if (!is_name (typelib->data, blob->name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -899,11 +899,11 @@ validate_signal_blob (GTypelib *metadata, if (blob->has_class_closure) { - if (((CommonBlob*)&metadata->data[container_offset])->blob_type == BLOB_TYPE_OBJECT) + if (((CommonBlob*)&typelib->data[container_offset])->blob_type == BLOB_TYPE_OBJECT) { ObjectBlob *object; - object = (ObjectBlob*)&metadata->data[container_offset]; + object = (ObjectBlob*)&typelib->data[container_offset]; n_signals = object->n_signals; } @@ -911,7 +911,7 @@ validate_signal_blob (GTypelib *metadata, { InterfaceBlob *iface; - iface = (InterfaceBlob*)&metadata->data[container_offset]; + iface = (InterfaceBlob*)&typelib->data[container_offset]; n_signals = iface->n_signals; } @@ -926,14 +926,14 @@ validate_signal_blob (GTypelib *metadata, } } - if (!validate_signature_blob (metadata, blob->signature, error)) + if (!validate_signature_blob (typelib, blob->signature, error)) return FALSE; return TRUE; } static gboolean -validate_vfunc_blob (GTypelib *metadata, +validate_vfunc_blob (GTypelib *typelib, guint32 offset, guint32 container_offset, GError **error) @@ -941,7 +941,7 @@ validate_vfunc_blob (GTypelib *metadata, VFuncBlob *blob; gint n_vfuncs; - if (metadata->len < offset + sizeof (VFuncBlob)) + if (typelib->len < offset + sizeof (VFuncBlob)) { g_set_error (error, G_TYPELIB_ERROR, @@ -950,9 +950,9 @@ validate_vfunc_blob (GTypelib *metadata, return FALSE; } - blob = (VFuncBlob*) &metadata->data[offset]; + blob = (VFuncBlob*) &typelib->data[offset]; - if (!is_name (metadata->data, blob->name)) + if (!is_name (typelib->data, blob->name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -963,11 +963,11 @@ validate_vfunc_blob (GTypelib *metadata, if (blob->class_closure) { - if (((CommonBlob*)&metadata->data[container_offset])->blob_type == BLOB_TYPE_OBJECT) + if (((CommonBlob*)&typelib->data[container_offset])->blob_type == BLOB_TYPE_OBJECT) { ObjectBlob *object; - object = (ObjectBlob*)&metadata->data[container_offset]; + object = (ObjectBlob*)&typelib->data[container_offset]; n_vfuncs = object->n_vfuncs; } @@ -975,7 +975,7 @@ validate_vfunc_blob (GTypelib *metadata, { InterfaceBlob *iface; - iface = (InterfaceBlob*)&metadata->data[container_offset]; + iface = (InterfaceBlob*)&typelib->data[container_offset]; n_vfuncs = iface->n_vfuncs; } @@ -990,14 +990,14 @@ validate_vfunc_blob (GTypelib *metadata, } } - if (!validate_signature_blob (metadata, blob->signature, error)) + if (!validate_signature_blob (typelib, blob->signature, error)) return FALSE; return TRUE; } static gboolean -validate_struct_blob (GTypelib *metadata, +validate_struct_blob (GTypelib *typelib, guint32 offset, guint16 blob_type, GError **error) @@ -1005,7 +1005,7 @@ validate_struct_blob (GTypelib *metadata, StructBlob *blob; gint i; - if (metadata->len < offset + sizeof (StructBlob)) + if (typelib->len < offset + sizeof (StructBlob)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1014,7 +1014,7 @@ validate_struct_blob (GTypelib *metadata, return FALSE; } - blob = (StructBlob*) &metadata->data[offset]; + blob = (StructBlob*) &typelib->data[offset]; if (blob->blob_type != blob_type) { @@ -1035,7 +1035,7 @@ validate_struct_blob (GTypelib *metadata, return FALSE; } - if (!is_name (metadata->data, blob->name)) + if (!is_name (typelib->data, blob->name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1046,7 +1046,7 @@ validate_struct_blob (GTypelib *metadata, if (blob_type == BLOB_TYPE_BOXED) { - if (!is_name (metadata->data, blob->gtype_name)) + if (!is_name (typelib->data, blob->gtype_name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1055,7 +1055,7 @@ validate_struct_blob (GTypelib *metadata, return FALSE; } - if (!is_name (metadata->data, blob->gtype_init)) + if (!is_name (typelib->data, blob->gtype_init)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1076,7 +1076,7 @@ validate_struct_blob (GTypelib *metadata, } } - if (metadata->len < offset + sizeof (StructBlob) + + if (typelib->len < offset + sizeof (StructBlob) + blob->n_fields * sizeof (FieldBlob) + blob->n_methods * sizeof (FunctionBlob)) { @@ -1089,7 +1089,7 @@ validate_struct_blob (GTypelib *metadata, for (i = 0; i < blob->n_fields; i++) { - if (!validate_field_blob (metadata, + if (!validate_field_blob (typelib, offset + sizeof (StructBlob) + i * sizeof (FieldBlob), error)) @@ -1098,7 +1098,7 @@ validate_struct_blob (GTypelib *metadata, for (i = 0; i < blob->n_methods; i++) { - if (!validate_function_blob (metadata, + if (!validate_function_blob (typelib, offset + sizeof (StructBlob) + blob->n_fields * sizeof (FieldBlob) + i * sizeof (FunctionBlob), @@ -1111,7 +1111,7 @@ validate_struct_blob (GTypelib *metadata, } static gboolean -validate_enum_blob (GTypelib *metadata, +validate_enum_blob (GTypelib *typelib, guint32 offset, guint16 blob_type, GError **error) @@ -1120,7 +1120,7 @@ validate_enum_blob (GTypelib *metadata, ValueBlob *v1, *v2; gint i, j; - if (metadata->len < offset + sizeof (EnumBlob)) + if (typelib->len < offset + sizeof (EnumBlob)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1129,7 +1129,7 @@ validate_enum_blob (GTypelib *metadata, return FALSE; } - blob = (EnumBlob*) &metadata->data[offset]; + blob = (EnumBlob*) &typelib->data[offset]; if (blob->blob_type != blob_type) { @@ -1142,7 +1142,7 @@ validate_enum_blob (GTypelib *metadata, if (!blob->unregistered) { - if (!is_name (metadata->data, blob->gtype_name)) + if (!is_name (typelib->data, blob->gtype_name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1151,7 +1151,7 @@ validate_enum_blob (GTypelib *metadata, return FALSE; } - if (!is_name (metadata->data, blob->gtype_init)) + if (!is_name (typelib->data, blob->gtype_init)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1172,7 +1172,7 @@ validate_enum_blob (GTypelib *metadata, } } - if (!is_name (metadata->data, blob->name)) + if (!is_name (typelib->data, blob->name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1181,7 +1181,7 @@ validate_enum_blob (GTypelib *metadata, return FALSE; } - if (metadata->len < offset + sizeof (EnumBlob) + + if (typelib->len < offset + sizeof (EnumBlob) + blob->n_values * sizeof (ValueBlob)) { g_set_error (error, @@ -1193,17 +1193,17 @@ validate_enum_blob (GTypelib *metadata, for (i = 0; i < blob->n_values; i++) { - if (!validate_value_blob (metadata, + if (!validate_value_blob (typelib, offset + sizeof (EnumBlob) + i * sizeof (ValueBlob), error)) return FALSE; - v1 = (ValueBlob *)&metadata->data[offset + sizeof (EnumBlob) + + v1 = (ValueBlob *)&typelib->data[offset + sizeof (EnumBlob) + i * sizeof (ValueBlob)]; for (j = 0; j < i; j++) { - v2 = (ValueBlob *)&metadata->data[offset + sizeof (EnumBlob) + + v2 = (ValueBlob *)&typelib->data[offset + sizeof (EnumBlob) + j * sizeof (ValueBlob)]; if (v1->value == v2->value) @@ -1222,7 +1222,7 @@ validate_enum_blob (GTypelib *metadata, } static gboolean -validate_object_blob (GTypelib *metadata, +validate_object_blob (GTypelib *typelib, guint32 offset, GError **error) { @@ -1231,9 +1231,9 @@ validate_object_blob (GTypelib *metadata, gint i; guint32 offset2; - header = (Header *)metadata->data; + header = (Header *)typelib->data; - if (metadata->len < offset + sizeof (ObjectBlob)) + if (typelib->len < offset + sizeof (ObjectBlob)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1242,7 +1242,7 @@ validate_object_blob (GTypelib *metadata, return FALSE; } - blob = (ObjectBlob*) &metadata->data[offset]; + blob = (ObjectBlob*) &typelib->data[offset]; if (blob->blob_type != BLOB_TYPE_OBJECT) { @@ -1253,7 +1253,7 @@ validate_object_blob (GTypelib *metadata, return FALSE; } - if (!is_name (metadata->data, blob->gtype_name)) + if (!is_name (typelib->data, blob->gtype_name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1262,7 +1262,7 @@ validate_object_blob (GTypelib *metadata, return FALSE; } - if (!is_name (metadata->data, blob->gtype_init)) + if (!is_name (typelib->data, blob->gtype_init)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1271,7 +1271,7 @@ validate_object_blob (GTypelib *metadata, return FALSE; } - if (!is_name (metadata->data, blob->name)) + if (!is_name (typelib->data, blob->name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1293,7 +1293,7 @@ validate_object_blob (GTypelib *metadata, { DirEntry *entry; - entry = g_typelib_get_dir_entry (metadata, blob->parent); + entry = g_typelib_get_dir_entry (typelib, blob->parent); if (entry->blob_type != BLOB_TYPE_OBJECT && (entry->local || entry->blob_type != 0)) { @@ -1305,7 +1305,7 @@ validate_object_blob (GTypelib *metadata, } } - if (metadata->len < offset + sizeof (ObjectBlob) + + if (typelib->len < offset + sizeof (ObjectBlob) + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + blob->n_fields * sizeof (FieldBlob) + blob->n_properties * sizeof (PropertyBlob) + @@ -1329,7 +1329,7 @@ validate_object_blob (GTypelib *metadata, guint16 iface; DirEntry *entry; - iface = *(guint16*)&metadata->data[offset2]; + iface = *(guint16*)&typelib->data[offset2]; if (iface == 0 || iface > header->n_entries) { g_set_error (error, @@ -1339,7 +1339,7 @@ validate_object_blob (GTypelib *metadata, return FALSE; } - entry = g_typelib_get_dir_entry (metadata, iface); + entry = g_typelib_get_dir_entry (typelib, iface); if (entry->blob_type != BLOB_TYPE_INTERFACE && (entry->local || entry->blob_type != 0)) @@ -1356,37 +1356,37 @@ validate_object_blob (GTypelib *metadata, for (i = 0; i < blob->n_fields; i++, offset2 += sizeof (FieldBlob)) { - if (!validate_field_blob (metadata, offset2, error)) + if (!validate_field_blob (typelib, offset2, error)) return FALSE; } for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob)) { - if (!validate_property_blob (metadata, offset2, error)) + if (!validate_property_blob (typelib, offset2, error)) return FALSE; } for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob)) { - if (!validate_function_blob (metadata, offset2, BLOB_TYPE_OBJECT, error)) + if (!validate_function_blob (typelib, offset2, BLOB_TYPE_OBJECT, error)) return FALSE; } for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob)) { - if (!validate_signal_blob (metadata, offset2, offset, error)) + if (!validate_signal_blob (typelib, offset2, offset, error)) return FALSE; } for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob)) { - if (!validate_vfunc_blob (metadata, offset2, offset, error)) + if (!validate_vfunc_blob (typelib, offset2, offset, error)) return FALSE; } for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob)) { - if (!validate_constant_blob (metadata, offset2, error)) + if (!validate_constant_blob (typelib, offset2, error)) return FALSE; } @@ -1394,7 +1394,7 @@ validate_object_blob (GTypelib *metadata, } static gboolean -validate_interface_blob (GTypelib *metadata, +validate_interface_blob (GTypelib *typelib, guint32 offset, GError **error) { @@ -1403,9 +1403,9 @@ validate_interface_blob (GTypelib *metadata, gint i; guint32 offset2; - header = (Header *)metadata->data; + header = (Header *)typelib->data; - if (metadata->len < offset + sizeof (InterfaceBlob)) + if (typelib->len < offset + sizeof (InterfaceBlob)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1414,7 +1414,7 @@ validate_interface_blob (GTypelib *metadata, return FALSE; } - blob = (InterfaceBlob*) &metadata->data[offset]; + blob = (InterfaceBlob*) &typelib->data[offset]; if (blob->blob_type != BLOB_TYPE_INTERFACE) { @@ -1425,7 +1425,7 @@ validate_interface_blob (GTypelib *metadata, return FALSE; } - if (!is_name (metadata->data, blob->gtype_name)) + if (!is_name (typelib->data, blob->gtype_name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1434,7 +1434,7 @@ validate_interface_blob (GTypelib *metadata, return FALSE; } - if (!is_name (metadata->data, blob->gtype_init)) + if (!is_name (typelib->data, blob->gtype_init)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1443,7 +1443,7 @@ validate_interface_blob (GTypelib *metadata, return FALSE; } - if (!is_name (metadata->data, blob->name)) + if (!is_name (typelib->data, blob->name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1452,7 +1452,7 @@ validate_interface_blob (GTypelib *metadata, return FALSE; } - if (metadata->len < offset + sizeof (InterfaceBlob) + + if (typelib->len < offset + sizeof (InterfaceBlob) + (blob->n_prerequisites + blob->n_prerequisites % 2) * 2 + blob->n_properties * sizeof (PropertyBlob) + blob->n_methods * sizeof (FunctionBlob) + @@ -1475,7 +1475,7 @@ validate_interface_blob (GTypelib *metadata, DirEntry *entry; guint16 req; - req = *(guint16*)&metadata->data[offset2]; + req = *(guint16*)&typelib->data[offset2]; if (req == 0 || req > header->n_entries) { g_set_error (error, @@ -1485,7 +1485,7 @@ validate_interface_blob (GTypelib *metadata, return FALSE; } - entry = g_typelib_get_dir_entry (metadata, req); + entry = g_typelib_get_dir_entry (typelib, req); if (entry->blob_type != BLOB_TYPE_INTERFACE && entry->blob_type != BLOB_TYPE_OBJECT && (entry->local || entry->blob_type != 0)) @@ -1502,31 +1502,31 @@ validate_interface_blob (GTypelib *metadata, for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob)) { - if (!validate_property_blob (metadata, offset2, error)) + if (!validate_property_blob (typelib, offset2, error)) return FALSE; } for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob)) { - if (!validate_function_blob (metadata, offset2, BLOB_TYPE_INTERFACE, error)) + if (!validate_function_blob (typelib, offset2, BLOB_TYPE_INTERFACE, error)) return FALSE; } for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob)) { - if (!validate_signal_blob (metadata, offset2, offset, error)) + if (!validate_signal_blob (typelib, offset2, offset, error)) return FALSE; } for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob)) { - if (!validate_vfunc_blob (metadata, offset2, offset, error)) + if (!validate_vfunc_blob (typelib, offset2, offset, error)) return FALSE; } for (i = 0; i < blob->n_constants; i++, offset2 += sizeof (ConstantBlob)) { - if (!validate_constant_blob (metadata, offset2, error)) + if (!validate_constant_blob (typelib, offset2, error)) return FALSE; } @@ -1534,7 +1534,7 @@ validate_interface_blob (GTypelib *metadata, } static gboolean -validate_errordomain_blob (GTypelib *metadata, +validate_errordomain_blob (GTypelib *typelib, guint32 offset, GError **error) { @@ -1542,7 +1542,7 @@ validate_errordomain_blob (GTypelib *metadata, } static gboolean -validate_union_blob (GTypelib *metadata, +validate_union_blob (GTypelib *typelib, guint32 offset, GError **error) { @@ -1550,13 +1550,13 @@ validate_union_blob (GTypelib *metadata, } static gboolean -validate_blob (GTypelib *metadata, +validate_blob (GTypelib *typelib, guint32 offset, GError **error) { CommonBlob *common; - if (metadata->len < offset + sizeof (CommonBlob)) + if (typelib->len < offset + sizeof (CommonBlob)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1565,46 +1565,46 @@ validate_blob (GTypelib *metadata, return FALSE; } - common = (CommonBlob*)&metadata->data[offset]; + common = (CommonBlob*)&typelib->data[offset]; switch (common->blob_type) { case BLOB_TYPE_FUNCTION: - if (!validate_function_blob (metadata, offset, 0, error)) + if (!validate_function_blob (typelib, offset, 0, error)) return FALSE; break; case BLOB_TYPE_CALLBACK: - if (!validate_callback_blob (metadata, offset, error)) + if (!validate_callback_blob (typelib, offset, error)) return FALSE; break; case BLOB_TYPE_STRUCT: case BLOB_TYPE_BOXED: - if (!validate_struct_blob (metadata, offset, common->blob_type, error)) + if (!validate_struct_blob (typelib, offset, common->blob_type, error)) return FALSE; break; case BLOB_TYPE_ENUM: case BLOB_TYPE_FLAGS: - if (!validate_enum_blob (metadata, offset, common->blob_type, error)) + if (!validate_enum_blob (typelib, offset, common->blob_type, error)) return FALSE; break; case BLOB_TYPE_OBJECT: - if (!validate_object_blob (metadata, offset, error)) + if (!validate_object_blob (typelib, offset, error)) return FALSE; break; case BLOB_TYPE_INTERFACE: - if (!validate_interface_blob (metadata, offset, error)) + if (!validate_interface_blob (typelib, offset, error)) return FALSE; break; case BLOB_TYPE_CONSTANT: - if (!validate_constant_blob (metadata, offset, error)) + if (!validate_constant_blob (typelib, offset, error)) return FALSE; break; case BLOB_TYPE_ERROR_DOMAIN: - if (!validate_errordomain_blob (metadata, offset, error)) + if (!validate_errordomain_blob (typelib, offset, error)) return FALSE; break; case BLOB_TYPE_UNION: - if (!validate_union_blob (metadata, offset, error)) + if (!validate_union_blob (typelib, offset, error)) return FALSE; break; default: @@ -1619,14 +1619,14 @@ validate_blob (GTypelib *metadata, } static gboolean -validate_directory (GTypelib *metadata, +validate_directory (GTypelib *typelib, GError **error) { - Header *header = (Header *)metadata->data; + Header *header = (Header *)typelib->data; DirEntry *entry; gint i; - if (metadata->len < header->directory + header->n_entries * sizeof (DirEntry)) + if (typelib->len < header->directory + header->n_entries * sizeof (DirEntry)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1637,9 +1637,9 @@ validate_directory (GTypelib *metadata, for (i = 0; i < header->n_entries; i++) { - entry = g_typelib_get_dir_entry (metadata, i + 1); + entry = g_typelib_get_dir_entry (typelib, i + 1); - if (!is_name (metadata->data, entry->name)) + if (!is_name (typelib->data, entry->name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1678,7 +1678,7 @@ validate_directory (GTypelib *metadata, return FALSE; } - if (!validate_blob (metadata, entry->offset, error)) + if (!validate_blob (typelib, entry->offset, error)) return FALSE; } else @@ -1692,7 +1692,7 @@ validate_directory (GTypelib *metadata, return FALSE; } - if (!is_name (metadata->data, entry->offset)) + if (!is_name (typelib->data, entry->offset)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1707,10 +1707,10 @@ validate_directory (GTypelib *metadata, } static gboolean -validate_annotations (GTypelib *metadata, +validate_annotations (GTypelib *typelib, GError **error) { - Header *header = (Header *)metadata->data; + Header *header = (Header *)typelib->data; if (header->size < header->annotations + header->n_annotations * sizeof (AnnotationBlob)) { @@ -1725,16 +1725,16 @@ validate_annotations (GTypelib *metadata, } gboolean -g_typelib_validate (GTypelib *metadata, +g_typelib_validate (GTypelib *typelib, GError **error) { - if (!validate_header (metadata, error)) + if (!validate_header (typelib, error)) return FALSE; - if (!validate_directory (metadata, error)) + if (!validate_directory (typelib, error)) return FALSE; - if (!validate_annotations (metadata, error)) + if (!validate_annotations (typelib, error)) return FALSE; return TRUE; @@ -1745,38 +1745,38 @@ g_typelib_error_quark (void) { static GQuark quark = 0; if (quark == 0) - quark = g_quark_from_static_string ("g-metadata-error-quark"); + quark = g_quark_from_static_string ("g-typelib-error-quark"); return quark; } static const char* -find_some_symbol (GTypelib *metadata) +find_some_symbol (GTypelib *typelib) { - Header *header = (Header *) metadata->data; + Header *header = (Header *) typelib->data; gint i; for (i = 0; i < header->n_entries; i++) { DirEntry *entry; - entry = g_typelib_get_dir_entry (metadata, i + 1); + entry = g_typelib_get_dir_entry (typelib, i + 1); switch (entry->blob_type) { case BLOB_TYPE_FUNCTION: { - FunctionBlob *blob = (FunctionBlob *) &metadata->data[entry->offset]; + FunctionBlob *blob = (FunctionBlob *) &typelib->data[entry->offset]; if (blob->symbol) - return g_typelib_get_string (metadata, blob->symbol); + return g_typelib_get_string (typelib, blob->symbol); } break; case BLOB_TYPE_OBJECT: { - RegisteredTypeBlob *blob = (RegisteredTypeBlob *) &metadata->data[entry->offset]; + RegisteredTypeBlob *blob = (RegisteredTypeBlob *) &typelib->data[entry->offset]; if (blob->gtype_init) - return g_typelib_get_string (metadata, blob->gtype_init); + return g_typelib_get_string (typelib, blob->gtype_init); } break; default: @@ -1788,16 +1788,16 @@ find_some_symbol (GTypelib *metadata) } static inline void -_g_typelib_init (GTypelib *metadata) +_g_typelib_init (GTypelib *typelib) { Header *header; - header = (Header *) metadata->data; + header = (Header *) typelib->data; if (header->shared_library) { const gchar *shlib; - shlib = g_typelib_get_string (metadata, header->shared_library); + shlib = g_typelib_get_string (typelib, header->shared_library); /* note that NULL shlib means to open the main app, which is allowed */ /* If we do have a shared lib, first be sure the main app isn't already linked to it */ @@ -1805,11 +1805,11 @@ _g_typelib_init (GTypelib *metadata) { const char *symbol_in_module; - symbol_in_module = find_some_symbol (metadata); + symbol_in_module = find_some_symbol (typelib); if (symbol_in_module != NULL) { - metadata->module = g_module_open (NULL, G_MODULE_BIND_LAZY); - if (metadata->module == NULL) + typelib->module = g_module_open (NULL, G_MODULE_BIND_LAZY); + if (typelib->module == NULL) { g_warning ("Could not open main app as GModule: %s", g_module_error ()); @@ -1817,21 +1817,21 @@ _g_typelib_init (GTypelib *metadata) else { void *sym; - if (!g_module_symbol (metadata->module, symbol_in_module, &sym)) + if (!g_module_symbol (typelib->module, symbol_in_module, &sym)) { /* we will try opening the shlib, symbol is not in app already */ - g_module_close (metadata->module); - metadata->module = NULL; + g_module_close (typelib->module); + typelib->module = NULL; } } } else { - g_warning ("Could not find any symbols in metadata"); + g_warning ("Could not find any symbols in typelib"); } } - if (metadata->module == NULL) + if (typelib->module == NULL) { /* Glade's autoconnect feature and OpenGL's extension mechanism * as used by Clutter rely on dlopen(NULL) to work as a means of @@ -1842,9 +1842,9 @@ _g_typelib_init (GTypelib *metadata) * load modules globally for now. */ - metadata->module = g_module_open (shlib, G_MODULE_BIND_LAZY); - if (metadata->module == NULL) - g_warning ("Failed to load shared library referenced by the metadata: %s", + typelib->module = g_module_open (shlib, G_MODULE_BIND_LAZY); + if (typelib->module == NULL) + g_warning ("Failed to load shared library referenced by the typelib: %s", g_module_error ()); } } @@ -1852,11 +1852,11 @@ _g_typelib_init (GTypelib *metadata) /** * g_typelib_new_from_memory: - * @memory: address of memory chunk containing the metadata - * @len: length of memory chunk containing the metadata + * @memory: address of memory chunk containing the typelib + * @len: length of memory chunk containing the typelib * * Creates a new #GTypelib from a memory location. The memory block - * pointed to by @metadata will be automatically g_free()d when the + * pointed to by @typelib will be automatically g_free()d when the * repository is destroyed. * * Return value: the new #GTypelib @@ -1876,8 +1876,8 @@ g_typelib_new_from_memory (guchar *memory, gsize len) /** * g_typelib_new_from_const_memory: - * @memory: address of memory chunk containing the metadata - * @len: length of memory chunk containing the metadata + * @memory: address of memory chunk containing the typelib + * @len: length of memory chunk containing the typelib * * Creates a new #GTypelib from a memory location. * @@ -1920,40 +1920,40 @@ g_typelib_new_from_mapped_file (GMappedFile *mfile) /** * g_typelib_free: - * @metadata: a #GTypelib + * @typelib: a #GTypelib * * Free a #GTypelib. **/ void -g_typelib_free (GTypelib *metadata) +g_typelib_free (GTypelib *typelib) { - if (metadata->mfile) - g_mapped_file_free (metadata->mfile); + if (typelib->mfile) + g_mapped_file_free (typelib->mfile); else - if (metadata->owns_memory) - g_free (metadata->data); - if (metadata->module) - g_module_close (metadata->module); - g_free (metadata); + if (typelib->owns_memory) + g_free (typelib->data); + if (typelib->module) + g_module_close (typelib->module); + g_free (typelib); } /** * g_typelib_set_module: - * @metadata: a #GTypelib instance + * @typelib: a #GTypelib instance * @module: a #GModule; takes ownership of this module * - * Sets the target module for all symbols referenced by the metadata. + * Sets the target module for all symbols referenced by the typelib. **/ void -g_typelib_set_module (GTypelib *metadata, GModule *module) +g_typelib_set_module (GTypelib *typelib, GModule *module) { - if (metadata->module) - g_module_close (metadata->module); - metadata->module = module; + if (typelib->module) + g_module_close (typelib->module); + typelib->module = module; } const gchar * -g_typelib_get_namespace(GTypelib *metadata) +g_typelib_get_namespace(GTypelib *typelib) { - return g_typelib_get_string (metadata, ((Header *) metadata->data)->namespace); + return g_typelib_get_string (typelib, ((Header *) typelib->data)->namespace); } diff --git a/gtypelib.h b/gtypelib.h index 0152a958d..cbaaa4f11 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -1,5 +1,5 @@ /* GObject introspection: struct definitions for the binary - * metadata format, validation + * typelib format, validation * * Copyright (C) 2005 Matthias Clasen * @@ -521,12 +521,12 @@ struct _GTypelib { GModule *module; }; -DirEntry *g_typelib_get_dir_entry (GTypelib *metadata, - guint16 index); +DirEntry *g_typelib_get_dir_entry (GTypelib *typelib, + guint16 index); void g_typelib_check_sanity (void); -#define g_typelib_get_string(metadata,offset) ((const gchar*)&(metadata->data)[(offset)]) +#define g_typelib_get_string(typelib,offset) ((const gchar*)&(typelib->data)[(offset)]) typedef enum @@ -542,8 +542,8 @@ typedef enum GQuark g_typelib_error_quark (void); -gboolean g_typelib_validate (GTypelib *metadata, - GError **error); +gboolean g_typelib_validate (GTypelib *typelib, + GError **error); G_END_DECLS From 0ed07b593405fac7e407293ecb6de3aad8203709 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 12 Aug 2008 15:34:27 +0000 Subject: [PATCH 024/692] Remove usage of (GAPI-oriented) TypeTag in favor of GITypeTag from 2008-08-12 Colin Walters * girepository/girparser.c, girepository/gtypelib.c, girepository/gtypelib.h, girepository/girnode.c: Remove usage of (GAPI-oriented) TypeTag in favor of GITypeTag from girepository.h. svn path=/trunk/; revision=347 --- girnode.c | 72 +++++++++++++++---------------- girparser.c | 121 +++++++++++++++++++++++++++------------------------- gtypelib.c | 16 +++---- gtypelib.h | 36 ---------------- 4 files changed, 106 insertions(+), 139 deletions(-) diff --git a/girnode.c b/girnode.c index 7734bf968..2aeba30e0 100644 --- a/girnode.c +++ b/girnode.c @@ -650,7 +650,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node) case G_IR_NODE_TYPE: { GIrNodeType *type = (GIrNodeType *)node; - if (type->tag < TYPE_TAG_ARRAY) + if (type->tag < GI_TYPE_TAG_ARRAY) size = 4; else { @@ -659,28 +659,28 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node) switch (type->tag) { - case TYPE_TAG_ARRAY: + case GI_TYPE_TAG_ARRAY: size = 4 + 4; if (type->parameter_type1) size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1); break; - case TYPE_TAG_INTERFACE: + case GI_TYPE_TAG_INTERFACE: size = 4 + 4; break; - case TYPE_TAG_LIST: - case TYPE_TAG_SLIST: + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: size = 4 + 4; if (type->parameter_type1) size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1); break; - case TYPE_TAG_HASH: + case GI_TYPE_TAG_GHASH: size = 4 + 4 + 4; if (type->parameter_type1) size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1); if (type->parameter_type2) size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type2); break; - case TYPE_TAG_ERROR: + case GI_TYPE_TAG_ERROR: { gint n; @@ -1224,7 +1224,8 @@ g_ir_node_build_typelib (GIrNode *node, g_assert (node != NULL); - g_debug ("build_typelib (%s)", + g_debug ("build_typelib: %s (%s)", + node->name, g_ir_node_type_to_string (node->type)); switch (node->type) @@ -1236,9 +1237,8 @@ g_ir_node_build_typelib (GIrNode *node, *offset += 4; - if (type->tag < TYPE_TAG_ARRAY || - type->tag == TYPE_TAG_STRING || - type->tag == TYPE_TAG_ANY) + if (type->tag < GI_TYPE_TAG_ARRAY || + type->tag == GI_TYPE_TAG_UTF8) { blob->reserved = 0; blob->reserved2 = 0; @@ -1271,7 +1271,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->offset = *offset2; switch (type->tag) { - case TYPE_TAG_ARRAY: + case GI_TYPE_TAG_ARRAY: { ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2]; guint32 pos; @@ -1293,7 +1293,7 @@ g_ir_node_build_typelib (GIrNode *node, } break; - case TYPE_TAG_INTERFACE: + case GI_TYPE_TAG_INTERFACE: { InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2]; *offset2 += 4; @@ -1307,8 +1307,8 @@ g_ir_node_build_typelib (GIrNode *node, } break; - case TYPE_TAG_LIST: - case TYPE_TAG_SLIST: + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: { ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2]; guint32 pos; @@ -1328,7 +1328,7 @@ g_ir_node_build_typelib (GIrNode *node, } break; - case TYPE_TAG_HASH: + case GI_TYPE_TAG_GHASH: { ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2]; guint32 pos; @@ -1351,7 +1351,7 @@ g_ir_node_build_typelib (GIrNode *node, } break; - case TYPE_TAG_ERROR: + case GI_TYPE_TAG_ERROR: { ErrorTypeBlob *blob = (ErrorTypeBlob *)&data[*offset2]; gint i; @@ -2095,70 +2095,70 @@ g_ir_node_build_typelib (GIrNode *node, blob->offset = *offset2; switch (constant->type->tag) { - case TYPE_TAG_BOOLEAN: + case GI_TYPE_TAG_BOOLEAN: blob->size = 4; *(gboolean*)&data[blob->offset] = parse_boolean_value (constant->value); break; - case TYPE_TAG_INT8: + case GI_TYPE_TAG_INT8: blob->size = 1; *(gint8*)&data[blob->offset] = (gint8) parse_int_value (constant->value); break; - case TYPE_TAG_UINT8: + case GI_TYPE_TAG_UINT8: blob->size = 1; *(guint8*)&data[blob->offset] = (guint8) parse_uint_value (constant->value); break; - case TYPE_TAG_INT16: + case GI_TYPE_TAG_INT16: blob->size = 2; *(gint16*)&data[blob->offset] = (gint16) parse_int_value (constant->value); break; - case TYPE_TAG_UINT16: + case GI_TYPE_TAG_UINT16: blob->size = 2; *(guint16*)&data[blob->offset] = (guint16) parse_uint_value (constant->value); break; - case TYPE_TAG_INT32: + case GI_TYPE_TAG_INT32: blob->size = 4; *(gint32*)&data[blob->offset] = (gint32) parse_int_value (constant->value); break; - case TYPE_TAG_UINT32: + case GI_TYPE_TAG_UINT32: blob->size = 4; *(guint32*)&data[blob->offset] = (guint32) parse_uint_value (constant->value); break; - case TYPE_TAG_INT64: + case GI_TYPE_TAG_INT64: blob->size = 8; *(gint64*)&data[blob->offset] = (gint64) parse_int_value (constant->value); break; - case TYPE_TAG_UINT64: + case GI_TYPE_TAG_UINT64: blob->size = 8; *(guint64*)&data[blob->offset] = (guint64) parse_uint_value (constant->value); break; - case TYPE_TAG_INT: + case GI_TYPE_TAG_INT: blob->size = sizeof (gint); *(gint*)&data[blob->offset] = (gint) parse_int_value (constant->value); break; - case TYPE_TAG_UINT: + case GI_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: + case GI_TYPE_TAG_SSIZE: /* FIXME */ + case GI_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: + case GI_TYPE_TAG_SIZE: /* FIXME */ + case GI_TYPE_TAG_ULONG: blob->size = sizeof (gulong); *(gulong*)&data[blob->offset] = (gulong) parse_uint_value (constant->value); break; - case TYPE_TAG_FLOAT: + case GI_TYPE_TAG_FLOAT: blob->size = sizeof (gfloat); *(gfloat*)&data[blob->offset] = (gfloat) parse_float_value (constant->value); break; - case TYPE_TAG_DOUBLE: + case GI_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: + case GI_TYPE_TAG_UTF8: + case GI_TYPE_TAG_FILENAME: blob->size = strlen (constant->value) + 1; memcpy (&data[blob->offset], constant->value, blob->size); break; diff --git a/girparser.c b/girparser.c index 565542c4e..3649c72fd 100644 --- a/girparser.c +++ b/girparser.c @@ -133,59 +133,60 @@ parse_type_internal (gchar *str, gchar **rest) gint tag; gboolean pointer; } basic[] = { - { "void", TYPE_TAG_VOID, 0 }, - { "gpointer", TYPE_TAG_VOID, 1 }, - { "bool", TYPE_TAG_BOOLEAN, 0 }, - { "gboolean", TYPE_TAG_BOOLEAN, 0 }, -#if 0 - { "char", TYPE_TAG_INT8, 0 }, - { "gchar", TYPE_TAG_INT8, 0 }, - { "guchar", TYPE_TAG_UINT8, 0 }, -#endif - { "int8_t", TYPE_TAG_INT8, 0 }, - { "int8", TYPE_TAG_INT8, 0 }, - { "gint8", TYPE_TAG_INT8, 0 }, - { "uint8_t", TYPE_TAG_UINT8, 0 }, - { "uint8", TYPE_TAG_UINT8, 0 }, - { "guint8", TYPE_TAG_UINT8, 0 }, - { "int16_t", TYPE_TAG_INT16, 0 }, - { "int16", TYPE_TAG_INT16, 0 }, - { "gint16", TYPE_TAG_INT16, 0 }, - { "uint16_t", TYPE_TAG_UINT16, 0 }, - { "uint16", TYPE_TAG_UINT16, 0 }, - { "guint16", TYPE_TAG_UINT16, 0 }, - { "int32_t", TYPE_TAG_INT32, 0 }, - { "int32", TYPE_TAG_INT32, 0 }, - { "gint32", TYPE_TAG_INT32, 0 }, - { "uint32_t", TYPE_TAG_UINT32, 0 }, - { "uint32", TYPE_TAG_UINT32, 0 }, - { "guint32", TYPE_TAG_UINT32, 0 }, - { "int64_t", TYPE_TAG_INT64, 0 }, - { "int64", TYPE_TAG_INT64, 0 }, - { "gint64", TYPE_TAG_INT64, 0 }, - { "uint64_t", TYPE_TAG_UINT64, 0 }, - { "uint64", TYPE_TAG_UINT64, 0 }, - { "guint64", TYPE_TAG_UINT64, 0 }, - { "int", TYPE_TAG_INT, 0 }, - { "gint", TYPE_TAG_INT, 0 }, - { "uint", TYPE_TAG_UINT, 0 }, - { "guint", TYPE_TAG_UINT, 0 }, - { "long", TYPE_TAG_LONG, 0 }, - { "glong", TYPE_TAG_LONG, 0 }, - { "ulong", TYPE_TAG_ULONG, 0 }, - { "gulong", TYPE_TAG_ULONG, 0 }, - { "ssize_t", TYPE_TAG_SSIZE, 0 }, - { "gssize", TYPE_TAG_SSIZE, 0 }, - { "size_t", TYPE_TAG_SIZE, 0 }, - { "gsize", TYPE_TAG_SIZE, 0 }, - { "float", TYPE_TAG_FLOAT, 0 }, - { "gfloat", TYPE_TAG_FLOAT, 0 }, - { "double", TYPE_TAG_DOUBLE, 0 }, - { "gdouble", TYPE_TAG_DOUBLE, 0 }, - { "utf8", TYPE_TAG_UTF8, 1 }, - { "gchar*", TYPE_TAG_UTF8, 1 }, - { "filename", TYPE_TAG_FILENAME,1 }, - { "string", TYPE_TAG_STRING, 1 } + { "void", GI_TYPE_TAG_VOID, 0 }, + { "none", GI_TYPE_TAG_VOID, 0 }, + { "gpointer", GI_TYPE_TAG_VOID, 1 }, + { "bool", GI_TYPE_TAG_BOOLEAN, 0 }, + { "gboolean", GI_TYPE_TAG_BOOLEAN, 0 }, + { "char", GI_TYPE_TAG_INT8, 0 }, + { "gchar", GI_TYPE_TAG_INT8, 0 }, + { "guchar", GI_TYPE_TAG_UINT8, 0 }, + { "gunichar", GI_TYPE_TAG_UINT32, 0 }, + { "int8_t", GI_TYPE_TAG_INT8, 0 }, + { "int8", GI_TYPE_TAG_INT8, 0 }, + { "gint8", GI_TYPE_TAG_INT8, 0 }, + { "uint8_t", GI_TYPE_TAG_UINT8, 0 }, + { "uint8", GI_TYPE_TAG_UINT8, 0 }, + { "guint8", GI_TYPE_TAG_UINT8, 0 }, + { "int16_t", GI_TYPE_TAG_INT16, 0 }, + { "int16", GI_TYPE_TAG_INT16, 0 }, + { "gint16", GI_TYPE_TAG_INT16, 0 }, + { "uint16_t", GI_TYPE_TAG_UINT16, 0 }, + { "uint16", GI_TYPE_TAG_UINT16, 0 }, + { "guint16", GI_TYPE_TAG_UINT16, 0 }, + { "int32_t", GI_TYPE_TAG_INT32, 0 }, + { "int32", GI_TYPE_TAG_INT32, 0 }, + { "gint32", GI_TYPE_TAG_INT32, 0 }, + { "uint32_t", GI_TYPE_TAG_UINT32, 0 }, + { "uint32", GI_TYPE_TAG_UINT32, 0 }, + { "guint32", GI_TYPE_TAG_UINT32, 0 }, + { "int64_t", GI_TYPE_TAG_INT64, 0 }, + { "int64", GI_TYPE_TAG_INT64, 0 }, + { "gint64", GI_TYPE_TAG_INT64, 0 }, + { "uint64_t", GI_TYPE_TAG_UINT64, 0 }, + { "uint64", GI_TYPE_TAG_UINT64, 0 }, + { "guint64", GI_TYPE_TAG_UINT64, 0 }, + { "int", GI_TYPE_TAG_INT, 0 }, + { "gint", GI_TYPE_TAG_INT, 0 }, + { "uint", GI_TYPE_TAG_UINT, 0 }, + { "guint", GI_TYPE_TAG_UINT, 0 }, + { "long", GI_TYPE_TAG_LONG, 0 }, + { "glong", GI_TYPE_TAG_LONG, 0 }, + { "ulong", GI_TYPE_TAG_ULONG, 0 }, + { "gulong", GI_TYPE_TAG_ULONG, 0 }, + { "ssize_t", GI_TYPE_TAG_SSIZE, 0 }, + { "gssize", GI_TYPE_TAG_SSIZE, 0 }, + { "size_t", GI_TYPE_TAG_SIZE, 0 }, + { "gsize", GI_TYPE_TAG_SIZE, 0 }, + { "float", GI_TYPE_TAG_FLOAT, 0 }, + { "gfloat", GI_TYPE_TAG_FLOAT, 0 }, + { "double", GI_TYPE_TAG_DOUBLE, 0 }, + { "gdouble", GI_TYPE_TAG_DOUBLE, 0 }, + { "utf8", GI_TYPE_TAG_UTF8, 1 }, + { "gchar*", GI_TYPE_TAG_UTF8, 1 }, + { "filename", GI_TYPE_TAG_FILENAME,1 }, + // FIXME merge - do we still want this? + { "string", GI_TYPE_TAG_UTF8, 1 } }; gint n_basic = G_N_ELEMENTS (basic); @@ -227,14 +228,14 @@ parse_type_internal (gchar *str, gchar **rest) { if (g_str_has_prefix (*rest, "GList")) { - type->tag = TYPE_TAG_LIST; + type->tag = GI_TYPE_TAG_GLIST; type->is_glist = TRUE; type->is_pointer = TRUE; *rest += strlen ("GList"); } else { - type->tag = TYPE_TAG_SLIST; + type->tag = GI_TYPE_TAG_GSLIST; type->is_gslist = TRUE; type->is_pointer = TRUE; *rest += strlen ("GSList"); @@ -259,7 +260,7 @@ parse_type_internal (gchar *str, gchar **rest) } else if (g_str_has_prefix (*rest, "GHashTable")) { - type->tag = TYPE_TAG_HASH; + type->tag = GI_TYPE_TAG_GHASH; type->is_ghashtable = TRUE; type->is_pointer = TRUE; *rest += strlen ("GHashTable"); @@ -291,7 +292,7 @@ parse_type_internal (gchar *str, gchar **rest) } else if (g_str_has_prefix (*rest, "GError")) { - type->tag = TYPE_TAG_ERROR; + type->tag = GI_TYPE_TAG_ERROR; type->is_error = TRUE; type->is_pointer = TRUE; *rest += strlen ("GError"); @@ -312,7 +313,7 @@ parse_type_internal (gchar *str, gchar **rest) } else { - type->tag = TYPE_TAG_INTERFACE; + type->tag = GI_TYPE_TAG_INTERFACE; type->is_interface = TRUE; start = *rest; @@ -341,7 +342,7 @@ parse_type_internal (gchar *str, gchar **rest) array = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE); - array->tag = TYPE_TAG_ARRAY; + array->tag = GI_TYPE_TAG_ARRAY; array->is_pointer = TRUE; array->is_array = TRUE; @@ -385,6 +386,7 @@ parse_type_internal (gchar *str, gchar **rest) type = array; } + g_assert (type->tag >= 0 && type->tag <= GI_TYPE_TAG_ERROR); return type; error: @@ -625,6 +627,7 @@ start_parameter (GMarkupParseContext *context, param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM); ctx->current_typed = (GIrNode*) param; + ctx->current_typed->name = g_strdup (name); state_switch (ctx, STATE_FUNCTION_PARAMETER); diff --git a/gtypelib.c b/gtypelib.c index ca149f0d6..dd598447c 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -388,7 +388,7 @@ validate_type_blob (GTypelib *typelib, if (simple->reserved == 0 && simple->reserved2 == 0) { - if (simple->tag >= TYPE_TAG_ARRAY) + if (simple->tag >= GI_TYPE_TAG_ARRAY) { g_set_error (error, G_TYPELIB_ERROR, @@ -397,7 +397,7 @@ validate_type_blob (GTypelib *typelib, return FALSE; } - if (simple->tag >= TYPE_TAG_UTF8 && + if (simple->tag >= GI_TYPE_TAG_UTF8 && !simple->pointer) { g_set_error (error, @@ -414,28 +414,28 @@ validate_type_blob (GTypelib *typelib, switch (iface->tag) { - case TYPE_TAG_ARRAY: + case GI_TYPE_TAG_ARRAY: if (!validate_array_type_blob (typelib, simple->offset, signature_offset, return_type, error)) return FALSE; break; - case TYPE_TAG_INTERFACE: + case GI_TYPE_TAG_INTERFACE: if (!validate_iface_type_blob (typelib, simple->offset, signature_offset, return_type, error)) return FALSE; break; - case TYPE_TAG_LIST: - case TYPE_TAG_SLIST: + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: if (!validate_param_type_blob (typelib, simple->offset, signature_offset, return_type, 1, error)) return FALSE; break; - case TYPE_TAG_HASH: + case GI_TYPE_TAG_GHASH: if (!validate_param_type_blob (typelib, simple->offset, signature_offset, return_type, 2, error)) return FALSE; break; - case TYPE_TAG_ERROR: + case GI_TYPE_TAG_ERROR: if (!validate_error_type_blob (typelib, simple->offset, signature_offset, return_type, error)) return FALSE; diff --git a/gtypelib.h b/gtypelib.h index cbaaa4f11..68e026031 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -96,42 +96,6 @@ typedef struct } DirEntry; -#define TYPE_POINTER_MASK 1 << 7 -#define TYPE_TAG_MASK 63 - -typedef enum -{ - TYPE_TAG_VOID = 0, - TYPE_TAG_BOOLEAN = 1, - TYPE_TAG_INT8 = 2, - TYPE_TAG_UINT8 = 3, - TYPE_TAG_INT16 = 4, - TYPE_TAG_UINT16 = 5, - TYPE_TAG_INT32 = 6, - TYPE_TAG_UINT32 = 7, - TYPE_TAG_INT64 = 8, - TYPE_TAG_UINT64 = 9, - TYPE_TAG_INT = 10, - TYPE_TAG_UINT = 11, - TYPE_TAG_LONG = 12, - TYPE_TAG_ULONG = 13, - TYPE_TAG_SSIZE = 14, - TYPE_TAG_SIZE = 15, - TYPE_TAG_FLOAT = 16, - TYPE_TAG_DOUBLE = 17, - TYPE_TAG_UTF8 = 18, - TYPE_TAG_FILENAME = 19, - TYPE_TAG_ARRAY = 20, - TYPE_TAG_INTERFACE = 21, - TYPE_TAG_LIST = 22, - TYPE_TAG_SLIST = 23, - TYPE_TAG_HASH = 24, - TYPE_TAG_ERROR = 25, - TYPE_TAG_STRING = 26, - TYPE_TAG_SEQUENCE = 27, - TYPE_TAG_ANY = 28 -} TypeTag; - typedef union { struct From 8c6c262f22265ed8fa6d987f97121759864277b1 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 12 Aug 2008 18:49:16 +0000 Subject: [PATCH 025/692] Handle 'any'. Add test for void *. 2008-08-12 Colin Walters * girepository/girparser.c: Handle 'any'. * tests/scanner/Foo-expected.gir, tests/scanner/foo-object.h: Add test for void *. svn path=/trunk/; revision=351 --- girparser.c | 1 + 1 file changed, 1 insertion(+) diff --git a/girparser.c b/girparser.c index 3649c72fd..0bc8af391 100644 --- a/girparser.c +++ b/girparser.c @@ -135,6 +135,7 @@ parse_type_internal (gchar *str, gchar **rest) } basic[] = { { "void", GI_TYPE_TAG_VOID, 0 }, { "none", GI_TYPE_TAG_VOID, 0 }, + { "any", GI_TYPE_TAG_VOID, 1 }, { "gpointer", GI_TYPE_TAG_VOID, 1 }, { "bool", GI_TYPE_TAG_BOOLEAN, 0 }, { "gboolean", GI_TYPE_TAG_BOOLEAN, 0 }, From de7d01898e17d58afdbc1f7c184da2ad8f8a7efd Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 13 Aug 2008 16:10:09 +0000 Subject: [PATCH 026/692] Record typedefs as elements. Also attempt to look up types in 2008-08-12 Colin Walters * giscanner/transformer.py: Record typedefs as elements. Also attempt to look up types in external namespaces. * giscanner/girwriter.py: Write them. * giscanner/glibtransformer.py: Rework resolver using real instanceof checks. Resolve interface methods and properties. * tests/scanner/foo-object.h: Add a method with typedef. * tests/scanner/Foo-expected.gir: Update. * girepository/girnode.c: Debug tweaks. * girepository/girparser.c: Make a first pass through the XML where we record all the aliases. This lets us resolve them as we go through the second pass. * gir/Makefile.am: Don't install gobject-2.0.gir; we want that to come from gir-repository. svn path=/trunk/; revision=355 --- girnode.c | 6 +-- girparser.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 140 insertions(+), 10 deletions(-) diff --git a/girnode.c b/girnode.c index 2aeba30e0..7961da37f 100644 --- a/girnode.c +++ b/girnode.c @@ -880,7 +880,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node) size = 0; } - g_debug ("node %p type '%s' full size %d", node, + g_debug ("node '%s' %p type '%s' full size %d", node->name, node, g_ir_node_type_to_string (node->type), size); return size; @@ -2173,8 +2173,8 @@ g_ir_node_build_typelib (GIrNode *node, g_assert_not_reached (); } - g_debug ("node %p type '%s', offset %d -> %d, offset2 %d -> %d", - node, g_ir_node_type_to_string (node->type), + g_debug ("node '%s' %p type '%s', offset %d -> %d, offset2 %d -> %d", + node->name, node, g_ir_node_type_to_string (node->type), old_offset, *offset, old_offset2, *offset2); if (*offset2 - old_offset2 + *offset - old_offset > g_ir_node_get_full_size (node)) diff --git a/girparser.c b/girparser.c index 0bc8af391..2e875d7fa 100644 --- a/girparser.c +++ b/girparser.c @@ -53,7 +53,8 @@ typedef enum STATE_STRUCT_FIELD, STATE_ERRORDOMAIN, STATE_UNION, - STATE_CONSTANT + STATE_CONSTANT, + STATE_ALIAS, /* 25 */ } ParseState; typedef struct _ParseContext ParseContext; @@ -63,6 +64,7 @@ struct _ParseContext ParseState prev_state; GList *modules; + GHashTable *aliases; GIrModule *current_module; GIrNode *current_node; @@ -123,6 +125,18 @@ state_switch (ParseContext *ctx, ParseState newstate) ctx->state = newstate; } +static GIrNodeType * parse_type_internal (gchar *str, gchar **rest); + +static GIrNodeType * +create_pointer () +{ + char *pointer = g_strdup ("any"); + char *pointer_rest; + GIrNodeType *ret = parse_type_internal (pointer, &pointer_rest); + g_free (pointer); + return ret; +} + static GIrNodeType * parse_type_internal (gchar *str, gchar **rest) { @@ -258,6 +272,10 @@ parse_type_internal (gchar *str, gchar **rest) goto error; (*rest)++; } + else + { + type->parameter_type1 = create_pointer (); + } } else if (g_str_has_prefix (*rest, "GHashTable")) { @@ -290,6 +308,12 @@ parse_type_internal (gchar *str, gchar **rest) goto error; (*rest)++; } + else + { + type->parameter_type1 = create_pointer (); + type->parameter_type2 = create_pointer (); + } + } else if (g_str_has_prefix (*rest, "GError")) { @@ -396,13 +420,28 @@ parse_type_internal (gchar *str, gchar **rest) return NULL; } +static const char * +resolve_aliases (ParseContext *ctx, const gchar *type) +{ + gpointer orig; + gpointer value; + + while (g_hash_table_lookup_extended (ctx->aliases, type, &orig, &value)) + { + g_debug ("Resolved: %s => %s", type, value); + type = value; + } + return type; +} + static GIrNodeType * -parse_type (const gchar *type) +parse_type (ParseContext *ctx, const gchar *type) { gchar *str; gchar *rest; GIrNodeType *node; + type = resolve_aliases (ctx, type); str = g_strdup (type); node = parse_type_internal (str, &rest); g_free (str); @@ -848,6 +887,34 @@ start_field (GMarkupParseContext *context, return FALSE; } +static gboolean +start_alias (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + const gchar *name; + const gchar *target; + const gchar *type; + + name = find_attribute ("name", attribute_names, attribute_values); + if (name == NULL) { + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; + } + + target = find_attribute ("target", attribute_names, attribute_values); + if (name == NULL) { + MISSING_ATTRIBUTE (context, error, element_name, "target"); + return FALSE; + } + + g_hash_table_insert (ctx->aliases, g_strdup (name), g_strdup (target)); + return TRUE; +} + static gboolean start_enum (GMarkupParseContext *context, const gchar *element_name, @@ -1075,7 +1142,7 @@ start_constant (GMarkupParseContext *context, ((GIrNode *)constant)->name = g_strdup (name); constant->value = g_strdup (value); - constant->type = parse_type (type); + constant->type = parse_type (ctx, type); if (deprecated && strcmp (deprecated, "1") == 0) constant->deprecated = TRUE; @@ -1310,19 +1377,19 @@ start_type (GMarkupParseContext *context, { GIrNodeParam *param; param = (GIrNodeParam *)ctx->current_typed; - param->type = parse_type (name); + param->type = parse_type (ctx, name); } break; case G_IR_NODE_FIELD: { GIrNodeField *field = (GIrNodeField *)ctx->current_typed; - field->type = parse_type (name); + field->type = parse_type (ctx, name); } break; case G_IR_NODE_PROPERTY: { GIrNodeProperty *property = (GIrNodeProperty *) ctx->current_typed; - property->type = parse_type (name); + property->type = parse_type (ctx, name); } break; default: @@ -1661,7 +1728,7 @@ start_discriminator (GMarkupParseContext *context, MISSING_ATTRIBUTE (context, error, element_name, "offset"); { ((GIrNodeUnion *)ctx->current_node)->discriminator_type - = parse_type (type); + = parse_type (ctx, type); ((GIrNodeUnion *)ctx->current_node)->discriminator_offset = atoi (offset); } @@ -1705,6 +1772,13 @@ start_element_handler (GMarkupParseContext *context, switch (element_name[0]) { + case 'a': + if (ctx->state == STATE_NAMESPACE && strcmp (element_name, "alias") == 0) + { + state_switch (ctx, STATE_ALIAS); + goto out; + } + break; case 'b': if (start_enum (context, element_name, attribute_names, attribute_values, @@ -2047,6 +2121,13 @@ end_element_handler (GMarkupParseContext *context, } break; + case STATE_ALIAS: + if (require_end_element (context, "alias", element_name, error)) + { + state_switch (ctx, STATE_NAMESPACE); + } + break; + case STATE_FUNCTION_RETURN: if (strcmp ("type", element_name) == 0) break; @@ -2262,6 +2343,44 @@ cleanup (GMarkupParseContext *context, ctx->current_module = NULL; } +static void +firstpass_start_element_handler (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + ParseContext *ctx = user_data; + + if (strcmp (element_name, "alias") == 0) + { + start_alias (context, element_name, attribute_names, attribute_values, + ctx, error); + } +} + +static void +firstpass_end_element_handler (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + ParseContext *ctx = user_data; + +} + + +static GMarkupParser firstpass_parser = +{ + firstpass_start_element_handler, + firstpass_end_element_handler, + NULL, + NULL, + NULL, +}; + + static GMarkupParser parser = { start_element_handler, @@ -2280,6 +2399,15 @@ g_ir_parse_string (const gchar *buffer, GMarkupParseContext *context; ctx.state = STATE_START; + ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL); + + if (!g_markup_parse_context_parse (context, buffer, length, error)) + goto out; + + if (!g_markup_parse_context_end_parse (context, error)) + goto out; context = g_markup_parse_context_new (&parser, 0, &ctx, NULL); if (!g_markup_parse_context_parse (context, buffer, length, error)) @@ -2289,6 +2417,8 @@ g_ir_parse_string (const gchar *buffer, goto out; out: + + g_hash_table_destroy (ctx.aliases); g_markup_parse_context_free (context); From 3e28196a9861f096a1f93c1c3c122d814731b784 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Wed, 13 Aug 2008 21:44:38 +0000 Subject: [PATCH 027/692] Allow get_type to be None, set a get_type for GInitiallyUnowned too. 2008-08-13 Johan Dahlin * girepository/girnode.c (g_ir_node_get_full_size_internal): * girepository/girparser.c (start_class): * giscanner/glibtransformer.py: Allow get_type to be None, set a get_type for GInitiallyUnowned too. svn path=/trunk/; revision=362 --- girnode.c | 4 +++- girparser.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/girnode.c b/girnode.c index 7961da37f..3d01ef17e 100644 --- a/girnode.c +++ b/girnode.c @@ -710,7 +710,9 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node) 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); + if (iface->gtype_init) + size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4); + size += ALIGN_VALUE ( + 1, 4); size += 2 * (n + (n % 2)); for (l = iface->members; l; l = l->next) diff --git a/girparser.c b/girparser.c index 2e875d7fa..209c2d4d0 100644 --- a/girparser.c +++ b/girparser.c @@ -1304,7 +1304,7 @@ start_class (GMarkupParseContext *context, MISSING_ATTRIBUTE (context, error, element_name, "name"); else if (typename == NULL) MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); - else if (typeinit == NULL) + else if (typeinit == NULL && strcmp (typename, "GObject")) MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); else { From c368516ae4ade22ea339df7e52312d9a3280c938 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 14 Aug 2008 16:09:06 +0000 Subject: [PATCH 028/692] Comment data structures. Also squash pointers in resolve_type_name to 2008-08-14 Colin Walters * giscanner/transformer.py: Comment data structures. Also squash pointers in resolve_type_name to correspond with what we do for params. * giscanner/glibtransformer.py: Print warnings in more situations. Rework checks for method/constructor to look up in our GType database instead of just checking for *. Avoid generating for GObject which duplicate the . * gir/Makefile.am: Generate glib-2.0.gir and gobject-2.0.gir in here. svn path=/trunk/; revision=373 --- girparser.c | 60 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/girparser.c b/girparser.c index 209c2d4d0..dfc704270 100644 --- a/girparser.c +++ b/girparser.c @@ -121,6 +121,7 @@ find_attribute (const gchar *name, static void state_switch (ParseContext *ctx, ParseState newstate) { + g_debug ("State: %d", newstate); ctx->prev_state = ctx->state; ctx->state = newstate; } @@ -1350,6 +1351,7 @@ start_type (GMarkupParseContext *context, ctx->state == STATE_CLASS_PROPERTY || ctx->state == STATE_CLASS_FIELD || ctx->state == STATE_INTERFACE_FIELD || + ctx->state == STATE_INTERFACE_PROPERTY || ctx->state == STATE_BOXED_FIELD )) return FALSE; @@ -2031,9 +2033,9 @@ start_element_handler (GMarkupParseContext *context, g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, - "Unexpected start tag '%s' on line %d char %d", + "Unexpected start tag '%s' on line %d char %d; current state=%d", element_name, - line_number, char_number); + line_number, char_number, ctx->state); out: ; if (*error) @@ -2047,6 +2049,7 @@ start_element_handler (GMarkupParseContext *context, static gboolean require_one_of_end_elements (GMarkupParseContext *context, + ParseContext *ctx, const char *actual_name, GError **error, ...) @@ -2076,20 +2079,21 @@ require_one_of_end_elements (GMarkupParseContext *context, g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, - "Unexpected end tag '%s' on line %d char %d", + "Unexpected end tag '%s' on line %d char %d; current state=%d", actual_name, - line_number, char_number); + line_number, char_number, ctx->state); backtrace_stderr(); return FALSE; } static gboolean require_end_element (GMarkupParseContext *context, + ParseContext *ctx, const char *expected_name, const char *actual_name, GError **error) { - return require_one_of_end_elements (context, actual_name, error, expected_name, NULL); + return require_one_of_end_elements (context, ctx, actual_name, error, expected_name, NULL); } static void @@ -2114,7 +2118,7 @@ end_element_handler (GMarkupParseContext *context, break; case STATE_NAMESPACE: - if (require_end_element (context, "namespace", element_name, error)) + if (require_end_element (context, ctx, "namespace", element_name, error)) { ctx->current_module = NULL; state_switch (ctx, STATE_REPOSITORY); @@ -2122,7 +2126,7 @@ end_element_handler (GMarkupParseContext *context, break; case STATE_ALIAS: - if (require_end_element (context, "alias", element_name, error)) + if (require_end_element (context, ctx, "alias", element_name, error)) { state_switch (ctx, STATE_NAMESPACE); } @@ -2131,14 +2135,14 @@ end_element_handler (GMarkupParseContext *context, case STATE_FUNCTION_RETURN: if (strcmp ("type", element_name) == 0) break; - if (require_end_element (context, "return-value", element_name, error)) + if (require_end_element (context, ctx, "return-value", element_name, error)) { state_switch (ctx, STATE_FUNCTION); } break; case STATE_FUNCTION_PARAMETERS: - if (require_end_element (context, "parameters", element_name, error)) + if (require_end_element (context, ctx, "parameters", element_name, error)) { state_switch (ctx, STATE_FUNCTION); } @@ -2147,7 +2151,7 @@ end_element_handler (GMarkupParseContext *context, case STATE_FUNCTION_PARAMETER: if (strcmp ("type", element_name) == 0) break; - if (require_end_element (context, "parameter", element_name, error)) + if (require_end_element (context, ctx, "parameter", element_name, error)) { state_switch (ctx, STATE_FUNCTION_PARAMETERS); } @@ -2189,7 +2193,7 @@ end_element_handler (GMarkupParseContext *context, case STATE_CLASS_FIELD: if (strcmp ("type", element_name) == 0) break; - if (require_end_element (context, "field", element_name, error)) + if (require_end_element (context, ctx, "field", element_name, error)) { state_switch (ctx, STATE_CLASS); } @@ -2198,14 +2202,14 @@ end_element_handler (GMarkupParseContext *context, case STATE_CLASS_PROPERTY: if (strcmp ("type", element_name) == 0) break; - if (require_end_element (context, "property", element_name, error)) + if (require_end_element (context, ctx, "property", element_name, error)) { state_switch (ctx, STATE_CLASS); } break; case STATE_CLASS: - if (require_end_element (context, "class", element_name, error)) + if (require_end_element (context, ctx, "class", element_name, error)) { ctx->current_node = NULL; state_switch (ctx, STATE_NAMESPACE); @@ -2213,7 +2217,7 @@ end_element_handler (GMarkupParseContext *context, break; case STATE_ERRORDOMAIN: - if (require_end_element (context, "errordomain", element_name, error)) + if (require_end_element (context, ctx, "errordomain", element_name, error)) { ctx->current_node = NULL; state_switch (ctx, STATE_NAMESPACE); @@ -2221,7 +2225,9 @@ end_element_handler (GMarkupParseContext *context, break; case STATE_INTERFACE_PROPERTY: - if (require_end_element (context, "property", element_name, error)) + if (strcmp ("type", element_name) == 0) + break; + if (require_end_element (context, ctx, "property", element_name, error)) { state_switch (ctx, STATE_INTERFACE); } @@ -2230,14 +2236,14 @@ end_element_handler (GMarkupParseContext *context, case STATE_INTERFACE_FIELD: if (strcmp ("type", element_name) == 0) break; - if (require_end_element (context, "field", element_name, error)) + if (require_end_element (context, ctx, "field", element_name, error)) { state_switch (ctx, STATE_INTERFACE); } break; case STATE_INTERFACE: - if (require_end_element (context, "interface", element_name, error)) + if (require_end_element (context, ctx, "interface", element_name, error)) { ctx->current_node = NULL; state_switch (ctx, STATE_NAMESPACE); @@ -2247,7 +2253,9 @@ end_element_handler (GMarkupParseContext *context, case STATE_ENUM: if (strcmp ("member", element_name) == 0) break; - else if (require_one_of_end_elements (context, element_name, error, "enumeration", "bitfield", NULL)) + else if (require_one_of_end_elements (context, ctx, + element_name, error, "enumeration", + "bitfield", NULL)) { ctx->current_node = NULL; state_switch (ctx, STATE_NAMESPACE); @@ -2255,7 +2263,7 @@ end_element_handler (GMarkupParseContext *context, break; case STATE_BOXED: - if (require_end_element (context, "glib:boxed", element_name, error)) + if (require_end_element (context, ctx, "glib:boxed", element_name, error)) { ctx->current_node = NULL; state_switch (ctx, STATE_NAMESPACE); @@ -2265,7 +2273,7 @@ end_element_handler (GMarkupParseContext *context, case STATE_BOXED_FIELD: if (strcmp ("type", element_name) == 0) break; - if (require_end_element (context, "field", element_name, error)) + if (require_end_element (context, ctx, "field", element_name, error)) { state_switch (ctx, STATE_BOXED); } @@ -2274,21 +2282,21 @@ end_element_handler (GMarkupParseContext *context, case STATE_STRUCT_FIELD: if (strcmp ("type", element_name) == 0) break; - if (require_end_element (context, "field", element_name, error)) + if (require_end_element (context, ctx, "field", element_name, error)) { state_switch (ctx, STATE_STRUCT); } break; case STATE_STRUCT: - if (require_end_element (context, "record", element_name, error)) + if (require_end_element (context, ctx, "record", element_name, error)) { ctx->current_node = NULL; state_switch (ctx, STATE_NAMESPACE); } break; case STATE_UNION: - if (require_end_element (context, "union", element_name, error)) + if (require_end_element (context, ctx, "union", element_name, error)) { ctx->current_node = NULL; state_switch (ctx, STATE_NAMESPACE); @@ -2297,15 +2305,15 @@ end_element_handler (GMarkupParseContext *context, case STATE_IMPLEMENTS: if (strcmp ("interface", element_name) == 0) break; - if (require_end_element (context, "implements", element_name, error)) + if (require_end_element (context, ctx, "implements", element_name, error)) state_switch (ctx, STATE_CLASS); break; case STATE_REQUIRES: - if (require_end_element (context, "requires", element_name, error)) + if (require_end_element (context, ctx, "requires", element_name, error)) state_switch (ctx, STATE_INTERFACE); break; case STATE_CONSTANT: - if (require_end_element (context, "constant", element_name, error)) + if (require_end_element (context, ctx, "constant", element_name, error)) { ctx->current_node = NULL; state_switch (ctx, STATE_NAMESPACE); From 698bcf0af5b13ec588ba82602ce693dcb0d14380 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 14 Aug 2008 19:07:34 +0000 Subject: [PATCH 029/692] Don't require c:type. Test boxed.gir Update, remove parts we don't support 2008-08-14 Johan Dahlin * girepository/girparser.c (start_type): Don't require c:type. * tests/Makefile.am: Test boxed.gir * tests/boxed.gir: Update, remove parts we don't support yet * tests/roundtrips.sh: Remove * tools/generate.c (write_type_info), (write_field_info), (write_callable_info), (write_struct_info): Make it emit proper gir. svn path=/trunk/; revision=376 --- girparser.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/girparser.c b/girparser.c index dfc704270..6b7942e90 100644 --- a/girparser.c +++ b/girparser.c @@ -1342,7 +1342,6 @@ start_type (GMarkupParseContext *context, GError **error) { const gchar *name; - const gchar *ctype; if (strcmp (element_name, "type") != 0 || !(ctx->state == STATE_FUNCTION_PARAMETER || @@ -1366,12 +1365,9 @@ start_type (GMarkupParseContext *context, } name = find_attribute ("name", attribute_names, attribute_values); - ctype = find_attribute ("c:type", attribute_names, attribute_values); if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); - if (ctype == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "c:type"); switch (ctx->current_typed->type) { From 27314af58e38bfe352078cc25412caa0038dfac6 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 14 Aug 2008 19:32:26 +0000 Subject: [PATCH 030/692] Clear up constant parsing 2008-08-14 Johan Dahlin * girepository/girparser.c (start_field), (start_constant), (start_type), (end_element_handler): Clear up constant parsing * tests/object.gir: Update * tools/generate.c (write_callable_info), (write_function_info), (write_callback_info), (write_constant_info), (write_signal_info), (write_vfunc_info), (write_property_info), (write_object_info), (write_interface_info): Constants/Signals are handled now. svn path=/trunk/; revision=377 --- girparser.c | 69 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 16 deletions(-) diff --git a/girparser.c b/girparser.c index 6b7942e90..07fff0a7f 100644 --- a/girparser.c +++ b/girparser.c @@ -53,8 +53,10 @@ typedef enum STATE_STRUCT_FIELD, STATE_ERRORDOMAIN, STATE_UNION, - STATE_CONSTANT, - STATE_ALIAS, /* 25 */ + STATE_NAMESPACE_CONSTANT, + STATE_CLASS_CONSTANT, /* 25 */ + STATE_INTERFACE_CONSTANT, + STATE_ALIAS } ParseState; typedef struct _ParseContext ParseContext; @@ -776,7 +778,6 @@ start_field (GMarkupParseContext *context, ctx->state == STATE_INTERFACE)) { const gchar *name; - const gchar *type; const gchar *readable; const gchar *writable; const gchar *bits; @@ -784,7 +785,6 @@ start_field (GMarkupParseContext *context, const gchar *offset; name = find_attribute ("name", attribute_names, attribute_values); - type = find_attribute ("c:type", attribute_names, attribute_values); readable = find_attribute ("readable", attribute_names, attribute_values); writable = find_attribute ("writable", attribute_names, attribute_values); bits = find_attribute ("bits", attribute_names, attribute_values); @@ -1119,19 +1119,15 @@ start_constant (GMarkupParseContext *context, ctx->state == STATE_INTERFACE)) { const gchar *name; - const gchar *type; const gchar *value; const gchar *deprecated; name = find_attribute ("name", attribute_names, attribute_values); - type = find_attribute ("c:type", attribute_names, attribute_values); value = find_attribute ("value", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); - else if (type == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "c:type"); else if (value == NULL) MISSING_ATTRIBUTE (context, error, element_name, "value"); else @@ -1142,8 +1138,8 @@ start_constant (GMarkupParseContext *context, ((GIrNode *)constant)->name = g_strdup (name); constant->value = g_strdup (value); - - constant->type = parse_type (ctx, type); + + ctx->current_typed = (GIrNode*) constant; if (deprecated && strcmp (deprecated, "1") == 0) constant->deprecated = TRUE; @@ -1163,7 +1159,22 @@ start_constant (GMarkupParseContext *context, iface = (GIrNodeInterface *)ctx->current_node; iface->members = g_list_append (iface->members, constant); } - state_switch (ctx, STATE_CONSTANT); + + switch (ctx->state) + { + case STATE_NAMESPACE: + state_switch (ctx, STATE_NAMESPACE_CONSTANT); + break; + case STATE_CLASS: + state_switch (ctx, STATE_CLASS_CONSTANT); + break; + case STATE_INTERFACE: + state_switch (ctx, STATE_INTERFACE_CONSTANT); + break; + default: + g_assert_not_reached (); + break; + } } return TRUE; @@ -1351,7 +1362,10 @@ start_type (GMarkupParseContext *context, ctx->state == STATE_CLASS_FIELD || ctx->state == STATE_INTERFACE_FIELD || ctx->state == STATE_INTERFACE_PROPERTY || - ctx->state == STATE_BOXED_FIELD + ctx->state == STATE_BOXED_FIELD || + ctx->state == STATE_NAMESPACE_CONSTANT || + ctx->state == STATE_CLASS_CONSTANT || + ctx->state == STATE_INTERFACE_CONSTANT )) return FALSE; @@ -1373,8 +1387,7 @@ start_type (GMarkupParseContext *context, { case G_IR_NODE_PARAM: { - GIrNodeParam *param; - param = (GIrNodeParam *)ctx->current_typed; + GIrNodeParam *param = (GIrNodeParam *)ctx->current_typed; param->type = parse_type (ctx, name); } break; @@ -1390,6 +1403,12 @@ start_type (GMarkupParseContext *context, property->type = parse_type (ctx, name); } break; + case G_IR_NODE_CONSTANT: + { + GIrNodeConstant *constant = (GIrNodeConstant *)ctx->current_typed; + constant->type = parse_type (ctx, name); + } + break; default: g_printerr("current node is %d\n", ctx->current_node->type); g_assert_not_reached (); @@ -2308,11 +2327,29 @@ end_element_handler (GMarkupParseContext *context, if (require_end_element (context, ctx, "requires", element_name, error)) state_switch (ctx, STATE_INTERFACE); break; - case STATE_CONSTANT: + case STATE_NAMESPACE_CONSTANT: + case STATE_CLASS_CONSTANT: + case STATE_INTERFACE_CONSTANT: + if (strcmp ("type", element_name) == 0) + break; if (require_end_element (context, ctx, "constant", element_name, error)) { ctx->current_node = NULL; - state_switch (ctx, STATE_NAMESPACE); + switch (ctx->state) + { + case STATE_NAMESPACE_CONSTANT: + state_switch (ctx, STATE_NAMESPACE); + break; + case STATE_CLASS_CONSTANT: + state_switch (ctx, STATE_CLASS); + break; + case STATE_INTERFACE_CONSTANT: + state_switch (ctx, STATE_INTERFACE); + break; + default: + g_assert_not_reached (); + break; + } } break; default: From 5241ccb8432d2851c2f55f79a23ecdd32d6a9c62 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 16 Aug 2008 21:55:06 +0000 Subject: [PATCH 031/692] Reorder svn path=/trunk/; revision=387 --- girparser.c | 84 ++++++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 39 deletions(-) diff --git a/girparser.c b/girparser.c index 07fff0a7f..1c2534df7 100644 --- a/girparser.c +++ b/girparser.c @@ -150,61 +150,67 @@ parse_type_internal (gchar *str, gchar **rest) gint tag; gboolean pointer; } basic[] = { - { "void", GI_TYPE_TAG_VOID, 0 }, { "none", GI_TYPE_TAG_VOID, 0 }, { "any", GI_TYPE_TAG_VOID, 1 }, - { "gpointer", GI_TYPE_TAG_VOID, 1 }, + { "bool", GI_TYPE_TAG_BOOLEAN, 0 }, - { "gboolean", GI_TYPE_TAG_BOOLEAN, 0 }, { "char", GI_TYPE_TAG_INT8, 0 }, + { "int8", GI_TYPE_TAG_INT8, 0 }, + { "uint8", GI_TYPE_TAG_UINT8, 0 }, + { "int16", GI_TYPE_TAG_INT16, 0 }, + { "uint16", GI_TYPE_TAG_UINT16, 0 }, + { "int32", GI_TYPE_TAG_INT32, 0 }, + { "uint32", GI_TYPE_TAG_UINT32, 0 }, + { "int64", GI_TYPE_TAG_INT64, 0 }, + { "uint64", GI_TYPE_TAG_UINT64, 0 }, + { "int", GI_TYPE_TAG_INT, 0 }, + { "uint", GI_TYPE_TAG_UINT, 0 }, + { "long", GI_TYPE_TAG_LONG, 0 }, + { "ulong", GI_TYPE_TAG_ULONG, 0 }, + { "ssize_t", GI_TYPE_TAG_SSIZE, 0 }, + { "ssize", GI_TYPE_TAG_SSIZE, 0 }, + { "size_t", GI_TYPE_TAG_SIZE, 0 }, + { "size", GI_TYPE_TAG_SIZE, 0 }, + { "float", GI_TYPE_TAG_FLOAT, 0 }, + { "double", GI_TYPE_TAG_DOUBLE, 0 }, + { "utf8", GI_TYPE_TAG_UTF8, 1 }, + { "filename", GI_TYPE_TAG_FILENAME,1 }, + + /* FIXME: merge - do we still want this? */ + { "string", GI_TYPE_TAG_UTF8, 1 } + + /* FIXME: Remove these */ + { "void", GI_TYPE_TAG_VOID, 0 }, + { "int8_t", GI_TYPE_TAG_INT8, 0 }, + { "uint8_t", GI_TYPE_TAG_UINT8, 0 }, + { "int16_t", GI_TYPE_TAG_INT16, 0 }, + { "uint16_t", GI_TYPE_TAG_UINT16, 0 }, + { "int32_t", GI_TYPE_TAG_INT32, 0 }, + { "uint32_t", GI_TYPE_TAG_UINT32, 0 }, + { "int64_t", GI_TYPE_TAG_INT64, 0 }, + { "uint64_t", GI_TYPE_TAG_UINT64, 0 }, + { "gpointer", GI_TYPE_TAG_VOID, 1 }, + { "gboolean", GI_TYPE_TAG_BOOLEAN, 0 }, { "gchar", GI_TYPE_TAG_INT8, 0 }, { "guchar", GI_TYPE_TAG_UINT8, 0 }, { "gunichar", GI_TYPE_TAG_UINT32, 0 }, - { "int8_t", GI_TYPE_TAG_INT8, 0 }, - { "int8", GI_TYPE_TAG_INT8, 0 }, - { "gint8", GI_TYPE_TAG_INT8, 0 }, - { "uint8_t", GI_TYPE_TAG_UINT8, 0 }, - { "uint8", GI_TYPE_TAG_UINT8, 0 }, - { "guint8", GI_TYPE_TAG_UINT8, 0 }, - { "int16_t", GI_TYPE_TAG_INT16, 0 }, - { "int16", GI_TYPE_TAG_INT16, 0 }, - { "gint16", GI_TYPE_TAG_INT16, 0 }, - { "uint16_t", GI_TYPE_TAG_UINT16, 0 }, - { "uint16", GI_TYPE_TAG_UINT16, 0 }, - { "guint16", GI_TYPE_TAG_UINT16, 0 }, - { "int32_t", GI_TYPE_TAG_INT32, 0 }, - { "int32", GI_TYPE_TAG_INT32, 0 }, - { "gint32", GI_TYPE_TAG_INT32, 0 }, - { "uint32_t", GI_TYPE_TAG_UINT32, 0 }, - { "uint32", GI_TYPE_TAG_UINT32, 0 }, - { "guint32", GI_TYPE_TAG_UINT32, 0 }, - { "int64_t", GI_TYPE_TAG_INT64, 0 }, - { "int64", GI_TYPE_TAG_INT64, 0 }, - { "gint64", GI_TYPE_TAG_INT64, 0 }, - { "uint64_t", GI_TYPE_TAG_UINT64, 0 }, - { "uint64", GI_TYPE_TAG_UINT64, 0 }, - { "guint64", GI_TYPE_TAG_UINT64, 0 }, - { "int", GI_TYPE_TAG_INT, 0 }, { "gint", GI_TYPE_TAG_INT, 0 }, - { "uint", GI_TYPE_TAG_UINT, 0 }, { "guint", GI_TYPE_TAG_UINT, 0 }, - { "long", GI_TYPE_TAG_LONG, 0 }, + { "gint8", GI_TYPE_TAG_INT8, 0 }, + { "guint8", GI_TYPE_TAG_UINT8, 0 }, + { "gint16", GI_TYPE_TAG_INT16, 0 }, + { "guint16", GI_TYPE_TAG_UINT16, 0 }, + { "gint32", GI_TYPE_TAG_INT32, 0 }, + { "guint32", GI_TYPE_TAG_UINT32, 0 }, + { "gint64", GI_TYPE_TAG_INT64, 0 }, + { "guint64", GI_TYPE_TAG_UINT64, 0 }, { "glong", GI_TYPE_TAG_LONG, 0 }, - { "ulong", GI_TYPE_TAG_ULONG, 0 }, { "gulong", GI_TYPE_TAG_ULONG, 0 }, - { "ssize_t", GI_TYPE_TAG_SSIZE, 0 }, { "gssize", GI_TYPE_TAG_SSIZE, 0 }, - { "size_t", GI_TYPE_TAG_SIZE, 0 }, { "gsize", GI_TYPE_TAG_SIZE, 0 }, - { "float", GI_TYPE_TAG_FLOAT, 0 }, { "gfloat", GI_TYPE_TAG_FLOAT, 0 }, - { "double", GI_TYPE_TAG_DOUBLE, 0 }, { "gdouble", GI_TYPE_TAG_DOUBLE, 0 }, - { "utf8", GI_TYPE_TAG_UTF8, 1 }, { "gchar*", GI_TYPE_TAG_UTF8, 1 }, - { "filename", GI_TYPE_TAG_FILENAME,1 }, - // FIXME merge - do we still want this? - { "string", GI_TYPE_TAG_UTF8, 1 } }; gint n_basic = G_N_ELEMENTS (basic); From bf5761db23b0f306e9cbae0992f0329393208cc4 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 16 Aug 2008 21:57:59 +0000 Subject: [PATCH 032/692] make it compile again... svn path=/trunk/; revision=388 --- girparser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/girparser.c b/girparser.c index 1c2534df7..6de19422d 100644 --- a/girparser.c +++ b/girparser.c @@ -177,7 +177,7 @@ parse_type_internal (gchar *str, gchar **rest) { "filename", GI_TYPE_TAG_FILENAME,1 }, /* FIXME: merge - do we still want this? */ - { "string", GI_TYPE_TAG_UTF8, 1 } + { "string", GI_TYPE_TAG_UTF8, 1 }, /* FIXME: Remove these */ { "void", GI_TYPE_TAG_VOID, 0 }, @@ -210,7 +210,7 @@ parse_type_internal (gchar *str, gchar **rest) { "gsize", GI_TYPE_TAG_SIZE, 0 }, { "gfloat", GI_TYPE_TAG_FLOAT, 0 }, { "gdouble", GI_TYPE_TAG_DOUBLE, 0 }, - { "gchar*", GI_TYPE_TAG_UTF8, 1 }, + { "gchar*", GI_TYPE_TAG_UTF8, 1 } }; gint n_basic = G_N_ELEMENTS (basic); From fc01170517132b7b8b0ee4fa892042d569f49cba Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 16 Aug 2008 22:26:55 +0000 Subject: [PATCH 033/692] Remove resolve_possible_typedefs, it was unused. Allow multiple enum 2008-08-17 Johan Dahlin * girepository/gtypelib.c (validate_enum_blob): * giscanner/glibtransformer.py: * giscanner/transformer.py: Remove resolve_possible_typedefs, it was unused. Allow multiple enum values of the sample value in an enum, since it's actually pretty common. Register enums so they can be resolved too. svn path=/trunk/; revision=389 --- gtypelib.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gtypelib.c b/gtypelib.c index dd598447c..c7371207b 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1199,6 +1199,7 @@ validate_enum_blob (GTypelib *typelib, error)) return FALSE; +#if 0 v1 = (ValueBlob *)&typelib->data[offset + sizeof (EnumBlob) + i * sizeof (ValueBlob)]; for (j = 0; j < i; j++) @@ -1208,6 +1209,7 @@ validate_enum_blob (GTypelib *typelib, if (v1->value == v2->value) { + /* FIXME should this be an error ? */ g_set_error (error, G_TYPELIB_ERROR, @@ -1216,6 +1218,7 @@ validate_enum_blob (GTypelib *typelib, return FALSE; } } +#endif } return TRUE; From b3312fb83fd807a582b8c86753a05fae00e038a6 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Mon, 18 Aug 2008 08:52:47 +0000 Subject: [PATCH 034/692] Make enum serializing functions public. Clean up some whitespace. 2008-08-18 Johan Dahlin * girepository/girepository.c (g_type_tag_to_string): * girepository/girepository.h: * girepository/girnode.c (g_ir_node_get_full_size_internal), (find_entry_node): * girepository/girnode.h: Make enum serializing functions public. Clean up some whitespace. svn path=/trunk/; revision=394 --- girepository.c | 62 ++++++++++++++++++++++++++++++++++++ girepository.h | 2 ++ girnode.c | 86 ++++++++------------------------------------------ girnode.h | 1 + 4 files changed, 79 insertions(+), 72 deletions(-) diff --git a/girepository.c b/girepository.c index b65d1b40d..765d27444 100644 --- a/girepository.c +++ b/girepository.c @@ -502,3 +502,65 @@ g_irepository_error_quark (void) quark = g_quark_from_static_string ("g-irepository-error-quark"); return quark; } + +const gchar* +g_type_tag_to_string (GITypeTag type) +{ + switch (type) + { + case GI_TYPE_TAG_VOID: + return "void"; + case GI_TYPE_TAG_BOOLEAN: + return "boolean"; + case GI_TYPE_TAG_INT8: + return "int8"; + case GI_TYPE_TAG_UINT8: + return "uint8"; + case GI_TYPE_TAG_INT16: + return "int16"; + case GI_TYPE_TAG_UINT16: + return "uint16"; + case GI_TYPE_TAG_INT32: + return "int32"; + case GI_TYPE_TAG_UINT32: + return "uint32"; + case GI_TYPE_TAG_INT64: + return "int64"; + case GI_TYPE_TAG_UINT64: + return "uint64"; + case GI_TYPE_TAG_INT: + return "int"; + case GI_TYPE_TAG_UINT: + return "uint"; + case GI_TYPE_TAG_LONG: + return "long"; + case GI_TYPE_TAG_ULONG: + return "ulong"; + case GI_TYPE_TAG_SSIZE: + return "ssize"; + case GI_TYPE_TAG_SIZE: + return "size"; + case GI_TYPE_TAG_FLOAT: + return "float"; + case GI_TYPE_TAG_DOUBLE: + return "double"; + case GI_TYPE_TAG_UTF8: + return "utf8"; + case GI_TYPE_TAG_FILENAME: + return "filename"; + case GI_TYPE_TAG_ARRAY: + return "array"; + case GI_TYPE_TAG_INTERFACE: + return "interface"; + case GI_TYPE_TAG_GLIST: + return "glist"; + case GI_TYPE_TAG_GSLIST: + return "gslist"; + case GI_TYPE_TAG_GHASH: + return "ghash"; + case GI_TYPE_TAG_ERROR: + return "error"; + default: + return "unknown"; + } +} diff --git a/girepository.h b/girepository.h index 010712e78..58d0aee22 100644 --- a/girepository.h +++ b/girepository.h @@ -285,6 +285,8 @@ typedef enum { GI_TYPE_TAG_ERROR = 25 } GITypeTag; +const gchar* g_type_tag_to_string (GITypeTag type); + gboolean g_type_info_is_pointer (GITypeInfo *info); GITypeTag g_type_info_get_tag (GITypeInfo *info); GITypeInfo * g_type_info_get_param_type (GITypeInfo *info, diff --git a/girnode.c b/girnode.c index 3d01ef17e..6fb32aa40 100644 --- a/girnode.c +++ b/girnode.c @@ -56,7 +56,7 @@ dump_stats (void) (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) -static const gchar * +const gchar * g_ir_node_type_to_string (GIrNodeTypeId type) { switch (type) @@ -104,68 +104,6 @@ g_ir_node_type_to_string (GIrNodeTypeId type) } } -static const gchar* -gi_type_tag_to_string (GITypeTag type) -{ - switch (type) - { - case GI_TYPE_TAG_VOID: - return "void"; - case GI_TYPE_TAG_BOOLEAN: - return "boolean"; - case GI_TYPE_TAG_INT8: - return "int8"; - case GI_TYPE_TAG_UINT8: - return "uint8"; - case GI_TYPE_TAG_INT16: - return "int16"; - case GI_TYPE_TAG_UINT16: - return "uint16"; - case GI_TYPE_TAG_INT32: - return "int32"; - case GI_TYPE_TAG_UINT32: - return "uint32"; - case GI_TYPE_TAG_INT64: - return "int64"; - case GI_TYPE_TAG_UINT64: - return "uint64"; - case GI_TYPE_TAG_INT: - return "int"; - case GI_TYPE_TAG_UINT: - return "uint"; - case GI_TYPE_TAG_LONG: - return "long"; - case GI_TYPE_TAG_ULONG: - return "ulong"; - case GI_TYPE_TAG_SSIZE: - return "ssize"; - case GI_TYPE_TAG_SIZE: - return "size"; - case GI_TYPE_TAG_FLOAT: - return "float"; - case GI_TYPE_TAG_DOUBLE: - return "double"; - case GI_TYPE_TAG_UTF8: - return "utf8"; - case GI_TYPE_TAG_FILENAME: - return "filename"; - case GI_TYPE_TAG_ARRAY: - return "array"; - case GI_TYPE_TAG_INTERFACE: - return "interface"; - case GI_TYPE_TAG_GLIST: - return "glist"; - case GI_TYPE_TAG_GSLIST: - return "gslist"; - case GI_TYPE_TAG_GHASH: - return "ghash"; - case GI_TYPE_TAG_ERROR: - return "error"; - default: - return "unknown"; - } -} - GIrNode * g_ir_node_new (GIrNodeTypeId type) { @@ -598,7 +536,8 @@ g_ir_node_get_size (GIrNode *node) /* returns the full size of the blob including variable-size parts */ static guint32 -g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node) +g_ir_node_get_full_size_internal (GIrNode *parent, + GIrNode *node) { GList *l; gint size, n; @@ -655,7 +594,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node) else { g_debug ("node %p type tag '%s'", node, - gi_type_tag_to_string (type->tag)); + g_type_tag_to_string (type->tag)); switch (type->tag) { @@ -923,7 +862,7 @@ g_ir_node_can_have_member (GIrNode *node) void g_ir_node_add_member (GIrNode *node, - GIrNodeFunction *member) + GIrNodeFunction *member) { g_return_if_fail (node != NULL); g_return_if_fail (member != NULL); @@ -1014,7 +953,7 @@ parse_boolean_value (const gchar *str) } static GIrNode * -find_entry_node (GIrModule *module, +find_entry_node (GIrModule *module, GList *modules, const gchar *name, guint16 *idx) @@ -1026,6 +965,9 @@ find_entry_node (GIrModule *module, gint n_names; GIrNode *result = NULL; + g_assert (name != NULL); + g_assert (strlen (name) > 0); + names = g_strsplit (name, ".", 0); n_names = g_strv_length (names); if (n_names > 2) @@ -1082,7 +1024,7 @@ find_entry_node (GIrModule *module, } static guint16 -find_entry (GIrModule *module, +find_entry (GIrModule *module, GList *modules, const gchar *name) { @@ -1094,9 +1036,9 @@ find_entry (GIrModule *module, } static void -serialize_type (GIrModule *module, +serialize_type (GIrModule *module, GList *modules, - GIrNodeType *node, + GIrNodeType *node, GString *str) { gint i; @@ -1211,8 +1153,8 @@ serialize_type (GIrModule *module, } void -g_ir_node_build_typelib (GIrNode *node, - GIrModule *module, +g_ir_node_build_typelib (GIrNode *node, + GIrModule *module, GList *modules, GHashTable *strings, GHashTable *types, diff --git a/girnode.h b/girnode.h index a01e01f38..6079d367a 100644 --- a/girnode.h +++ b/girnode.h @@ -328,6 +328,7 @@ guint32 write_string (const gchar *str, guint32 *offset); const gchar * g_ir_node_param_direction_string (GIrNodeParam * node); +const gchar * g_ir_node_type_to_string (GIrNodeTypeId type); G_END_DECLS From abcebee79f5d4916cf929fff52e18fff11a6c771 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 20 Aug 2008 15:05:46 +0000 Subject: [PATCH 035/692] Union field parsing 2008-08-20 Colin Walters * girepository/girparser.c: Parse union fields. svn path=/trunk/; revision=416 --- girparser.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/girparser.c b/girparser.c index 6de19422d..a4581e6c7 100644 --- a/girparser.c +++ b/girparser.c @@ -53,8 +53,9 @@ typedef enum STATE_STRUCT_FIELD, STATE_ERRORDOMAIN, STATE_UNION, - STATE_NAMESPACE_CONSTANT, - STATE_CLASS_CONSTANT, /* 25 */ + STATE_UNION_FIELD, + STATE_NAMESPACE_CONSTANT, /* 25 */ + STATE_CLASS_CONSTANT, STATE_INTERFACE_CONSTANT, STATE_ALIAS } ParseState; @@ -882,6 +883,7 @@ start_field (GMarkupParseContext *context, union_->discriminators = g_list_append (union_->discriminators, constant); } + state_switch (ctx, STATE_UNION_FIELD); } break; default: @@ -1364,6 +1366,7 @@ start_type (GMarkupParseContext *context, !(ctx->state == STATE_FUNCTION_PARAMETER || ctx->state == STATE_FUNCTION_RETURN || ctx->state == STATE_STRUCT_FIELD || + ctx->state == STATE_UNION_FIELD || ctx->state == STATE_CLASS_PROPERTY || ctx->state == STATE_CLASS_FIELD || ctx->state == STATE_INTERFACE_FIELD || @@ -2316,6 +2319,16 @@ end_element_handler (GMarkupParseContext *context, state_switch (ctx, STATE_NAMESPACE); } break; + + case STATE_UNION_FIELD: + if (strcmp ("type", element_name) == 0) + break; + if (require_end_element (context, ctx, "field", element_name, error)) + { + state_switch (ctx, STATE_UNION); + } + break; + case STATE_UNION: if (require_end_element (context, ctx, "union", element_name, error)) { From e47f68925ea39c2edea07725acb01ce24243ad9b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 20 Aug 2008 19:01:20 +0000 Subject: [PATCH 036/692] Avoid alias infloops. 2008-08-20 Colin Walters * girepository/girparser.c: Avoid alias infloops. svn path=/trunk/; revision=420 --- girparser.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/girparser.c b/girparser.c index a4581e6c7..f15e3c1f4 100644 --- a/girparser.c +++ b/girparser.c @@ -435,11 +435,16 @@ resolve_aliases (ParseContext *ctx, const gchar *type) { gpointer orig; gpointer value; + GSList *seen_values = NULL; + seen_values = g_slist_prepend (seen_values, type); while (g_hash_table_lookup_extended (ctx->aliases, type, &orig, &value)) { g_debug ("Resolved: %s => %s", type, value); type = value; + if (g_slist_find_custom (seen_values, type, strcmp) != NULL) + break; + seen_values = g_slist_prepend (seen_values, type); } return type; } From 89e881b47b0042c3a8c093c0645c9ea792e4a80d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 20 Aug 2008 19:17:14 +0000 Subject: [PATCH 037/692] Rename .gir files using GI namespace. Use XDG_DATA_DIRS for looking up 2008-08-20 Colin Walters * gir/Makefile.am: Rename .gir files using GI namespace. * girepository/girepository.c: Use XDG_DATA_DIRS for looking up typelibs. Also typelibs are now suffixed with .typelib. * tests/invoke/Makefile.am: Only use metadata. * girepository/Makefile.am: Remove unnecessary include. * tests/scanner/Makefile.am: Update using GI namespaces for scanner includes. svn path=/trunk/; revision=422 --- Makefile.am | 2 -- girepository.c | 28 +++++++++------------------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/Makefile.am b/Makefile.am index 36e7baf93..fe66da265 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,8 +2,6 @@ include $(top_srcdir)/gcov.mak GCOVSOURCES = $(libgirepository_la_SOURCES) -INCLUDES = -DGIREPO_DEFAULT_SEARCH_PATH="\"$(libdir)\"" - girepodir = $(includedir)/gobject-introspection-1.0/ girepo_HEADERS = girepository.h diff --git a/girepository.c b/girepository.c index 765d27444..a1759f60b 100644 --- a/girepository.c +++ b/girepository.c @@ -114,11 +114,6 @@ g_irepository_register (GIRepository *repository, if (typelib->module == NULL) typelib->module = g_module_open (NULL, 0); - if (g_getenv ("G_IREPOSITORY_VERBOSE")) - { - g_printerr ("Loaded typelib %s\n", name); - } - return name; } @@ -395,22 +390,17 @@ g_irepository_get_shared_library (GIRepository *repository, static inline void g_irepository_build_search_path (void) { - gchar **dir; - gchar **tokens; + const gchar *const *datadirs; + const gchar *const *dir; - if (g_getenv ("GIREPOPATH")) { - gchar *path; - path = g_strconcat (g_getenv ("GIREPOPATH"), ":", GIREPO_DEFAULT_SEARCH_PATH, NULL); - tokens = g_strsplit (path, ":", 0); - g_free (path); - } else - tokens = g_strsplit (GIREPO_DEFAULT_SEARCH_PATH, ":", 0); + datadirs = g_get_system_data_dirs (); - search_path = g_slist_prepend (search_path, "."); - for (dir = tokens; *dir; ++dir) - search_path = g_slist_prepend (search_path, *dir); + search_path = NULL; + for (dir = datadirs; *dir; dir++) { + char *path = g_build_filename (*dir, "gitypelibs", NULL); + search_path = g_slist_prepend (search_path, path); + } search_path = g_slist_reverse (search_path); - g_free (tokens); } const gchar * @@ -441,7 +431,7 @@ g_irepository_register_file (GIRepository *repository, if (search_path == NULL) g_irepository_build_search_path (); - fname = g_strconcat (namespace, ".repo", NULL); + fname = g_strconcat (namespace, ".typelib", NULL); for (ldir = search_path; ldir; ldir = ldir->next) { dir = ldir->data; From 4de606f07d15514a14e869d666604b7725cec96e Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 20 Aug 2008 19:57:10 +0000 Subject: [PATCH 038/692] And parse them. 2008-08-20 Colin Walters * girepository/girparser.py: And parse them. svn path=/trunk/; revision=425 --- girparser.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/girparser.c b/girparser.c index f15e3c1f4..eb4a8a4f3 100644 --- a/girparser.c +++ b/girparser.c @@ -197,6 +197,8 @@ parse_type_internal (gchar *str, gchar **rest) { "gunichar", GI_TYPE_TAG_UINT32, 0 }, { "gint", GI_TYPE_TAG_INT, 0 }, { "guint", GI_TYPE_TAG_UINT, 0 }, + { "gshort", GI_TYPE_TAG_INT16, 0 }, + { "gushort", GI_TYPE_TAG_UINT16, 0 }, { "gint8", GI_TYPE_TAG_INT8, 0 }, { "guint8", GI_TYPE_TAG_UINT8, 0 }, { "gint16", GI_TYPE_TAG_INT16, 0 }, From 61ae81c9c8ecfd26b21c32513f2808dd33cc560a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 20 Aug 2008 23:56:40 +0000 Subject: [PATCH 039/692] Remove g_irepository_register_file in favor of g_irepository_require. 2008-08-20 Colin Walters * girepository/girepository.c: Remove g_irepository_register_file in favor of g_irepository_require. There are two possible deployment scenarios for typelibs: First, separate in $DATADIR/gitypelibs/. Second, they may be embedded in shlibs. However since the first is now the normal case, the API is optimized around it. Refactor internals to look up typelibs for namespaces just-in-time, but we expect consumers to call g_irepository_require. Also, add some docs. No one has died from that before. * gir/Makefile.am: Need --library for glib. * giscanner/girwriter.py: Write out shared-library. * tools/g-ir-writer: Take the first --library argument as the target of shared-library. In the future we should make this nicer with pkg-config probably. svn path=/trunk/; revision=426 --- girepository.c | 124 ++++++++++++++++++++++++++++++++++--------------- girepository.h | 6 +-- 2 files changed, 90 insertions(+), 40 deletions(-) diff --git a/girepository.c b/girepository.c index a1759f60b..0fcc98734 100644 --- a/girepository.c +++ b/girepository.c @@ -28,6 +28,7 @@ #include "girepository.h" #include "gtypelib.h" +static GStaticMutex globals_lock = G_STATIC_MUTEX_INIT; static GIRepository *default_repository = NULL; static GHashTable *default_typelib = NULL; static GSList *search_path = NULL; @@ -68,6 +69,39 @@ g_irepository_class_init (GIRepositoryClass *class) g_type_class_add_private (class, sizeof (GIRepositoryPrivate)); } +static void +init_globals () +{ + g_static_mutex_lock (&globals_lock); + + if (default_repository == NULL) + { + default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL); + if (default_typelib == NULL) + default_typelib = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) NULL, + (GDestroyNotify) g_typelib_free); + default_repository->priv->typelib = default_typelib; + } + + if (search_path == NULL) + { + const gchar *const *datadirs; + const gchar *const *dir; + + datadirs = g_get_system_data_dirs (); + + search_path = NULL; + for (dir = datadirs; *dir; dir++) { + char *path = g_build_filename (*dir, "gitypelibs", NULL); + search_path = g_slist_prepend (search_path, path); + } + search_path = g_slist_reverse (search_path); + } + + g_static_mutex_unlock (&globals_lock); +} + const gchar * g_irepository_register (GIRepository *repository, GTypelib *typelib) @@ -93,10 +127,7 @@ g_irepository_register (GIRepository *repository, } else { - if (default_typelib == NULL) - default_typelib = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) NULL, - (GDestroyNotify) g_typelib_free); + init_globals (); table = default_typelib; } @@ -126,8 +157,11 @@ g_irepository_unregister (GIRepository *repository, if (repository != NULL) table = repository->priv->typelib; - else - table = default_typelib; + else + { + init_globals (); + table = default_typelib; + } if (!g_hash_table_remove (table, namespace)) { @@ -144,7 +178,10 @@ g_irepository_is_registered (GIRepository *repository, if (repository != NULL) table = repository->priv->typelib; else - table = default_typelib; + { + init_globals (); + table = default_typelib; + } return g_hash_table_lookup (table, namespace) != NULL; } @@ -152,16 +189,7 @@ g_irepository_is_registered (GIRepository *repository, GIRepository * g_irepository_get_default (void) { - if (default_repository == NULL) - { - default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL); - if (default_typelib == NULL) - default_typelib = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) NULL, - (GDestroyNotify) g_typelib_free); - default_repository->priv->typelib = default_typelib; - } - + init_globals (); return default_repository; } @@ -315,6 +343,17 @@ g_irepository_find_by_gtype (GIRepository *repository, return data.iface; } +/** + * g_irepository_find_by_name + * @repository: A #GIRepository, may be %NULL for the default + * @namespace: Namespace to search in, may be %NULL for all + * @name: Name to find + * + * Searches for a particular name in one or all namespaces. + * See #g_irepository_require to load metadata for namespaces. + + * Returns: #GIBaseInfo representing metadata about @name, or %NULL + */ GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, const gchar *namespace, @@ -352,6 +391,16 @@ collect_namespaces (gpointer key, *list = g_list_append (*list, key); } +/** + * g_irepository_get_namespaces + * @repository: A #GIRepository, may be %NULL for the default + * + * Return the list of currently known namespaces. Normally + * if you want a particular namespace, you should call + * #g_irepository_require to load it in. + + * Returns: List of namespaces + */ gchar ** g_irepository_get_namespaces (GIRepository *repository) { @@ -390,23 +439,25 @@ g_irepository_get_shared_library (GIRepository *repository, static inline void g_irepository_build_search_path (void) { - const gchar *const *datadirs; - const gchar *const *dir; - - datadirs = g_get_system_data_dirs (); - - search_path = NULL; - for (dir = datadirs; *dir; dir++) { - char *path = g_build_filename (*dir, "gitypelibs", NULL); - search_path = g_slist_prepend (search_path, path); - } - search_path = g_slist_reverse (search_path); } +/** + * g_irepository_require + * @repository: Repository, may be null for the default + * @namespace: GI namespace to use, e.g. "Gtk" + * @error: a #GError. + * + * Force the namespace @namespace to be loaded if it isn't + * already. If @namespace is not loaded, this function will + * search for a ".typelib" file using the repository search + * path. + * + * Returns: Namespace if successful, NULL otherwise + */ const gchar * -g_irepository_register_file (GIRepository *repository, - const gchar *namespace, - GError **error) +g_irepository_require (GIRepository *repository, + const gchar *namespace, + GError **error) { GSList *ldir; const char *dir; @@ -422,14 +473,14 @@ g_irepository_register_file (GIRepository *repository, if (repository != NULL) table = repository->priv->typelib; else - table = default_typelib; + { + init_globals (); + table = default_typelib; + } /* don't bother loading a namespace if already registered */ if (g_hash_table_lookup (table, namespace)) - return NULL; - - if (search_path == NULL) - g_irepository_build_search_path (); + return namespace; fname = g_strconcat (namespace, ".typelib", NULL); @@ -438,7 +489,6 @@ g_irepository_register_file (GIRepository *repository, full_path = g_build_filename (dir, fname, NULL); mfile = g_mapped_file_new (full_path, FALSE, &error1); if (error1) { - g_debug ("Failed to mmap \"%s\": %s", full_path, error1->message); g_clear_error (&error1); g_free (full_path); continue; diff --git a/girepository.h b/girepository.h index 58d0aee22..c3b804a3f 100644 --- a/girepository.h +++ b/girepository.h @@ -76,14 +76,14 @@ const gchar * g_irepository_register (GIRepository *repository, GTypelib *typelib); void g_irepository_unregister (GIRepository *repository, const gchar *namespace); -const gchar * g_irepository_register_file (GIRepository *repository, - const gchar *filename, - GError **error); gboolean g_irepository_is_registered (GIRepository *repository, const gchar *namespace); GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, const gchar *namespace, const gchar *name); +const char * g_irepository_require (GIRepository *repository, + const char *namespace, + GError **error); gchar ** g_irepository_get_namespaces (GIRepository *repository); GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository, GType gtype); From ae74722007a878efb46d44c04bc96896fb4cdadb Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 21 Aug 2008 00:42:23 +0000 Subject: [PATCH 040/692] Calculate size correctly, avoid use-after-free. 2008-08-20 Colin Walters * girepository/girmodule.c (g_ir_module_build_typelib): Calculate size correctly, avoid use-after-free. svn path=/trunk/; revision=427 --- girmodule.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/girmodule.c b/girmodule.c index 46e70f686..1ffbf9ba4 100644 --- a/girmodule.c +++ b/girmodule.c @@ -64,7 +64,7 @@ GTypelib * g_ir_module_build_typelib (GIrModule *module, GList *modules) { - guchar *typelib; + GTypelib *typelib; gsize length; gint i; GList *e; @@ -102,6 +102,11 @@ g_ir_module_build_typelib (GIrModule *module, size += g_ir_node_get_full_size (node); } + /* Adjust size for strings allocated in header below specially */ + size += strlen (module->name); + if (module->shared_library) + size += strlen (module->shared_library); + g_message ("allocating %d bytes (%d header, %d directory, %d entries)\n", size, header_size, dir_size, size - header_size - dir_size); @@ -201,15 +206,19 @@ g_ir_module_build_typelib (GIrModule *module, } dump_stats (); - g_hash_table_destroy (strings); - g_hash_table_destroy (types); header->annotations = offset2; g_message ("reallocating to %d bytes", offset2); - typelib = g_realloc (data, offset2); + data = g_realloc (data, offset2); + header = (Header*) data; length = header->size = offset2; - return g_typelib_new_from_memory (typelib, length); + typelib = g_typelib_new_from_memory (data, length); + + g_hash_table_destroy (strings); + g_hash_table_destroy (types); + + return typelib; } From c09cf789a0d1165bd1949e065fecb2109ebc5be4 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 21 Aug 2008 03:06:13 +0000 Subject: [PATCH 041/692] Add new function g_irepository_get_typelib_path which tells us from where 2008-08-20 Colin Walters * girepository/girepository.c: Add new function g_irepository_get_typelib_path which tells us from where we loaded a namespace. svn path=/trunk/; revision=429 --- girepository.c | 58 ++++++++++++++++++++++++++++++++++++++++++-------- girepository.h | 2 ++ 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/girepository.c b/girepository.c index 0fcc98734..4bf287f09 100644 --- a/girepository.c +++ b/girepository.c @@ -102,9 +102,19 @@ init_globals () g_static_mutex_unlock (&globals_lock); } -const gchar * -g_irepository_register (GIRepository *repository, - GTypelib *typelib) +static char * +build_typelib_key (const char *name, const char *source) +{ + GString *str = g_string_new (name); + g_string_append_c (str, '\0'); + g_string_append (str, source); + return g_string_free (str, FALSE); +} + +static const gchar * +register_internal (GIRepository *repository, + const char *source, + GTypelib *typelib) { Header *header; const gchar *name; @@ -140,7 +150,7 @@ g_irepository_register (GIRepository *repository, return NULL; } - g_hash_table_insert (table, g_strdup(name), (void *)typelib); + g_hash_table_insert (table, build_typelib_key (name, source), (void *)typelib); if (typelib->module == NULL) typelib->module = g_module_open (NULL, 0); @@ -148,6 +158,12 @@ g_irepository_register (GIRepository *repository, return name; } +const gchar * +g_irepository_register (GIRepository *repository, + GTypelib *typelib) +{ + return register_internal (repository, "", typelib); +} void g_irepository_unregister (GIRepository *repository, @@ -436,14 +452,34 @@ g_irepository_get_shared_library (GIRepository *repository, return NULL; } -static inline void -g_irepository_build_search_path (void) +/** + * g_irepository_get_typelib_path + * @repository: Repository, may be %NULL for the default + * @namespace: GI namespace to use, e.g. "Gtk" + * + * If namespace @namespace is loaded, return the full path to the + * .typelib file it was loaded from. If the typelib for + * namespace @namespace was included in a shared library, return + * the special string "". + * + * Returns: Filesystem path (or ) if successful, %NULL otherwise + */ + +const gchar * +g_irepository_get_typelib_path (GIRepository *repository, + const gchar *namespace) { + gpointer orig_key, value; + + if (!g_hash_table_lookup_extended (repository->priv->typelib, namespace, + &orig_key, &value)) + return NULL; + return ((char*)orig_key) + strlen ((char *) orig_key) + 1; } /** * g_irepository_require - * @repository: Repository, may be null for the default + * @repository: Repository, may be %NULL for the default * @namespace: GI namespace to use, e.g. "Gtk" * @error: a #GError. * @@ -493,10 +529,10 @@ g_irepository_require (GIRepository *repository, g_free (full_path); continue; } - g_free (full_path); typelib = g_typelib_new_from_mapped_file (mfile); typelib_namespace = g_typelib_get_string (typelib, ((Header *) typelib->data)->namespace); if (strcmp (typelib_namespace, namespace) != 0) { + g_free (full_path); g_set_error (error, G_IREPOSITORY_ERROR, G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH, "Typelib file %s for namespace '%s' contains namespace '%s'" @@ -508,6 +544,7 @@ g_irepository_require (GIRepository *repository, } g_free (fname); if (typelib == NULL) { + g_free (full_path); g_set_error (error, G_IREPOSITORY_ERROR, G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, "Typelib file for namespace '%s' was not found in search" @@ -520,6 +557,7 @@ g_irepository_require (GIRepository *repository, shlib_fname = g_typelib_get_string (typelib, shlib); module = g_module_open (shlib_fname, G_MODULE_BIND_LAZY|G_MODULE_BIND_LOCAL); if (module == NULL) { + g_free (full_path); g_set_error (error, G_IREPOSITORY_ERROR, G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, "Typelib for namespace '%s' references shared library %s," @@ -530,7 +568,9 @@ g_irepository_require (GIRepository *repository, } g_hash_table_remove (table, namespace); - return g_irepository_register (repository, typelib); + register_internal (repository, full_path, typelib); + g_free (full_path); + return namespace; } diff --git a/girepository.h b/girepository.h index c3b804a3f..4c6801697 100644 --- a/girepository.h +++ b/girepository.h @@ -92,6 +92,8 @@ gint g_irepository_get_n_infos (GIRepository *repository, GIBaseInfo * g_irepository_get_info (GIRepository *repository, const gchar *namespace, gint index); +const gchar * g_irepository_get_typelib_path (GIRepository *repository, + const gchar *namespace); const gchar * g_irepository_get_shared_library (GIRepository *repository, const gchar *namespace); /* Typelib */ From 790ba0d7b0d804e1ebf3964912460700bf3063ad Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 21 Aug 2008 06:47:49 +0000 Subject: [PATCH 042/692] Rewrap and fix double free bug by leaking a bit. 2008-08-21 Johan Dahlin * girepository/girepository.c (g_irepository_require): Rewrap and fix double free bug by leaking a bit. svn path=/trunk/; revision=430 --- girepository.c | 97 ++++++++++++++++++++++++++++---------------------- 1 file changed, 55 insertions(+), 42 deletions(-) diff --git a/girepository.c b/girepository.c index 4bf287f09..9cacac662 100644 --- a/girepository.c +++ b/girepository.c @@ -520,52 +520,65 @@ g_irepository_require (GIRepository *repository, fname = g_strconcat (namespace, ".typelib", NULL); - for (ldir = search_path; ldir; ldir = ldir->next) { - dir = ldir->data; - full_path = g_build_filename (dir, fname, NULL); - mfile = g_mapped_file_new (full_path, FALSE, &error1); - if (error1) { - g_clear_error (&error1); - g_free (full_path); - continue; - } - typelib = g_typelib_new_from_mapped_file (mfile); - typelib_namespace = g_typelib_get_string (typelib, ((Header *) typelib->data)->namespace); - if (strcmp (typelib_namespace, namespace) != 0) { - g_free (full_path); - g_set_error (error, G_IREPOSITORY_ERROR, - G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH, - "Typelib file %s for namespace '%s' contains namespace '%s'" - " which doesn't match the file name", - full_path, namespace, typelib_namespace); - return NULL; - } - break; + for (ldir = search_path; ldir; ldir = ldir->next) + { + Header *header; + + full_path = g_build_filename (ldir->data, fname, NULL); + mfile = g_mapped_file_new (full_path, FALSE, &error1); + if (error1) + { + g_clear_error (&error1); + g_free (full_path); + continue; + } + + typelib = g_typelib_new_from_mapped_file (mfile); + header = (Header *) typelib->data; + typelib_namespace = g_typelib_get_string (typelib, header->namespace); + + if (strcmp (typelib_namespace, namespace) != 0) + { + g_free (full_path); + g_set_error (error, G_IREPOSITORY_ERROR, + G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH, + "Typelib file %s for namespace '%s' contains " + "namespace '%s' which doesn't match the file name", + full_path, namespace, typelib_namespace); + return NULL; + } + break; } - g_free (fname); - if (typelib == NULL) { - g_free (full_path); - g_set_error (error, G_IREPOSITORY_ERROR, - G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, - "Typelib file for namespace '%s' was not found in search" - " path or could not be openened", namespace); - return NULL; - } - /* optionally load shared library and attach it to the typelib */ - shlib = ((Header *) typelib->data)->shared_library; - if (shlib) { - shlib_fname = g_typelib_get_string (typelib, shlib); - module = g_module_open (shlib_fname, G_MODULE_BIND_LAZY|G_MODULE_BIND_LOCAL); - if (module == NULL) { - g_free (full_path); + + if (typelib == NULL) + { g_set_error (error, G_IREPOSITORY_ERROR, - G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, - "Typelib for namespace '%s' references shared library %s," - " but it could not be openened (%s)", - namespace, shlib_fname, g_module_error ()); + G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, + "Typelib file for namespace '%s' was not found in search" + " path or could not be openened", namespace); return NULL; } - } + + g_free (fname); + + /* optionally load shared library and attach it to the typelib */ + shlib = ((Header *) typelib->data)->shared_library; + if (shlib) + { + shlib_fname = g_typelib_get_string (typelib, shlib); + module = g_module_open (shlib_fname, + G_MODULE_BIND_LAZY|G_MODULE_BIND_LOCAL); + if (module == NULL) + { + g_free (full_path); + g_set_error (error, G_IREPOSITORY_ERROR, + G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, + "Typelib for namespace '%s' references shared library " + "%s, but it could not be openened (%s)", + namespace, shlib_fname, g_module_error ()); + return NULL; + } + } g_hash_table_remove (table, namespace); register_internal (repository, full_path, typelib); From 9152ea35ab68ffee0eefc645ffad21c4c5da4459 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 21 Aug 2008 08:20:07 +0000 Subject: [PATCH 043/692] Remove compilation warnings 2008-08-21 Johan Dahlin * girepository/girparser.c (resolve_aliases): Remove compilation warnings svn path=/trunk/; revision=431 --- girparser.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/girparser.c b/girparser.c index eb4a8a4f3..917d37d8e 100644 --- a/girparser.c +++ b/girparser.c @@ -439,15 +439,17 @@ resolve_aliases (ParseContext *ctx, const gchar *type) gpointer value; GSList *seen_values = NULL; - seen_values = g_slist_prepend (seen_values, type); + seen_values = g_slist_prepend (seen_values, (char*)type); while (g_hash_table_lookup_extended (ctx->aliases, type, &orig, &value)) { g_debug ("Resolved: %s => %s", type, value); type = value; - if (g_slist_find_custom (seen_values, type, strcmp) != NULL) + if (g_slist_find_custom (seen_values, type, + (GCompareFunc)strcmp) != NULL) break; - seen_values = g_slist_prepend (seen_values, type); + seen_values = g_slist_prepend (seen_values, (gchar*)type); } + g_slist_free (seen_values); return type; } From 3011ce453900fabbd0f552423c53e82d7a1ed1a5 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 21 Aug 2008 13:26:53 +0000 Subject: [PATCH 044/692] Fix one small leak in error case. 2008-08-21 Colin Walters * girepository/girparser.c (g_irepository_require): Fix one small leak in error case. svn path=/trunk/; revision=434 --- girepository.c | 1 + 1 file changed, 1 insertion(+) diff --git a/girepository.c b/girepository.c index 9cacac662..3898c4f8a 100644 --- a/girepository.c +++ b/girepository.c @@ -552,6 +552,7 @@ g_irepository_require (GIRepository *repository, if (typelib == NULL) { + g_free (full_path); g_set_error (error, G_IREPOSITORY_ERROR, G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, "Typelib file for namespace '%s' was not found in search" From a47d659cd10914ed7e3b8bb72a5134afe79f851b Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 21 Aug 2008 14:21:00 +0000 Subject: [PATCH 045/692] Use g_module_build_path to resolve the shlib name 2008-08-21 Johan Dahlin * girepository/gtypelib.c (_g_typelib_init): Use g_module_build_path to resolve the shlib name svn path=/trunk/; revision=437 --- gtypelib.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gtypelib.c b/gtypelib.c index c7371207b..6e04f6521 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1836,6 +1836,8 @@ _g_typelib_init (GTypelib *typelib) if (typelib->module == NULL) { + gchar *resolved_shlib; + /* Glade's autoconnect feature and OpenGL's extension mechanism * as used by Clutter rely on dlopen(NULL) to work as a means of * accessing the app's symbols. This keeps us from using @@ -1844,11 +1846,14 @@ _g_typelib_init (GTypelib *typelib) * themselves and are not expecting to be unloaded. So we just * load modules globally for now. */ - - typelib->module = g_module_open (shlib, G_MODULE_BIND_LAZY); + + resolved_shlib = g_module_build_path (NULL, shlib); + typelib->module = g_module_open (resolved_shlib, G_MODULE_BIND_LAZY); if (typelib->module == NULL) g_warning ("Failed to load shared library referenced by the typelib: %s", g_module_error ()); + + g_free (resolved_shlib); } } } From 60adefcef2e5b67d403d7b86320bc510a58f595c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 21 Aug 2008 16:15:55 +0000 Subject: [PATCH 046/692] Tweak to use UINT instead of INT. Not likely to matter. Add to 2008-08-21 Colin Walters * girepository/girnode.c (write_string): Tweak to use UINT instead of INT. Not likely to matter. * girepository/girmodule.c (g_ir_module_build_typelib): Add to header_offset as well for header strings to match what write_string does. * girepository/gtypelib.c: Replace is_name with validate_name, which more strongly validates and handles errors in a better way. Update all callers. * giscanner/glibtransformer.py: Handle constructors better. svn path=/trunk/; revision=439 --- girmodule.c | 8 +- girnode.c | 4 +- gtypelib.c | 289 +++++++++++++++------------------------------------- 3 files changed, 91 insertions(+), 210 deletions(-) diff --git a/girmodule.c b/girmodule.c index 1ffbf9ba4..1fcdadbce 100644 --- a/girmodule.c +++ b/girmodule.c @@ -104,8 +104,12 @@ g_ir_module_build_typelib (GIrModule *module, /* Adjust size for strings allocated in header below specially */ size += strlen (module->name); - if (module->shared_library) - size += strlen (module->shared_library); + header_size = ALIGN_VALUE (header_size + strlen (module->name) + 1, 4); + if (module->shared_library) + { + size += strlen (module->shared_library); + header_size = ALIGN_VALUE (header_size + strlen (module->shared_library) + 1, 4); + } g_message ("allocating %d bytes (%d header, %d directory, %d entries)\n", size, header_size, dir_size, size - header_size - dir_size); diff --git a/girnode.c b/girnode.c index 6fb32aa40..06e1b8e78 100644 --- a/girnode.c +++ b/girnode.c @@ -2144,12 +2144,12 @@ write_string (const gchar *str, value = g_hash_table_lookup (strings, str); if (value) - return GPOINTER_TO_INT (value); + return GPOINTER_TO_UINT (value); unique_string_count += 1; unique_string_size += strlen (str); - g_hash_table_insert (strings, (gpointer)str, GINT_TO_POINTER (*offset)); + g_hash_table_insert (strings, (gpointer)str, GUINT_TO_POINTER (*offset)); start = *offset; *offset = ALIGN_VALUE (start + strlen (str) + 1, 4); diff --git a/gtypelib.c b/gtypelib.c index 6e04f6521..53684fdb7 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -81,17 +81,44 @@ is_aligned (guint32 offset) #define MAX_NAME_LEN 200 static gboolean -is_name (const guchar *data, guint32 offset) +validate_name (GTypelib *typelib, + const char *msg, + const guchar *data, guint32 offset, + GError **error) { gchar *name; + if (typelib->len < offset) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short for type %s", + msg); + return FALSE; + } + name = (gchar*)&data[offset]; - if (!memchr (name, '\0', MAX_NAME_LEN)) - return FALSE; + if (!memchr (name, '\0', MAX_NAME_LEN)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The %s is too long: %s", + msg, name); + return FALSE; + } - if (strspn (name, G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_") < strlen (name)) - return FALSE; + if (strspn (name, G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_") < strlen (name)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The %s is contains invalid characters: %s", + msg, name); + return FALSE; + } return TRUE; } @@ -204,14 +231,8 @@ validate_header (GTypelib *typelib, return FALSE; } - if (!is_name (typelib->data, header->namespace)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_HEADER, - "Invalid namespace name"); - return FALSE; - } + if (!validate_name (typelib, "namespace", typelib->data, header->namespace, error)) + return FALSE; return TRUE; } @@ -470,14 +491,8 @@ validate_arg_blob (GTypelib *typelib, blob = (ArgBlob*) &typelib->data[offset]; - if (!is_name (typelib->data, blob->name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid argument name"); - return FALSE; - } + if (!validate_name (typelib, "argument", typelib->data, blob->name, error)) + return FALSE; if (!validate_type_blob (typelib, offset + G_STRUCT_OFFSET (ArgBlob, arg_type), @@ -557,23 +572,11 @@ validate_function_blob (GTypelib *typelib, return FALSE; } - if (!is_name (typelib->data, blob->name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid function name"); - return FALSE; - } + if (!validate_name (typelib, "function", typelib->data, blob->name, error)) + return FALSE; - if (!is_name (typelib->data, blob->symbol)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid function symbol"); - return FALSE; - } + if (!validate_name (typelib, "function symbol", typelib->data, blob->symbol, error)) + return FALSE; if (blob->constructor) { @@ -657,14 +660,8 @@ validate_callback_blob (GTypelib *typelib, return FALSE; } - if (!is_name (typelib->data, blob->name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid callback name"); - return FALSE; - } + if (!validate_name (typelib, "callback", typelib->data, blob->name, error)) + return FALSE; if (!validate_signature_blob (typelib, blob->signature, error)) return FALSE; @@ -708,14 +705,8 @@ validate_constant_blob (GTypelib *typelib, return FALSE; } - if (!is_name (typelib->data, blob->name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid constant name"); - return FALSE; - } + if (!validate_name (typelib, "constant", typelib->data, blob->name, error)) + return FALSE; if (!validate_type_blob (typelib, offset + G_STRUCT_OFFSET (ConstantBlob, type), 0, FALSE, error)) @@ -775,14 +766,8 @@ validate_value_blob (GTypelib *typelib, blob = (ValueBlob*) &typelib->data[offset]; - if (!is_name (typelib->data, blob->name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid value name"); - return FALSE; - } + if (!validate_name (typelib, "value", typelib->data, blob->name, error)) + return FALSE; return TRUE; } @@ -805,15 +790,9 @@ validate_field_blob (GTypelib *typelib, blob = (FieldBlob*) &typelib->data[offset]; - if (!is_name (typelib->data, blob->name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid field name"); - return FALSE; - } - + if (!validate_name (typelib, "field", typelib->data, blob->name, error)) + return FALSE; + if (!validate_type_blob (typelib, offset + G_STRUCT_OFFSET (FieldBlob, type), 0, FALSE, error)) @@ -840,14 +819,8 @@ validate_property_blob (GTypelib *typelib, blob = (PropertyBlob*) &typelib->data[offset]; - if (!is_name (typelib->data, blob->name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid property name"); - return FALSE; - } + if (!validate_name (typelib, "property", typelib->data, blob->name, error)) + return FALSE; if (!validate_type_blob (typelib, offset + G_STRUCT_OFFSET (PropertyBlob, type), @@ -877,14 +850,8 @@ validate_signal_blob (GTypelib *typelib, blob = (SignalBlob*) &typelib->data[offset]; - if (!is_name (typelib->data, blob->name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid signal name"); - return FALSE; - } + if (!validate_name (typelib, "signal", typelib->data, blob->name, error)) + return FALSE; if ((blob->run_first != 0) + (blob->run_last != 0) + @@ -952,14 +919,8 @@ validate_vfunc_blob (GTypelib *typelib, blob = (VFuncBlob*) &typelib->data[offset]; - if (!is_name (typelib->data, blob->name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid vfunc name"); - return FALSE; - } + if (!validate_name (typelib, "vfunc", typelib->data, blob->name, error)) + return FALSE; if (blob->class_closure) { @@ -1035,34 +996,16 @@ validate_struct_blob (GTypelib *typelib, return FALSE; } - if (!is_name (typelib->data, blob->name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid struct name"); - return FALSE; - } + if (!validate_name (typelib, "struct", typelib->data, blob->name, error)) + return FALSE; if (blob_type == BLOB_TYPE_BOXED) { - if (!is_name (typelib->data, blob->gtype_name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid boxed type name"); - return FALSE; - } + if (!validate_name (typelib, "boxed", typelib->data, blob->gtype_name, error)) + return FALSE; - if (!is_name (typelib->data, blob->gtype_init)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid boxed type init"); - return FALSE; - } + if (!validate_name (typelib, "boxed", typelib->data, blob->gtype_init, error)) + return FALSE; } else { @@ -1142,23 +1085,11 @@ validate_enum_blob (GTypelib *typelib, if (!blob->unregistered) { - if (!is_name (typelib->data, blob->gtype_name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid enum type name"); - return FALSE; - } + if (!validate_name (typelib, "enum", typelib->data, blob->gtype_name, error)) + return FALSE; - if (!is_name (typelib->data, blob->gtype_init)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid enum type init"); - return FALSE; - } + if (!validate_name (typelib, "enum", typelib->data, blob->gtype_init, error)) + return FALSE; } else { @@ -1172,14 +1103,8 @@ validate_enum_blob (GTypelib *typelib, } } - if (!is_name (typelib->data, blob->name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid enum name"); - return FALSE; - } + if (!validate_name (typelib, "enum", typelib->data, blob->name, error)) + return FALSE; if (typelib->len < offset + sizeof (EnumBlob) + blob->n_values * sizeof (ValueBlob)) @@ -1256,32 +1181,14 @@ validate_object_blob (GTypelib *typelib, return FALSE; } - if (!is_name (typelib->data, blob->gtype_name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid object type name"); - return FALSE; - } + if (!validate_name (typelib, "object", typelib->data, blob->gtype_name, error)) + return FALSE; - if (!is_name (typelib->data, blob->gtype_init)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid object type init"); - return FALSE; - } + if (!validate_name (typelib, "object", typelib->data, blob->gtype_init, error)) + return FALSE; - if (!is_name (typelib->data, blob->name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid object name"); - return FALSE; - } + if (!validate_name (typelib, "object", typelib->data, blob->name, error)) + return FALSE; if (blob->parent > header->n_entries) { @@ -1428,32 +1335,14 @@ validate_interface_blob (GTypelib *typelib, return FALSE; } - if (!is_name (typelib->data, blob->gtype_name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid interface type name"); - return FALSE; - } + if (!validate_name (typelib, "interface", typelib->data, blob->gtype_name, error)) + return FALSE; - if (!is_name (typelib->data, blob->gtype_init)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid interface type init"); - return FALSE; - } + if (!validate_name (typelib, "interface", typelib->data, blob->gtype_init, error)) + return FALSE; - if (!is_name (typelib->data, blob->name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid interface name"); - return FALSE; - } + if (!validate_name (typelib, "interface", typelib->data, blob->name, error)) + return FALSE; if (typelib->len < offset + sizeof (InterfaceBlob) + (blob->n_prerequisites + blob->n_prerequisites % 2) * 2 + @@ -1642,14 +1531,8 @@ validate_directory (GTypelib *typelib, { entry = g_typelib_get_dir_entry (typelib, i + 1); - if (!is_name (typelib->data, entry->name)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_DIRECTORY, - "Invalid entry name"); - return FALSE; - } + if (!validate_name (typelib, "entry", typelib->data, entry->name, error)) + return FALSE; if ((entry->local && entry->blob_type == BLOB_TYPE_INVALID) || entry->blob_type > BLOB_TYPE_UNION) @@ -1695,14 +1578,8 @@ validate_directory (GTypelib *typelib, return FALSE; } - if (!is_name (typelib->data, entry->offset)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_DIRECTORY, - "Invalid namespace name"); - return FALSE; - } + if (!validate_name (typelib, "namespace", typelib->data, entry->offset, error)) + return FALSE; } } From c66c06f048c7f7492059c06e1a438242b5e0712e Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 21 Aug 2008 16:25:42 +0000 Subject: [PATCH 047/692] Revert change to increment header_size; we do that in write_string. 2008-08-21 Colin Walters * girepository/girmodule.c (g_ir_module_build_typelib): Revert change to increment header_size; we do that in write_string. svn path=/trunk/; revision=440 --- girmodule.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/girmodule.c b/girmodule.c index 1fcdadbce..1077a487f 100644 --- a/girmodule.c +++ b/girmodule.c @@ -104,12 +104,8 @@ g_ir_module_build_typelib (GIrModule *module, /* Adjust size for strings allocated in header below specially */ size += strlen (module->name); - header_size = ALIGN_VALUE (header_size + strlen (module->name) + 1, 4); if (module->shared_library) - { - size += strlen (module->shared_library); - header_size = ALIGN_VALUE (header_size + strlen (module->shared_library) + 1, 4); - } + size += strlen (module->shared_library); g_message ("allocating %d bytes (%d header, %d directory, %d entries)\n", size, header_size, dir_size, size - header_size - dir_size); From bfb52af9030458a24cb404bf8e688b360591287b Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 21 Aug 2008 16:38:03 +0000 Subject: [PATCH 048/692] Plug memory leak and avoid using freed memory. Resolve the whole module 2008-08-21 Johan Dahlin * girepository/girepository.c (g_irepository_require): Plug memory leak and avoid using freed memory. Resolve the whole module path, here as well. svn path=/trunk/; revision=441 --- girepository.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/girepository.c b/girepository.c index 3898c4f8a..cf18a2e80 100644 --- a/girepository.c +++ b/girepository.c @@ -529,7 +529,6 @@ g_irepository_require (GIRepository *repository, if (error1) { g_clear_error (&error1); - g_free (full_path); continue; } @@ -539,12 +538,12 @@ g_irepository_require (GIRepository *repository, if (strcmp (typelib_namespace, namespace) != 0) { - g_free (full_path); g_set_error (error, G_IREPOSITORY_ERROR, G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH, "Typelib file %s for namespace '%s' contains " "namespace '%s' which doesn't match the file name", full_path, namespace, typelib_namespace); + g_free (full_path); return NULL; } break; @@ -552,11 +551,11 @@ g_irepository_require (GIRepository *repository, if (typelib == NULL) { - g_free (full_path); g_set_error (error, G_IREPOSITORY_ERROR, G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, "Typelib file for namespace '%s' was not found in search" " path or could not be openened", namespace); + g_free (full_path); return NULL; } @@ -566,19 +565,25 @@ g_irepository_require (GIRepository *repository, shlib = ((Header *) typelib->data)->shared_library; if (shlib) { + gchar *resolved_shlib; + shlib_fname = g_typelib_get_string (typelib, shlib); - module = g_module_open (shlib_fname, + resolved_shlib = g_module_build_path (NULL, shlib_fname); + + module = g_module_open (resolved_shlib, G_MODULE_BIND_LAZY|G_MODULE_BIND_LOCAL); if (module == NULL) { - g_free (full_path); g_set_error (error, G_IREPOSITORY_ERROR, G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, "Typelib for namespace '%s' references shared library " "%s, but it could not be openened (%s)", - namespace, shlib_fname, g_module_error ()); + namespace, resolved_shlib, g_module_error ()); + g_free (full_path); + g_free (resolved_shlib); return NULL; } + g_free (resolved_shlib); } g_hash_table_remove (table, namespace); From e4c8517aacb396d5d61fe0531dbb8eb0d13752ac Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 22 Aug 2008 20:05:23 +0000 Subject: [PATCH 049/692] Pass through recursive types. Avoid overwriting errors. Always write the 2008-08-22 Colin Walters * girepository/girparser.c: Pass through recursive types. Avoid overwriting errors. * giscanner/xmlwriter.py: Always write the XML header. * tests/*.gir: Adjust. * tests/scanner/Makefile.am: Build typelibs, and generate XML from those. Once we have a good diff mechanism... * tests/scanner/*-expected.gir: Add XML header. * tools/g-ir-scanner: Accept --typelib-xml option. * tools/generate.c: Better defaults for transfer. svn path=/trunk/; revision=457 --- girparser.c | 82 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 24 deletions(-) diff --git a/girparser.c b/girparser.c index 917d37d8e..9a321d2c7 100644 --- a/girparser.c +++ b/girparser.c @@ -57,7 +57,8 @@ typedef enum STATE_NAMESPACE_CONSTANT, /* 25 */ STATE_CLASS_CONSTANT, STATE_INTERFACE_CONSTANT, - STATE_ALIAS + STATE_ALIAS, + STATE_TYPE, } ParseState; typedef struct _ParseContext ParseContext; @@ -72,6 +73,7 @@ struct _ParseContext GIrModule *current_module; GIrNode *current_node; GIrNode *current_typed; + int type_depth; }; #define MISSING_ATTRIBUTE(ctx,error,element,attribute) \ @@ -736,9 +738,19 @@ start_parameter (GMarkupParseContext *context, param->transfer = FALSE; param->shallow_transfer = TRUE; } - else + else { - param->transfer = TRUE; + if (transfer) + { + if (strcmp (transfer, "full") != 0) + g_warning ("Unknown transfer %s", transfer); + else + param->transfer = TRUE; + } + else if (param->in && !param->out) + param->transfer = FALSE; + else + param->transfer = TRUE; param->shallow_transfer = FALSE; } @@ -1371,22 +1383,33 @@ start_type (GMarkupParseContext *context, { const gchar *name; - if (strcmp (element_name, "type") != 0 || - !(ctx->state == STATE_FUNCTION_PARAMETER || - ctx->state == STATE_FUNCTION_RETURN || - ctx->state == STATE_STRUCT_FIELD || - ctx->state == STATE_UNION_FIELD || - ctx->state == STATE_CLASS_PROPERTY || - ctx->state == STATE_CLASS_FIELD || - ctx->state == STATE_INTERFACE_FIELD || - ctx->state == STATE_INTERFACE_PROPERTY || - ctx->state == STATE_BOXED_FIELD || - ctx->state == STATE_NAMESPACE_CONSTANT || - ctx->state == STATE_CLASS_CONSTANT || - ctx->state == STATE_INTERFACE_CONSTANT - )) + if (strcmp (element_name, "type") != 0) return FALSE; + if (ctx->state == STATE_TYPE) + ctx->type_depth++; + else if (ctx->state == STATE_FUNCTION_PARAMETER || + ctx->state == STATE_FUNCTION_RETURN || + ctx->state == STATE_STRUCT_FIELD || + ctx->state == STATE_UNION_FIELD || + ctx->state == STATE_CLASS_PROPERTY || + ctx->state == STATE_CLASS_FIELD || + ctx->state == STATE_INTERFACE_FIELD || + ctx->state == STATE_INTERFACE_PROPERTY || + ctx->state == STATE_BOXED_FIELD || + ctx->state == STATE_NAMESPACE_CONSTANT || + ctx->state == STATE_CLASS_CONSTANT || + ctx->state == STATE_INTERFACE_CONSTANT + ) + { + state_switch (ctx, STATE_TYPE); + ctx->type_depth = 1; + } + + /* FIXME handle recursive types */ + if (ctx->type_depth > 1) + return TRUE; + if (!ctx->current_typed) { g_set_error (error, @@ -1395,7 +1418,7 @@ start_type (GMarkupParseContext *context, "The element is invalid here"); return FALSE; } - + name = find_attribute ("name", attribute_names, attribute_values); if (name == NULL) @@ -2063,12 +2086,13 @@ start_element_handler (GMarkupParseContext *context, g_markup_parse_context_get_position (context, &line_number, &char_number); - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_UNKNOWN_ELEMENT, - "Unexpected start tag '%s' on line %d char %d; current state=%d", - element_name, - line_number, char_number, ctx->state); + if (error && *error == NULL) + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_UNKNOWN_ELEMENT, + "Unexpected start tag '%s' on line %d char %d; current state=%d", + element_name, + line_number, char_number, ctx->state); out: ; if (*error) @@ -2380,6 +2404,15 @@ end_element_handler (GMarkupParseContext *context, } } break; + case STATE_TYPE: + if (strcmp ("type", element_name) == 0) + { + if (ctx->type_depth == 1) + state_switch (ctx, ctx->prev_state); + else + ctx->type_depth -= 1; + break; + } default: g_error ("Unhandled state %d in end_element_handler\n", ctx->state); } @@ -2469,6 +2502,7 @@ g_ir_parse_string (const gchar *buffer, ctx.state = STATE_START; ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + ctx.type_depth = 0; context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL); From 71aacda759be86fe84a5b65bd022696249a157ec Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 22 Aug 2008 22:15:28 +0000 Subject: [PATCH 050/692] Don't hardcode integers, use GITypeTag. 2008-08-22 Colin Walters * girepository/girnode.c: Don't hardcode integers, use GITypeTag. svn path=/trunk/; revision=465 --- girnode.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/girnode.c b/girnode.c index 06e1b8e78..4401080a1 100644 --- a/girnode.c +++ b/girnode.c @@ -1068,12 +1068,12 @@ serialize_type (GIrModule *module, "any" }; - if (node->tag < 20) + if (node->tag < GI_TYPE_TAG_ARRAY) { g_string_append_printf (str, "%s%s", basic[node->tag], node->is_pointer ? "*" : ""); } - else if (node->tag == 20) + else if (node->tag == GI_TYPE_TAG_ARRAY) { serialize_type (module, modules, node->parameter_type1, str); g_string_append (str, "["); @@ -1087,7 +1087,7 @@ serialize_type (GIrModule *module, g_string_append (str, "]"); } - else if (node->tag == 21) + else if (node->tag == GI_TYPE_TAG_INTERFACE) { GIrNode *iface; gchar *name; @@ -1103,7 +1103,7 @@ serialize_type (GIrModule *module, g_string_append_printf (str, "%s%s", name, node->is_pointer ? "*" : ""); } - else if (node->tag == 22) + else if (node->tag == GI_TYPE_TAG_GLIST) { g_string_append (str, "GList"); if (node->parameter_type1) @@ -1113,7 +1113,7 @@ serialize_type (GIrModule *module, g_string_append (str, ">"); } } - else if (node->tag == 23) + else if (node->tag == GI_TYPE_TAG_GSLIST) { g_string_append (str, "GSList"); if (node->parameter_type1) @@ -1123,7 +1123,7 @@ serialize_type (GIrModule *module, g_string_append (str, ">"); } } - else if (node->tag == 24) + else if (node->tag == GI_TYPE_TAG_GHASH) { g_string_append (str, "GHashTable<"); if (node->parameter_type1) @@ -1135,7 +1135,7 @@ serialize_type (GIrModule *module, g_string_append (str, ">"); } } - else if (node->tag == 25) + else if (node->tag == GI_TYPE_TAG_ERROR) { g_string_append (str, "GError"); if (node->errors) From ca6a30f98a4666db1e2d10ab7281f77809c32449 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 23 Aug 2008 16:11:01 +0000 Subject: [PATCH 051/692] Ignore . Parse them. Generate them. Process 2008-08-22 Colin Walters * girepository/girparser.c: Ignore . * giscanner/girparser.py: Parse them. * giscanner/girwriter.py: Generate them. * giscanner/transformer.py: Process recursively. Don't require full path for includes, look in {$XDG_DATA_DIRS}/gir. * tools/g-ir-scanner: Pass through includes. * Makefile.am: Remove extra --include args for scanner. * *-expected.gir: Add expected includes. svn path=/trunk/; revision=467 --- girparser.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/girparser.c b/girparser.c index 9a321d2c7..5b428564f 100644 --- a/girparser.c +++ b/girparser.c @@ -32,29 +32,30 @@ typedef enum STATE_START, STATE_END, STATE_REPOSITORY, + STATE_INCLUDE, STATE_NAMESPACE, - STATE_ENUM, - STATE_BITFIELD, /* 5 */ + STATE_ENUM, /* 5 */ + STATE_BITFIELD, STATE_FUNCTION, STATE_FUNCTION_RETURN, STATE_FUNCTION_PARAMETERS, - STATE_FUNCTION_PARAMETER, - STATE_CLASS, /* 10 */ + STATE_FUNCTION_PARAMETER, /* 10 */ + STATE_CLASS, STATE_CLASS_FIELD, STATE_CLASS_PROPERTY, STATE_INTERFACE, - STATE_INTERFACE_PROPERTY, - STATE_INTERFACE_FIELD, /* 15 */ + STATE_INTERFACE_PROPERTY, /* 15 */ + STATE_INTERFACE_FIELD, STATE_IMPLEMENTS, STATE_REQUIRES, STATE_BOXED, - STATE_BOXED_FIELD, - STATE_STRUCT, /* 20 */ + STATE_BOXED_FIELD, /* 20 */ + STATE_STRUCT, STATE_STRUCT_FIELD, STATE_ERRORDOMAIN, STATE_UNION, - STATE_UNION_FIELD, - STATE_NAMESPACE_CONSTANT, /* 25 */ + STATE_UNION_FIELD, /* 25 */ + STATE_NAMESPACE_CONSTANT, STATE_CLASS_CONSTANT, STATE_INTERFACE_CONSTANT, STATE_ALIAS, @@ -1922,6 +1923,12 @@ start_element_handler (GMarkupParseContext *context, break; case 'i': + if (strcmp (element_name, "include") == 0 && + ctx->state == STATE_REPOSITORY) + { + state_switch (ctx, STATE_INCLUDE); + goto out; + } if (start_interface (context, element_name, attribute_names, attribute_values, ctx, error)) @@ -2174,6 +2181,13 @@ end_element_handler (GMarkupParseContext *context, state_switch (ctx, STATE_END); break; + case STATE_INCLUDE: + if (require_end_element (context, ctx, "include", element_name, error)) + { + state_switch (ctx, STATE_REPOSITORY); + } + break; + case STATE_NAMESPACE: if (require_end_element (context, ctx, "namespace", element_name, error)) { From 20b10e4542b9cd979f5ab307ad5c9c8548fbdc5e Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 23 Aug 2008 16:36:15 +0000 Subject: [PATCH 052/692] Add debug print, fix includes svn path=/trunk/; revision=470 --- girparser.c | 1 + 1 file changed, 1 insertion(+) diff --git a/girparser.c b/girparser.c index 5b428564f..df2d6c1f2 100644 --- a/girparser.c +++ b/girparser.c @@ -467,6 +467,7 @@ parse_type (ParseContext *ctx, const gchar *type) str = g_strdup (type); node = parse_type_internal (str, &rest); g_free (str); + g_debug ("Parsed type: %s => %d", type, node->tag); return node; } From 6d34368cacd2fd9163233c908385b604f0c8daa2 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 23 Aug 2008 16:46:58 +0000 Subject: [PATCH 053/692] Another debug print svn path=/trunk/; revision=471 --- girnode.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/girnode.c b/girnode.c index 4401080a1..b6522d82e 100644 --- a/girnode.c +++ b/girnode.c @@ -1390,7 +1390,9 @@ g_ir_node_build_typelib (GIrNode *node, blob->name = write_string (node->name, strings, data, offset2); blob->symbol = write_string (function->symbol, strings, data, offset2); blob->signature = signature; - + + g_debug ("building function '%s'", function->symbol); + g_ir_node_build_typelib ((GIrNode *)function->result->type, module, modules, strings, types, data, &signature, offset2); @@ -1411,6 +1413,7 @@ g_ir_node_build_typelib (GIrNode *node, module, modules, strings, types, data, &signature, offset2); } + } break; From 4c2a09226b5ad6d69d5478c8f99232cc00d86f22 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 23 Aug 2008 21:29:58 +0000 Subject: [PATCH 054/692] Remove duplicate start_boxed. svn path=/trunk/; revision=474 --- girparser.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/girparser.c b/girparser.c index df2d6c1f2..c816bd69a 100644 --- a/girparser.c +++ b/girparser.c @@ -1917,10 +1917,6 @@ start_element_handler (GMarkupParseContext *context, attribute_names, attribute_values, ctx, error)) goto out; - else if (start_glib_boxed (context, element_name, - attribute_names, attribute_values, - ctx, error)) - goto out; break; case 'i': From 5daf51a5807b259a4a43eab62a31cb2b33c1f0cd Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 23 Aug 2008 21:30:01 +0000 Subject: [PATCH 055/692] Redo signature_offset to be cleaner and correct for vfuncs svn path=/trunk/; revision=475 --- ginfo.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/ginfo.c b/ginfo.c index 492d660ea..b48541aa2 100644 --- a/ginfo.c +++ b/ginfo.c @@ -515,16 +515,24 @@ g_function_info_get_vfunc (GIFunctionInfo *info) static guint32 signature_offset (GICallableInfo *info) { + int sigoff = -1; switch (info->base.type) { case GI_INFO_TYPE_FUNCTION: + sigoff = G_STRUCT_OFFSET (FunctionBlob, signature); + break; case GI_INFO_TYPE_VFUNC: - return *(guint32 *)&info->base.typelib->data[info->base.offset + 12]; + sigoff = G_STRUCT_OFFSET (VFuncBlob, signature); + break; case GI_INFO_TYPE_CALLBACK: + sigoff = G_STRUCT_OFFSET (CallbackBlob, signature); + break; case GI_INFO_TYPE_SIGNAL: - return *(guint32 *)&info->base.typelib->data[info->base.offset + 8]; + sigoff = G_STRUCT_OFFSET (SignalBlob, signature); + break; } - + if (sigoff >= 0) + return *(guint32 *)&info->base.typelib->data[info->base.offset + sigoff]; return 0; } From a2678afc9cfe82d74fdcf48074b928eb6ae1a86c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 23 Aug 2008 21:30:06 +0000 Subject: [PATCH 056/692] Add debug bit, tweak to use GUINT as correct. svn path=/trunk/; revision=476 --- girnode.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/girnode.c b/girnode.c index b6522d82e..ce3e9ba00 100644 --- a/girnode.c +++ b/girnode.c @@ -1011,6 +1011,8 @@ find_entry_node (GIrModule *module, result = node; + g_debug ("Creating XREF: %s %s", names[0], names[1]); + goto out; } @@ -1204,13 +1206,13 @@ g_ir_node_build_typelib (GIrNode *node, value = g_hash_table_lookup (types, s); if (value) { - blob->offset = GPOINTER_TO_INT (value); + blob->offset = GPOINTER_TO_UINT (value); g_free (s); } else { unique_types_count += 1; - g_hash_table_insert (types, s, GINT_TO_POINTER(*offset2)); + g_hash_table_insert (types, s, GUINT_TO_POINTER(*offset2)); blob->offset = *offset2; switch (type->tag) From 88f221c38e0c55e166050e65c0a60e540cb9ed46 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 23 Aug 2008 21:30:09 +0000 Subject: [PATCH 057/692] Check constructor returns svn path=/trunk/; revision=477 --- gtypelib.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 125 insertions(+), 15 deletions(-) diff --git a/gtypelib.c b/gtypelib.c index 53684fdb7..858cd3ccc 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -30,6 +30,46 @@ #define ALIGN_VALUE(this, boundary) \ (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) +static gboolean +validate_interface_blob (GTypelib *typelib, + guint32 offset, + GError **error); + +static InterfaceTypeBlob * +get_type_blob (GTypelib *typelib, + const char *funcname, + SimpleTypeBlob *simple, + GError **error) +{ + if (simple->offset == 0) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "Expected blob for type"); + return FALSE; + } + + if (simple->reserved == 0 && simple->reserved2 == 0) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "Expected non-basic type in function %s, got %d", funcname, + simple->tag); + return FALSE; + } + + if (typelib->len < simple->offset + sizeof (CommonBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + return (InterfaceTypeBlob*) &typelib->data[simple->offset]; +} DirEntry * g_typelib_get_dir_entry (GTypelib *typelib, @@ -80,26 +120,41 @@ is_aligned (guint32 offset) #define MAX_NAME_LEN 200 +static const char * +get_string (GTypelib *typelib, guint32 offset, GError **error) +{ + if (typelib->len < offset) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "Buffer is too short while looking up name"); + return NULL; + } + + return (const char*)&typelib->data[offset]; +} + +static const char * +get_string_nofail (GTypelib *typelib, guint32 offset) +{ + const char *ret = get_string (typelib, offset, NULL); + g_assert (ret); + return ret; +} + static gboolean validate_name (GTypelib *typelib, const char *msg, const guchar *data, guint32 offset, GError **error) { - gchar *name; + const char *name; - if (typelib->len < offset) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID, - "The buffer is too short for type %s", - msg); - return FALSE; - } + name = get_string (typelib, offset, error); + if (!name) + return FALSE; - name = (gchar*)&data[offset]; - if (!memchr (name, '\0', MAX_NAME_LEN)) { g_set_error (error, @@ -502,6 +557,34 @@ validate_arg_blob (GTypelib *typelib, return TRUE; } +static SimpleTypeBlob * +return_type_from_signature (GTypelib *typelib, + guint32 offset, + GError **error) +{ + SignatureBlob *blob; + if (typelib->len < offset + sizeof (SignatureBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return NULL; + } + + blob = (SignatureBlob*) &typelib->data[offset]; + if (blob->return_type.offset == 0) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "No return type found in signature"); + return NULL; + } + + return (SimpleTypeBlob *)&typelib->data[offset + G_STRUCT_OFFSET (SignatureBlob, return_type)]; +} + static gboolean validate_signature_blob (GTypelib *typelib, guint32 offset, @@ -551,6 +634,8 @@ validate_function_blob (GTypelib *typelib, GError **error) { FunctionBlob *blob; + SignatureBlob *sigblob; + const char *funcname; if (typelib->len < offset + sizeof (FunctionBlob)) { @@ -574,6 +659,8 @@ validate_function_blob (GTypelib *typelib, if (!validate_name (typelib, "function", typelib->data, blob->name, error)) return FALSE; + + funcname = get_string_nofail (typelib, blob->name); if (!validate_name (typelib, "function symbol", typelib->data, blob->symbol, error)) return FALSE; @@ -590,7 +677,7 @@ validate_function_blob (GTypelib *typelib, g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, - "Constructor not allowed"); + "Constructor %s not allowed", funcname); return FALSE; } } @@ -625,10 +712,33 @@ validate_function_blob (GTypelib *typelib, /* FIXME: validate index range */ /* FIXME: validate "this" argument for methods */ - /* FIXME: validate return type for constructors */ if (!validate_signature_blob (typelib, blob->signature, error)) return FALSE; + + sigblob = (SignatureBlob*) &typelib->data[blob->signature]; + + if (blob->constructor) + { + SimpleTypeBlob *simple = return_type_from_signature (typelib, + blob->signature, + error); + InterfaceTypeBlob *iface; + if (!simple) + return FALSE; + iface = get_type_blob (typelib, funcname, simple, error); + if (!iface) + return FALSE; + if (!(iface->tag == GI_TYPE_TAG_INTERFACE)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "Invalid return type %d for constructor %s", + iface->tag, funcname); + return FALSE; + } + } return TRUE; } @@ -1331,7 +1441,7 @@ validate_interface_blob (GTypelib *typelib, g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, - "Wrong blob type"); + "Wrong blob type; expected interface, got %d", blob->blob_type); return FALSE; } From 78f4434ef63be0afad0713197dc88af7786057ca Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 24 Aug 2008 10:43:02 +0000 Subject: [PATCH 058/692] Remove left-over code, checking type of function. 2008-08-24 Johan Dahlin * girepository/girparser.c (start_function): Remove left-over code, checking type of function. svn path=/trunk/; revision=480 --- girparser.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/girparser.c b/girparser.c index c816bd69a..905c315af 100644 --- a/girparser.c +++ b/girparser.c @@ -551,12 +551,10 @@ start_function (GMarkupParseContext *context, const gchar *name; const gchar *symbol; const gchar *deprecated; - const gchar *type; name = find_attribute ("name", attribute_names, attribute_values); symbol = find_attribute ("c:identifier", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - type = find_attribute ("type", attribute_names, attribute_values); if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); @@ -581,11 +579,6 @@ start_function (GMarkupParseContext *context, { function->is_method = TRUE; - if (type && strcmp (type, "setter") == 0) - function->is_setter = TRUE; - else if (type && strcmp (type, "getter") == 0) - function->is_getter = TRUE; - if (strcmp (element_name, "constructor") == 0) function->is_constructor = TRUE; else From ed13aae5f2ec1b44b37514e7a37b0b4895713706 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 24 Aug 2008 11:01:44 +0000 Subject: [PATCH 059/692] Refactor a couple of parsing functions to be simpler to follow. Avoid huge 2008-08-24 Johan Dahlin * girepository/girparser.c (start_glib_boxed), (start_function), (start_field), (start_alias): Refactor a couple of parsing functions to be simpler to follow. Avoid huge ifs. svn path=/trunk/; revision=481 --- girparser.c | 568 +++++++++++++++++++++++++++------------------------- 1 file changed, 296 insertions(+), 272 deletions(-) diff --git a/girparser.c b/girparser.c index 905c315af..c9d252975 100644 --- a/girparser.c +++ b/girparser.c @@ -480,50 +480,54 @@ start_glib_boxed (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "glib:boxed") == 0 && - ctx->state == STATE_NAMESPACE) - { - const gchar *name; - const gchar *typename; - const gchar *typeinit; - const gchar *deprecated; - - name = find_attribute ("glib:name", attribute_names, attribute_values); - typename = find_attribute ("glib:type-name", attribute_names, attribute_values); - typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "glib:name"); - else if (typename == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); - else if (typeinit == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); - else - { - GIrNodeBoxed *boxed; + const gchar *name; + const gchar *typename; + const gchar *typeinit; + const gchar *deprecated; + GIrNodeBoxed *boxed; - boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED); - - ((GIrNode *)boxed)->name = g_strdup (name); - boxed->gtype_name = g_strdup (typename); - boxed->gtype_init = g_strdup (typeinit); - if (deprecated && strcmp (deprecated, "1") == 0) - boxed->deprecated = TRUE; - else - boxed->deprecated = FALSE; - - ctx->current_node = (GIrNode *)boxed; - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, boxed); - - state_switch (ctx, STATE_BOXED); - } - - return TRUE; + if (!(strcmp (element_name, "glib:boxed") == 0 && + ctx->state == STATE_NAMESPACE)) + return FALSE; + + name = find_attribute ("glib:name", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:name"); + return FALSE; + } + else if (typename == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); + return FALSE; + } + else if (typeinit == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); + return FALSE; } - return FALSE; + boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED); + + ((GIrNode *)boxed)->name = g_strdup (name); + boxed->gtype_name = g_strdup (typename); + boxed->gtype_init = g_strdup (typeinit); + if (deprecated && strcmp (deprecated, "1") == 0) + boxed->deprecated = TRUE; + else + boxed->deprecated = FALSE; + + ctx->current_node = (GIrNode *)boxed; + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, boxed); + + state_switch (ctx, STATE_BOXED); + + return TRUE; } static gboolean @@ -534,118 +538,129 @@ start_function (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if ((ctx->state == STATE_NAMESPACE && - (strcmp (element_name, "function") == 0 || - strcmp (element_name, "callback") == 0)) || - ((ctx->state == STATE_CLASS || - ctx->state == STATE_INTERFACE || - ctx->state == STATE_BOXED || - ctx->state == STATE_UNION) && - (strcmp (element_name, "method") == 0 || - strcmp (element_name, "callback") == 0)) || - ((ctx->state == STATE_CLASS || - ctx->state == STATE_BOXED) && - (strcmp (element_name, "constructor") == 0)) || - (ctx->state == STATE_STRUCT && strcmp (element_name, "callback") == 0)) + const gchar *name; + const gchar *symbol; + const gchar *deprecated; + GIrNodeFunction *function; + gboolean found = FALSE; + + switch (ctx->state) { - const gchar *name; - const gchar *symbol; - const gchar *deprecated; - - name = find_attribute ("name", attribute_names, attribute_values); - symbol = find_attribute ("c:identifier", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else if (strcmp (element_name, "callback") != 0 && symbol == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "c:identifier"); - else - { - GIrNodeFunction *function; - - function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION); - - ((GIrNode *)function)->name = g_strdup (name); - function->symbol = g_strdup (symbol); - function->parameters = NULL; - if (deprecated && strcmp (deprecated, "1") == 0) - function->deprecated = TRUE; - else - function->deprecated = FALSE; - - if (strcmp (element_name, "method") == 0 || - strcmp (element_name, "constructor") == 0) - { - function->is_method = TRUE; - - if (strcmp (element_name, "constructor") == 0) - function->is_constructor = TRUE; - else - function->is_constructor = FALSE; - } - else - { - function->is_method = FALSE; - function->is_setter = FALSE; - function->is_getter = FALSE; - function->is_constructor = FALSE; - if (strcmp (element_name, "callback") == 0) - ((GIrNode *)function)->type = G_IR_NODE_CALLBACK; - } - - if (ctx->current_node == NULL) - { - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, function); - } - else - switch (ctx->current_node->type) - { - case G_IR_NODE_INTERFACE: - case G_IR_NODE_OBJECT: - { - GIrNodeInterface *iface; - - iface = (GIrNodeInterface *)ctx->current_node; - iface->members = g_list_append (iface->members, function); - } - break; - case G_IR_NODE_BOXED: - { - GIrNodeBoxed *boxed; - - boxed = (GIrNodeBoxed *)ctx->current_node; - boxed->members = g_list_append (boxed->members, function); - } - break; - case G_IR_NODE_STRUCT: - { - GIrNodeStruct *struct_; - - struct_ = (GIrNodeStruct *)ctx->current_node; - struct_->members = g_list_append (struct_->members, function); } - break; - case G_IR_NODE_UNION: - { - GIrNodeUnion *union_; - - union_ = (GIrNodeUnion *)ctx->current_node; - union_->members = g_list_append (union_->members, function); - } - break; - default: - g_assert_not_reached (); - } - - ctx->current_node = (GIrNode *)function; - state_switch (ctx, STATE_FUNCTION); - - return TRUE; - } + case STATE_NAMESPACE: + found = (strcmp (element_name, "function") == 0 || + strcmp (element_name, "callback") == 0); + break; + case STATE_CLASS: + case STATE_BOXED: + case STATE_STRUCT: + case STATE_UNION: + found = strcmp (element_name, "constructor") == 0; + /* fallthrough */ + case STATE_INTERFACE: + found = (found || + strcmp (element_name, "method") == 0 || + strcmp (element_name, "callback") == 0); + break; + default: + break; } - return FALSE; + if (!found) + return FALSE; + + name = find_attribute ("name", attribute_names, attribute_values); + symbol = find_attribute ("c:identifier", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; + } + else if (strcmp (element_name, "callback") != 0 && symbol == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "c:identifier"); + return FALSE; + } + + function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION); + + ((GIrNode *)function)->name = g_strdup (name); + function->symbol = g_strdup (symbol); + function->parameters = NULL; + if (deprecated && strcmp (deprecated, "1") == 0) + function->deprecated = TRUE; + else + function->deprecated = FALSE; + + if (strcmp (element_name, "method") == 0 || + strcmp (element_name, "constructor") == 0) + { + function->is_method = TRUE; + + if (strcmp (element_name, "constructor") == 0) + function->is_constructor = TRUE; + else + function->is_constructor = FALSE; + } + else + { + function->is_method = FALSE; + function->is_setter = FALSE; + function->is_getter = FALSE; + function->is_constructor = FALSE; + if (strcmp (element_name, "callback") == 0) + ((GIrNode *)function)->type = G_IR_NODE_CALLBACK; + } + + if (ctx->current_node == NULL) + { + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, function); + } + else + switch (ctx->current_node->type) + { + case G_IR_NODE_INTERFACE: + case G_IR_NODE_OBJECT: + { + GIrNodeInterface *iface; + + iface = (GIrNodeInterface *)ctx->current_node; + iface->members = g_list_append (iface->members, function); + } + break; + case G_IR_NODE_BOXED: + { + GIrNodeBoxed *boxed; + + boxed = (GIrNodeBoxed *)ctx->current_node; + boxed->members = g_list_append (boxed->members, function); + } + break; + case G_IR_NODE_STRUCT: + { + GIrNodeStruct *struct_; + + struct_ = (GIrNodeStruct *)ctx->current_node; + struct_->members = g_list_append (struct_->members, function); } + break; + case G_IR_NODE_UNION: + { + GIrNodeUnion *union_; + + union_ = (GIrNodeUnion *)ctx->current_node; + union_->members = g_list_append (union_->members, function); + } + break; + default: + g_assert_not_reached (); + } + + ctx->current_node = (GIrNode *)function; + state_switch (ctx, STATE_FUNCTION); + + return TRUE; } static gboolean @@ -793,123 +808,129 @@ start_field (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "field") == 0 && - (ctx->state == STATE_CLASS || - ctx->state == STATE_BOXED || - ctx->state == STATE_STRUCT || - ctx->state == STATE_UNION || - ctx->state == STATE_INTERFACE)) + const gchar *name; + const gchar *readable; + const gchar *writable; + const gchar *bits; + const gchar *branch; + const gchar *offset; + GIrNodeField *field; + + switch (ctx->state) { - const gchar *name; - const gchar *readable; - const gchar *writable; - const gchar *bits; - const gchar *branch; - const gchar *offset; - - name = find_attribute ("name", attribute_names, attribute_values); - readable = find_attribute ("readable", attribute_names, attribute_values); - writable = find_attribute ("writable", attribute_names, attribute_values); - bits = find_attribute ("bits", attribute_names, attribute_values); - branch = find_attribute ("branch", attribute_names, attribute_values); - offset = find_attribute ("offset", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { - GIrNodeField *field; - - field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD); - ctx->current_typed = (GIrNode*) field; - ((GIrNode *)field)->name = g_strdup (name); - if (readable && strcmp (readable, "1") == 0) - field->readable = TRUE; - else - field->readable = FALSE; - - if (writable && strcmp (writable, "1") == 0) - field->writable = TRUE; - else - field->writable = FALSE; - - if (bits) - field->bits = atoi (bits); - else - field->bits = 0; - - if (offset) - field->offset = atoi (offset); - else - field->offset = 0; - - switch (ctx->current_node->type) - { - case G_IR_NODE_OBJECT: - { - GIrNodeInterface *iface; - - iface = (GIrNodeInterface *)ctx->current_node; - iface->members = g_list_append (iface->members, field); - state_switch (ctx, STATE_CLASS_FIELD); - } - break; - case G_IR_NODE_INTERFACE: - { - GIrNodeInterface *iface; - - iface = (GIrNodeInterface *)ctx->current_node; - iface->members = g_list_append (iface->members, field); - state_switch (ctx, STATE_INTERFACE_FIELD); - } - break; - case G_IR_NODE_BOXED: - { - GIrNodeBoxed *boxed; - - boxed = (GIrNodeBoxed *)ctx->current_node; - boxed->members = g_list_append (boxed->members, field); - state_switch (ctx, STATE_BOXED_FIELD); - } - break; - case G_IR_NODE_STRUCT: - { - GIrNodeStruct *struct_; - - struct_ = (GIrNodeStruct *)ctx->current_node; - struct_->members = g_list_append (struct_->members, field); - state_switch (ctx, STATE_STRUCT_FIELD); - } - break; - case G_IR_NODE_UNION: - { - GIrNodeUnion *union_; - - union_ = (GIrNodeUnion *)ctx->current_node; - union_->members = g_list_append (union_->members, field); - if (branch) - { - GIrNodeConstant *constant; - - constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT); - ((GIrNode *)constant)->name = g_strdup (name); - constant->value = g_strdup (branch); - constant->type = union_->discriminator_type; - constant->deprecated = FALSE; - - union_->discriminators = g_list_append (union_->discriminators, constant); - } - state_switch (ctx, STATE_UNION_FIELD); - } - break; - default: - g_assert_not_reached (); - } - } - return TRUE; + case STATE_CLASS: + case STATE_BOXED: + case STATE_STRUCT: + case STATE_UNION: + case STATE_INTERFACE: + break; + default: + return FALSE; } - return FALSE; + if (strcmp (element_name, "field") != 0) + return FALSE; + + name = find_attribute ("name", attribute_names, attribute_values); + readable = find_attribute ("readable", attribute_names, attribute_values); + writable = find_attribute ("writable", attribute_names, attribute_values); + bits = find_attribute ("bits", attribute_names, attribute_values); + branch = find_attribute ("branch", attribute_names, attribute_values); + offset = find_attribute ("offset", attribute_names, attribute_values); + + if (name == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; + } + + field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD); + ctx->current_typed = (GIrNode*) field; + ((GIrNode *)field)->name = g_strdup (name); + if (readable && strcmp (readable, "1") == 0) + field->readable = TRUE; + else + field->readable = FALSE; + + if (writable && strcmp (writable, "1") == 0) + field->writable = TRUE; + else + field->writable = FALSE; + + if (bits) + field->bits = atoi (bits); + else + field->bits = 0; + + if (offset) + field->offset = atoi (offset); + else + field->offset = 0; + + switch (ctx->current_node->type) + { + case G_IR_NODE_OBJECT: + { + GIrNodeInterface *iface; + + iface = (GIrNodeInterface *)ctx->current_node; + iface->members = g_list_append (iface->members, field); + state_switch (ctx, STATE_CLASS_FIELD); + } + break; + case G_IR_NODE_INTERFACE: + { + GIrNodeInterface *iface; + + iface = (GIrNodeInterface *)ctx->current_node; + iface->members = g_list_append (iface->members, field); + state_switch (ctx, STATE_INTERFACE_FIELD); + } + break; + case G_IR_NODE_BOXED: + { + GIrNodeBoxed *boxed; + + boxed = (GIrNodeBoxed *)ctx->current_node; + boxed->members = g_list_append (boxed->members, field); + state_switch (ctx, STATE_BOXED_FIELD); + } + break; + case G_IR_NODE_STRUCT: + { + GIrNodeStruct *struct_; + + struct_ = (GIrNodeStruct *)ctx->current_node; + struct_->members = g_list_append (struct_->members, field); + state_switch (ctx, STATE_STRUCT_FIELD); + } + break; + case G_IR_NODE_UNION: + { + GIrNodeUnion *union_; + + union_ = (GIrNodeUnion *)ctx->current_node; + union_->members = g_list_append (union_->members, field); + if (branch) + { + GIrNodeConstant *constant; + + constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT); + ((GIrNode *)constant)->name = g_strdup (name); + constant->value = g_strdup (branch); + constant->type = union_->discriminator_type; + constant->deprecated = FALSE; + + union_->discriminators = g_list_append (union_->discriminators, constant); + } + state_switch (ctx, STATE_UNION_FIELD); + } + break; + default: + g_assert_not_reached (); + } + + return TRUE; } static gboolean @@ -925,18 +946,21 @@ start_alias (GMarkupParseContext *context, const gchar *type; name = find_attribute ("name", attribute_names, attribute_values); - if (name == NULL) { - MISSING_ATTRIBUTE (context, error, element_name, "name"); - return FALSE; - } + if (name == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; + } target = find_attribute ("target", attribute_names, attribute_values); - if (name == NULL) { - MISSING_ATTRIBUTE (context, error, element_name, "target"); - return FALSE; - } + if (name == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "target"); + return FALSE; + } g_hash_table_insert (ctx->aliases, g_strdup (name), g_strdup (target)); + return TRUE; } From 1ebc6cfb7a979102eaf715ec7257d73ad2cd843f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 24 Aug 2008 16:51:43 +0000 Subject: [PATCH 060/692] Add context stack so when we get an error we can print out nicely where it 2008-08-24 Colin Walters * girepository/gtypelib.c: Add context stack so when we get an error we can print out nicely where it is. svn path=/trunk/; revision=482 --- gtypelib.c | 238 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 176 insertions(+), 62 deletions(-) diff --git a/gtypelib.c b/gtypelib.c index 858cd3ccc..4fd5193cc 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -26,18 +26,83 @@ #include "gtypelib.h" +typedef struct { + GTypelib *typelib; + GSList *context_stack; +} ValidateContext; #define ALIGN_VALUE(this, boundary) \ (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) +static void +push_context (ValidateContext *ctx, const char *name) +{ + ctx->context_stack = g_slist_prepend (ctx->context_stack, (char*)name); +} + +static void +pop_context (ValidateContext *ctx) +{ + g_assert (ctx->context_stack != NULL); + ctx->context_stack = g_slist_delete_link (ctx->context_stack, + ctx->context_stack); +} + static gboolean -validate_interface_blob (GTypelib *typelib, +validate_interface_blob (ValidateContext *ctx, guint32 offset, GError **error); +DirEntry * +get_dir_entry_checked (GTypelib *typelib, + guint16 index, + GError **error) +{ + Header *header = (Header *)typelib->data; + guint32 offset; + + if (index == 0 || index > header->n_entries) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid directory index %d", index); + return FALSE; + } + + offset = header->directory + (index - 1) * header->entry_blob_size; + + if (typelib->len < offset + sizeof (DirEntry)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + + return (DirEntry *)&typelib->data[offset]; +} + + +static CommonBlob * +get_blob (GTypelib *typelib, + guint32 offset, + GError **error) +{ + if (typelib->len < offset + sizeof (CommonBlob)) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "The buffer is too short"); + return FALSE; + } + return (CommonBlob *)&typelib->data[offset]; +} + static InterfaceTypeBlob * get_type_blob (GTypelib *typelib, - const char *funcname, SimpleTypeBlob *simple, GError **error) { @@ -55,20 +120,12 @@ get_type_blob (GTypelib *typelib, g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID, - "Expected non-basic type in function %s, got %d", funcname, + "Expected non-basic type but got %d", simple->tag); return FALSE; } - if (typelib->len < simple->offset + sizeof (CommonBlob)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID, - "The buffer is too short"); - return FALSE; - } - return (InterfaceTypeBlob*) &typelib->data[simple->offset]; + return (InterfaceTypeBlob*) get_blob (typelib, simple->offset, error); } DirEntry * @@ -144,7 +201,7 @@ get_string_nofail (GTypelib *typelib, guint32 offset) } static gboolean -validate_name (GTypelib *typelib, +validate_name (GTypelib *typelib, const char *msg, const guchar *data, guint32 offset, GError **error) @@ -179,9 +236,10 @@ validate_name (GTypelib *typelib, } static gboolean -validate_header (GTypelib *typelib, - GError **error) +validate_header (ValidateContext *ctx, + GError **error) { + GTypelib *typelib = ctx->typelib; Header *header; if (typelib->len < sizeof (Header)) @@ -336,20 +394,16 @@ validate_iface_type_blob (GTypelib *typelib, GError **error) { InterfaceTypeBlob *blob; - Header *header; - - header = (Header *)typelib->data; + InterfaceBlob *target; blob = (InterfaceTypeBlob*)&typelib->data[offset]; - if (blob->interface == 0 || blob->interface > header->n_entries) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid directory index %d", blob->interface); - return FALSE; - } + target = (InterfaceBlob*) get_dir_entry_checked (typelib, blob->interface, error); + + if (!target) + return FALSE; + if (target->blob_type == 0) /* non-local */ + return TRUE; return TRUE; } @@ -628,14 +682,14 @@ validate_signature_blob (GTypelib *typelib, } static gboolean -validate_function_blob (GTypelib *typelib, +validate_function_blob (ValidateContext *ctx, guint32 offset, guint16 container_type, GError **error) { + GTypelib *typelib = ctx->typelib; FunctionBlob *blob; SignatureBlob *sigblob; - const char *funcname; if (typelib->len < offset + sizeof (FunctionBlob)) { @@ -660,7 +714,7 @@ validate_function_blob (GTypelib *typelib, if (!validate_name (typelib, "function", typelib->data, blob->name, error)) return FALSE; - funcname = get_string_nofail (typelib, blob->name); + push_context (ctx, get_string_nofail (typelib, blob->name)); if (!validate_name (typelib, "function symbol", typelib->data, blob->symbol, error)) return FALSE; @@ -677,7 +731,7 @@ validate_function_blob (GTypelib *typelib, g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, - "Constructor %s not allowed", funcname); + "Constructor not allowed"); return FALSE; } } @@ -723,31 +777,36 @@ validate_function_blob (GTypelib *typelib, SimpleTypeBlob *simple = return_type_from_signature (typelib, blob->signature, error); - InterfaceTypeBlob *iface; + InterfaceTypeBlob *iface_type; + InterfaceBlob *iface; + if (!simple) return FALSE; - iface = get_type_blob (typelib, funcname, simple, error); - if (!iface) + iface_type = get_type_blob (typelib, simple, error); + if (!iface_type) return FALSE; - if (!(iface->tag == GI_TYPE_TAG_INTERFACE)) + if (!(iface_type->tag == GI_TYPE_TAG_INTERFACE)) { g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID, - "Invalid return type %d for constructor %s", - iface->tag, funcname); + "Invalid return type %d for constructor", + iface_type->tag); return FALSE; } } - + + pop_context (ctx); + return TRUE; } static gboolean -validate_callback_blob (GTypelib *typelib, +validate_callback_blob (ValidateContext *ctx, guint32 offset, GError **error) { + GTypelib *typelib = ctx->typelib; CallbackBlob *blob; if (typelib->len < offset + sizeof (CallbackBlob)) @@ -772,9 +831,13 @@ validate_callback_blob (GTypelib *typelib, if (!validate_name (typelib, "callback", typelib->data, blob->name, error)) return FALSE; + + push_context (ctx, get_string_nofail (typelib, blob->name)); if (!validate_signature_blob (typelib, blob->signature, error)) return FALSE; + + pop_context (ctx); return TRUE; } @@ -1068,11 +1131,12 @@ validate_vfunc_blob (GTypelib *typelib, } static gboolean -validate_struct_blob (GTypelib *typelib, +validate_struct_blob (ValidateContext *ctx, guint32 offset, guint16 blob_type, GError **error) { + GTypelib *typelib = ctx->typelib; StructBlob *blob; gint i; @@ -1108,6 +1172,8 @@ validate_struct_blob (GTypelib *typelib, if (!validate_name (typelib, "struct", typelib->data, blob->name, error)) return FALSE; + + push_context (ctx, get_string_nofail (typelib, blob->name)); if (blob_type == BLOB_TYPE_BOXED) { @@ -1151,7 +1217,7 @@ validate_struct_blob (GTypelib *typelib, for (i = 0; i < blob->n_methods; i++) { - if (!validate_function_blob (typelib, + if (!validate_function_blob (ctx, offset + sizeof (StructBlob) + blob->n_fields * sizeof (FieldBlob) + i * sizeof (FunctionBlob), @@ -1160,6 +1226,8 @@ validate_struct_blob (GTypelib *typelib, return FALSE; } + pop_context (ctx); + return TRUE; } @@ -1260,10 +1328,11 @@ validate_enum_blob (GTypelib *typelib, } static gboolean -validate_object_blob (GTypelib *typelib, +validate_object_blob (ValidateContext *ctx, guint32 offset, GError **error) { + GTypelib *typelib = ctx->typelib; Header *header; ObjectBlob *blob; gint i; @@ -1388,7 +1457,7 @@ validate_object_blob (GTypelib *typelib, for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob)) { - if (!validate_function_blob (typelib, offset2, BLOB_TYPE_OBJECT, error)) + if (!validate_function_blob (ctx, offset2, BLOB_TYPE_OBJECT, error)) return FALSE; } @@ -1414,10 +1483,11 @@ validate_object_blob (GTypelib *typelib, } static gboolean -validate_interface_blob (GTypelib *typelib, +validate_interface_blob (ValidateContext *ctx, guint32 offset, GError **error) { + GTypelib *typelib = ctx->typelib; Header *header; InterfaceBlob *blob; gint i; @@ -1510,7 +1580,7 @@ validate_interface_blob (GTypelib *typelib, for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob)) { - if (!validate_function_blob (typelib, offset2, BLOB_TYPE_INTERFACE, error)) + if (!validate_function_blob (ctx, offset2, BLOB_TYPE_INTERFACE, error)) return FALSE; } @@ -1552,10 +1622,11 @@ validate_union_blob (GTypelib *typelib, } static gboolean -validate_blob (GTypelib *typelib, - guint32 offset, - GError **error) +validate_blob (ValidateContext *ctx, + guint32 offset, + GError **error) { + GTypelib *typelib = ctx->typelib; CommonBlob *common; if (typelib->len < offset + sizeof (CommonBlob)) @@ -1572,16 +1643,16 @@ validate_blob (GTypelib *typelib, switch (common->blob_type) { case BLOB_TYPE_FUNCTION: - if (!validate_function_blob (typelib, offset, 0, error)) + if (!validate_function_blob (ctx, offset, 0, error)) return FALSE; break; case BLOB_TYPE_CALLBACK: - if (!validate_callback_blob (typelib, offset, error)) + if (!validate_callback_blob (ctx, offset, error)) return FALSE; break; case BLOB_TYPE_STRUCT: case BLOB_TYPE_BOXED: - if (!validate_struct_blob (typelib, offset, common->blob_type, error)) + if (!validate_struct_blob (ctx, offset, common->blob_type, error)) return FALSE; break; case BLOB_TYPE_ENUM: @@ -1590,11 +1661,11 @@ validate_blob (GTypelib *typelib, return FALSE; break; case BLOB_TYPE_OBJECT: - if (!validate_object_blob (typelib, offset, error)) + if (!validate_object_blob (ctx, offset, error)) return FALSE; break; case BLOB_TYPE_INTERFACE: - if (!validate_interface_blob (typelib, offset, error)) + if (!validate_interface_blob (ctx, offset, error)) return FALSE; break; case BLOB_TYPE_CONSTANT: @@ -1621,9 +1692,10 @@ validate_blob (GTypelib *typelib, } static gboolean -validate_directory (GTypelib *typelib, - GError **error) +validate_directory (ValidateContext *ctx, + GError **error) { + GTypelib *typelib = ctx->typelib; Header *header = (Header *)typelib->data; DirEntry *entry; gint i; @@ -1674,7 +1746,7 @@ validate_directory (GTypelib *typelib, return FALSE; } - if (!validate_blob (typelib, entry->offset, error)) + if (!validate_blob (ctx, entry->offset, error)) return FALSE; } else @@ -1697,9 +1769,10 @@ validate_directory (GTypelib *typelib, } static gboolean -validate_annotations (GTypelib *typelib, +validate_annotations (ValidateContext *ctx, GError **error) { + GTypelib *typelib = ctx->typelib; Header *header = (Header *)typelib->data; if (header->size < header->annotations + header->n_annotations * sizeof (AnnotationBlob)) @@ -1714,18 +1787,59 @@ validate_annotations (GTypelib *typelib, return TRUE; } +static void +prefix_with_context (GError **error, + const char *section, + ValidateContext *ctx) +{ + GString *str = g_string_new (NULL); + GSList *link; + char *buf; + + link = ctx->context_stack; + if (!link) + { + g_prefix_error (error, "In %s:", section); + return; + } + + for (; link; link = link->next) + { + g_string_append (str, link->data); + if (link->next) + g_string_append_c (str, '/'); + } + g_string_append_c (str, ')'); + buf = g_string_free (str, FALSE); + g_prefix_error (error, "In %s (Context: %s): ", section, buf); + g_free (buf); +} + gboolean g_typelib_validate (GTypelib *typelib, GError **error) { - if (!validate_header (typelib, error)) - return FALSE; + ValidateContext ctx; + ctx.typelib = typelib; + ctx.context_stack = NULL; - if (!validate_directory (typelib, error)) - return FALSE; + if (!validate_header (&ctx, error)) + { + prefix_with_context (error, "In header", &ctx); + return FALSE; + } - if (!validate_annotations (typelib, error)) - return FALSE; + if (!validate_directory (&ctx, error)) + { + prefix_with_context (error, "directory", &ctx); + return FALSE; + } + + if (!validate_annotations (&ctx, error)) + { + prefix_with_context (error, "annotations", &ctx); + return FALSE; + } return TRUE; } From 92b476b8c1af0a6f59f54bf62eb259f97780cf48 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 24 Aug 2008 16:55:07 +0000 Subject: [PATCH 061/692] Don't open shared library here; we already do it in gtypelib.c. 2008-08-24 Colin Walters * girepository/girepository.c (g_irepository_require): Don't open shared library here; we already do it in gtypelib.c. svn path=/trunk/; revision=483 --- girepository.c | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/girepository.c b/girepository.c index cf18a2e80..e77406d56 100644 --- a/girepository.c +++ b/girepository.c @@ -560,32 +560,6 @@ g_irepository_require (GIRepository *repository, } g_free (fname); - - /* optionally load shared library and attach it to the typelib */ - shlib = ((Header *) typelib->data)->shared_library; - if (shlib) - { - gchar *resolved_shlib; - - shlib_fname = g_typelib_get_string (typelib, shlib); - resolved_shlib = g_module_build_path (NULL, shlib_fname); - - module = g_module_open (resolved_shlib, - G_MODULE_BIND_LAZY|G_MODULE_BIND_LOCAL); - if (module == NULL) - { - g_set_error (error, G_IREPOSITORY_ERROR, - G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, - "Typelib for namespace '%s' references shared library " - "%s, but it could not be openened (%s)", - namespace, resolved_shlib, g_module_error ()); - g_free (full_path); - g_free (resolved_shlib); - return NULL; - } - g_free (resolved_shlib); - } - g_hash_table_remove (table, namespace); register_internal (repository, full_path, typelib); g_free (full_path); From 777cc726a449fcd066abacd7522bedda6527ec18 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 25 Aug 2008 15:22:39 +0000 Subject: [PATCH 062/692] Parse new implements syntax, drop gapi one. Update. Generate new syntax. 2008-08-25 Colin Walters * girepository/girparser.c: Parse new implements syntax, drop gapi one. * tests/object.gir: Update. * tools/generate.c: Generate new syntax. svn path=/trunk/; revision=492 --- girparser.c | 79 +++++++++++++++++++++++------------------------------ 1 file changed, 34 insertions(+), 45 deletions(-) diff --git a/girparser.c b/girparser.c index c9d252975..0f0a6add7 100644 --- a/girparser.c +++ b/girparser.c @@ -1531,6 +1531,36 @@ start_return_value (GMarkupParseContext *context, return FALSE; } +static gboolean +start_implements (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + GIrNodeInterface *iface; + const char *name; + + if (strcmp (element_name, "implements") != 0 || + !(ctx->state == STATE_CLASS)) + return FALSE; + + state_switch (ctx, STATE_IMPLEMENTS); + + name = find_attribute ("name", attribute_names, attribute_values); + if (name == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; + } + + iface = (GIrNodeInterface *)ctx->current_node; + iface->interfaces = g_list_append (iface->interfaces, g_strdup (name)); + + return TRUE; +} + static gboolean start_glib_signal (GMarkupParseContext *context, const gchar *element_name, @@ -1947,51 +1977,10 @@ start_element_handler (GMarkupParseContext *context, attribute_names, attribute_values, ctx, error)) goto out; - if (strcmp (element_name, "implements") == 0 && - ctx->state == STATE_CLASS) - { - state_switch (ctx, STATE_IMPLEMENTS); - - goto out; - } - else if (strcmp (element_name, "interface") == 0 && - ctx->state == STATE_IMPLEMENTS) - { - const gchar *name; - - name = find_attribute ("name", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { - GIrNodeInterface *iface; - - iface = (GIrNodeInterface *)ctx->current_node; - iface ->interfaces = g_list_append (iface->interfaces, g_strdup (name)); - } - - goto out; - } - else if (strcmp (element_name, "interface") == 0 && - ctx->state == STATE_REQUIRES) - { - const gchar *name; - - name = find_attribute ("name", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { - GIrNodeInterface *iface; - - iface = (GIrNodeInterface *)ctx->current_node; - iface ->prerequisites = g_list_append (iface->prerequisites, g_strdup (name)); - } - - goto out; - } + else if (start_implements (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; break; case 'm': From 00fb846ad8c006b0dd91f55899a701a12295427e Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 26 Aug 2008 20:04:38 +0000 Subject: [PATCH 063/692] Handle both .la and .so names; this works better in the uninstalled 2008-08-26 Colin Walters * girepository/gtypelib.c (_g_typelib_init): Handle both .la and .so names; this works better in the uninstalled library case. svn path=/trunk/; revision=498 --- gtypelib.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/gtypelib.c b/gtypelib.c index 4fd5193cc..92c3f931f 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1937,7 +1937,7 @@ _g_typelib_init (GTypelib *typelib) if (typelib->module == NULL) { - gchar *resolved_shlib; + GString *shlib_full; /* Glade's autoconnect feature and OpenGL's extension mechanism * as used by Clutter rely on dlopen(NULL) to work as a means of @@ -1948,13 +1948,23 @@ _g_typelib_init (GTypelib *typelib) * load modules globally for now. */ - resolved_shlib = g_module_build_path (NULL, shlib); - typelib->module = g_module_open (resolved_shlib, G_MODULE_BIND_LAZY); - if (typelib->module == NULL) - g_warning ("Failed to load shared library referenced by the typelib: %s", - g_module_error ()); + typelib->module = g_module_open (shlib, G_MODULE_BIND_LAZY); - g_free (resolved_shlib); + if (typelib->module == NULL) + { + shlib_full = g_string_new (shlib); + /* Prefix with "lib", try both .la and .so */ + if (!g_str_has_prefix (shlib_full->str, "lib")) + g_string_prepend (shlib_full, "lib"); + g_string_append (shlib_full, ".la"); + typelib->module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); + if (typelib->module == NULL) + g_string_overwrite (shlib_full, strlen (shlib_full->str)-2, "so"); + typelib->module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); + } + if (typelib->module == NULL) + g_warning ("Failed to load shared library '%s' referenced by the typelib: %s", + shlib, g_module_error ()); } } } From 7f30a2502ccd73b5e78871caf408ceb3ade5a456 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 26 Aug 2008 20:06:42 +0000 Subject: [PATCH 064/692] Fix small memory leak svn path=/trunk/; revision=499 --- gtypelib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gtypelib.c b/gtypelib.c index 92c3f931f..dc9eba00c 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1965,6 +1965,7 @@ _g_typelib_init (GTypelib *typelib) if (typelib->module == NULL) g_warning ("Failed to load shared library '%s' referenced by the typelib: %s", shlib, g_module_error ()); + g_string_free (shlib_full, TRUE); } } } From d6139fcb45cc5affe0de3a81747332a8e5fceaf0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 26 Aug 2008 21:01:36 +0000 Subject: [PATCH 065/692] Free string in the right place. 2008-08-26 Colin Walters * girepository/gtypelib.c (_g_typelib_init): Free string in the right place. svn path=/trunk/; revision=500 --- gtypelib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gtypelib.c b/gtypelib.c index dc9eba00c..395a83dc9 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1953,6 +1953,7 @@ _g_typelib_init (GTypelib *typelib) if (typelib->module == NULL) { shlib_full = g_string_new (shlib); + /* Prefix with "lib", try both .la and .so */ if (!g_str_has_prefix (shlib_full->str, "lib")) g_string_prepend (shlib_full, "lib"); @@ -1961,11 +1962,12 @@ _g_typelib_init (GTypelib *typelib) if (typelib->module == NULL) g_string_overwrite (shlib_full, strlen (shlib_full->str)-2, "so"); typelib->module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); + + g_string_free (shlib_full, TRUE); } if (typelib->module == NULL) g_warning ("Failed to load shared library '%s' referenced by the typelib: %s", shlib, g_module_error ()); - g_string_free (shlib_full, TRUE); } } } From 7805ca101fc83de82b7422a734585f37b1ff1da1 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 26 Aug 2008 21:05:32 +0000 Subject: [PATCH 066/692] Also use G_MODULE_SUFFIX instead of hardcoding .so. 2008-08-26 Colin Walters * girepository/gtypelib.c (_g_typelib_init): Also use G_MODULE_SUFFIX instead of hardcoding .so. svn path=/trunk/; revision=501 --- gtypelib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtypelib.c b/gtypelib.c index 395a83dc9..bfd7fd416 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1960,7 +1960,7 @@ _g_typelib_init (GTypelib *typelib) g_string_append (shlib_full, ".la"); typelib->module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); if (typelib->module == NULL) - g_string_overwrite (shlib_full, strlen (shlib_full->str)-2, "so"); + g_string_overwrite (shlib_full, strlen (shlib_full->str)-2, G_MODULE_SUFFIX); typelib->module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); g_string_free (shlib_full, TRUE); From c9951bd0997f38912140da432450789ccc88f6a3 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 26 Aug 2008 21:55:42 +0000 Subject: [PATCH 067/692] Search $DATADIR/girepository instead of $DATADIR/gitypelibs; this naming 2008-08-26 Colin Walters * girepository/girepository.c: Search $DATADIR/girepository instead of $DATADIR/gitypelibs; this naming makes it clearer that e.g. jgir can install .jars there. * gir/Makefile.am: Install there. svn path=/trunk/; revision=502 --- girepository.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girepository.c b/girepository.c index e77406d56..e87df1c3f 100644 --- a/girepository.c +++ b/girepository.c @@ -93,7 +93,7 @@ init_globals () search_path = NULL; for (dir = datadirs; *dir; dir++) { - char *path = g_build_filename (*dir, "gitypelibs", NULL); + char *path = g_build_filename (*dir, "girepository", NULL); search_path = g_slist_prepend (search_path, path); } search_path = g_slist_reverse (search_path); From 2bb80a1209ce0a8ccb9685b8f00de460cd2f75de Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Wed, 27 Aug 2008 13:33:21 +0000 Subject: [PATCH 068/692] Make g-ir-scanner work on Windows. Still problems with the typelib code. 2008-08-27 Tor Lillqvist Make g-ir-scanner work on Windows. Still problems with the typelib code. Changes okayed by jdahlin. * configure.ac: Check for Windows, set Automake conditional OS_WIN32. Change backslashes to forward slashes in pyexecdir to avoid shell quoting issues * girepository/Makefile.am: Use -no-undefined so that libtool agrees to build a shared library on Windows. * girepository/girparser.c (backtrace_stderr): No backtrace() on Windows. Empty implementation on Windows so far. * girepository/gtypelib.c (g_typelib_check_sanity): Give more informative error message for the assertion failures. Tell also what the expected size of the struct is. Check all sizes first and fail afterwards if at least one size was different from expected. * tools/Makefile.am: Reorder libraries into proper logical dependency order. * tools/generate.c: Don't include , not used. * giscanner/Makefile.am: On Windows, link with the Python library, and install the module DLL as _giscanner.pyd. Remove the unnecessary import library and libtool library that libtool has installed. * giscanner/scannerlexer.l: Recognize the gcc __attribute__ syntax and just skip it. Recognize also two "l" suffixes for long long constants. Recognize also __inline__. * giscanner/grealpath.h (g_realpath): Implement on Windows, using GetFullPathName(). As such, GetFullPathName() does more than the UNIX realpath(). It also changes relative paths into absolute paths. But for our purposes that shouldn't matter. * giscanner/giscannermodule.c (pygi_source_scanner_parse_file): On Windows the file descriptor passed to us is from Python. Python Python2.5 uses the msvcr71.dll C library, while mingw-built code uses msvcrt.dll. On Windows, file descriptors are specific to which C library is used. So we must find out what underlying OS handle corresponds to the file descriptor Python passes us, and then make that into a file descriptor valid for the C library this code uses. * giscanner/sourcescanner.py (_parse): Don't need to bypass __attribute__ as the lexer now handles it. The definition as empty was ineffective for mingw anyway, as mingw's _mingw.h undefines __attribute__. Close the temp file before unlinking it. * giscanner/cgobject.py: Use correct library name for the gobject DLL on Windows. * gir/Makefile.am: Must pass the full basename of the DLLs on Windows to g-ir-scanner. It's a bit ugly that we have to "know" that the names of the GLib DLLs are like libglib-2.0-0.dll, but in reality they won't change, until there is a GLib 3, and then also the Unix code here needs changing. Must pass CPPFLAGS to g-ir-scanner when building GLib.gir so that libintl.h is found. svn path=/trunk/; revision=503 --- Makefile.am | 1 + girparser.c | 2 ++ gtypelib.c | 64 ++++++++++++++++++++++++++++++++--------------------- 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/Makefile.am b/Makefile.am index fe66da265..be2d0d9cf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,6 +16,7 @@ libgirepository_la_SOURCES = \ ginvoke.c libgirepository_la_CPPFLAGS = $(GIREPO_CFLAGS) libgirepository_la_LIBADD = $(GIREPO_LIBS) +libgirepository_la_LDFLAGS = -no-undefined libgirepository_parser_la_SOURCES = \ girmodule.c \ diff --git a/girparser.c b/girparser.c index 0f0a6add7..247f896c9 100644 --- a/girparser.c +++ b/girparser.c @@ -91,6 +91,7 @@ struct _ParseContext static void backtrace_stderr (void) { +#ifndef _WIN32 void *array[50]; int size; char **strings; @@ -107,6 +108,7 @@ backtrace_stderr (void) fprintf (stderr, "--- END BACKTRACE ---\n", size); free (strings); +#endif } diff --git a/gtypelib.c b/gtypelib.c index bfd7fd416..a6295cbba 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -141,31 +141,45 @@ void g_typelib_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); + + gboolean size_check_ok = TRUE; + +#define CHECK_SIZE(s,n) \ + if (sizeof(s) != n) \ + { \ + g_printerr ("sizeof("#s") is expected to be %d but is %"G_GSIZE_FORMAT".\n", \ + n, sizeof (s)); \ + size_check_ok = FALSE; \ + } + + CHECK_SIZE (Header, 100); + CHECK_SIZE (DirEntry, 12); + CHECK_SIZE (SimpleTypeBlob, 4); + CHECK_SIZE (ArgBlob, 12); + CHECK_SIZE (SignatureBlob, 8); + CHECK_SIZE (CommonBlob, 8); + CHECK_SIZE (FunctionBlob, 16); + CHECK_SIZE (InterfaceTypeBlob, 4); + CHECK_SIZE (ArrayTypeBlob, 8); + CHECK_SIZE (ParamTypeBlob, 4); + CHECK_SIZE (ErrorTypeBlob, 4); + CHECK_SIZE (ErrorDomainBlob, 16); + CHECK_SIZE (ValueBlob, 12); + CHECK_SIZE (FieldBlob, 12); + CHECK_SIZE (RegisteredTypeBlob, 16); + CHECK_SIZE (StructBlob, 20); + CHECK_SIZE (EnumBlob, 20); + CHECK_SIZE (PropertyBlob, 12); + CHECK_SIZE (SignalBlob, 12); + CHECK_SIZE (VFuncBlob, 16); + CHECK_SIZE (ObjectBlob, 32); + CHECK_SIZE (InterfaceBlob, 28); + CHECK_SIZE (ConstantBlob, 20); + CHECK_SIZE (AnnotationBlob, 12); + CHECK_SIZE (UnionBlob, 28); +#undef CHECK_SIZE + + g_assert (size_check_ok); } From 0969efd5a5857d11f8d9445b2b49da0c0b8dbafc Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Thu, 28 Aug 2008 10:24:35 +0000 Subject: [PATCH 069/692] Change type of bitfield fields from guint to the most suitable smaller 2008-08-28 Tor Lillqvist * girepository/gtypelib.h: Change type of bitfield fields from guint to the most suitable smaller type. This makes the struct sizes match the ones on Linux that the sanity check expects when using gcc -mms-bitfields on Windows. svn path=/trunk/; revision=508 --- gtypelib.h | 174 ++++++++++++++++++++++++++--------------------------- 1 file changed, 87 insertions(+), 87 deletions(-) diff --git a/gtypelib.h b/gtypelib.h index 68e026031..9213bbbb0 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -88,8 +88,8 @@ typedef struct { guint16 blob_type; - guint local : 1; - guint reserved :15; + guint16 local : 1; + guint16 reserved :15; guint32 name; guint32 offset; @@ -131,10 +131,10 @@ typedef struct { SimpleTypeBlob return_type; - guint may_return_null : 1; - guint caller_owns_return_value : 1; - guint caller_owns_return_container : 1; - guint reserved :13; + guint16 may_return_null : 1; + guint16 caller_owns_return_value : 1; + guint16 caller_owns_return_container : 1; + guint16 reserved :13; guint16 n_arguments; @@ -145,8 +145,8 @@ typedef struct { guint16 blob_type; /* 1 */ - guint deprecated : 1; - guint reserved :15; + guint16 deprecated : 1; + guint16 reserved :15; guint32 name; } CommonBlob; @@ -155,13 +155,13 @@ typedef struct { guint16 blob_type; /* 1 */ - guint deprecated : 1; - guint setter : 1; - guint getter : 1; - guint constructor : 1; - guint wraps_vfunc : 1; - guint reserved : 1; - guint index :10; + guint16 deprecated : 1; + guint16 setter : 1; + guint16 getter : 1; + guint16 constructor : 1; + guint16 wraps_vfunc : 1; + guint16 reserved : 1; + guint16 index :10; guint32 name; guint32 symbol; @@ -172,8 +172,8 @@ typedef struct { guint16 blob_type; /* 2 */ - guint deprecated : 1; - guint reserved :15; + guint16 deprecated : 1; + guint16 reserved :15; guint32 name; guint32 signature; @@ -181,58 +181,58 @@ typedef struct typedef struct { - guint pointer :1; - guint reserved :2; - guint tag :5; - guint8 reserved2; - guint16 interface; + guint8 pointer :1; + guint8 reserved :2; + guint8 tag :5; + guint8 reserved2; + guint16 interface; } InterfaceTypeBlob; typedef struct { - guint pointer :1; - guint reserved :2; - guint tag :5; + guint16 pointer :1; + guint16 reserved :2; + guint16 tag :5; - guint zero_terminated :1; - guint has_length :1; - guint reserved2 :6; + guint16 zero_terminated :1; + guint16 has_length :1; + guint16 reserved2 :6; - guint16 length; + guint16 length; SimpleTypeBlob type; } ArrayTypeBlob; typedef struct { - guint pointer :1; - guint reserved :2; - guint tag :5; + guint8 pointer :1; + guint8 reserved :2; + guint8 tag :5; - guint8 reserved2; - guint16 n_types; + guint8 reserved2; + guint16 n_types; SimpleTypeBlob type[]; } ParamTypeBlob; typedef struct { - guint pointer :1; - guint reserved :2; - guint tag :5; + guint8 pointer :1; + guint8 reserved :2; + guint8 tag :5; - guint8 reserved2; - guint16 n_domains; + guint8 reserved2; + guint16 n_domains; - guint16 domains[]; + guint16 domains[]; } ErrorTypeBlob; typedef struct { guint16 blob_type; /* 10 */ - guint deprecated : 1; - guint reserved :15; + guint16 deprecated : 1; + guint16 reserved :15; guint32 name; @@ -243,8 +243,8 @@ typedef struct typedef struct { - guint deprecated : 1; - guint reserved :31; + guint32 deprecated : 1; + guint32 reserved :31; guint32 name; guint32 value; } ValueBlob; @@ -253,9 +253,9 @@ typedef struct { guint32 name; - guint readable : 1; - guint writable : 1; - guint reserved : 6; + guint8 readable :1; + guint8 writable :1; + guint8 reserved :6; guint8 bits; guint16 struct_offset; @@ -266,8 +266,8 @@ typedef struct typedef struct { guint16 blob_type; - guint deprecated : 1; - guint unregistered :15; + guint16 deprecated : 1; + guint16 unregistered :15; guint32 name; guint32 gtype_name; @@ -278,9 +278,9 @@ typedef struct { guint16 blob_type; - guint deprecated : 1; - guint unregistered : 1; - guint reserved :14; + guint16 deprecated : 1; + guint16 unregistered : 1; + guint16 reserved :14; guint32 name; @@ -300,10 +300,10 @@ typedef struct typedef struct { guint16 blob_type; - guint deprecated : 1; - guint unregistered : 1; - guint discriminated : 1; - guint reserved :13; + guint16 deprecated : 1; + guint16 unregistered : 1; + guint16 discriminated : 1; + guint16 reserved :13; guint32 name; guint32 gtype_name; @@ -326,9 +326,9 @@ typedef struct { guint16 blob_type; - guint deprecated : 1; - guint unregistered : 1; - guint reserved :14; + guint16 deprecated : 1; + guint16 unregistered : 1; + guint16 reserved :14; guint32 name; @@ -345,12 +345,12 @@ typedef struct { guint32 name; - guint deprecated : 1; - guint readable : 1; - guint writable : 1; - guint construct : 1; - guint construct_only : 1; - guint reserved :27; + guint32 deprecated : 1; + guint32 readable : 1; + guint32 writable : 1; + guint32 construct : 1; + guint32 construct_only : 1; + guint32 reserved :27; SimpleTypeBlob type; @@ -358,17 +358,17 @@ typedef struct typedef struct { - guint deprecated : 1; - guint run_first : 1; - guint run_last : 1; - guint run_cleanup : 1; - guint no_recurse : 1; - guint detailed : 1; - guint action : 1; - guint no_hooks : 1; - guint has_class_closure : 1; - guint true_stops_emit : 1; - guint reserved : 6; + guint16 deprecated : 1; + guint16 run_first : 1; + guint16 run_last : 1; + guint16 run_cleanup : 1; + guint16 no_recurse : 1; + guint16 detailed : 1; + guint16 action : 1; + guint16 no_hooks : 1; + guint16 has_class_closure : 1; + guint16 true_stops_emit : 1; + guint16 reserved : 6; guint16 class_closure; @@ -381,11 +381,11 @@ typedef struct { guint32 name; - guint must_chain_up : 1; - guint must_be_implemented : 1; - guint must_not_be_implemented : 1; - guint class_closure : 1; - guint reserved :12; + guint16 must_chain_up : 1; + guint16 must_be_implemented : 1; + guint16 must_not_be_implemented : 1; + guint16 class_closure : 1; + guint16 reserved :12; guint16 signal; guint16 struct_offset; @@ -396,8 +396,8 @@ typedef struct typedef struct { guint16 blob_type; /* 7 */ - guint deprecated : 1; - guint reserved :15; + guint16 deprecated : 1; + guint16 reserved :15; guint32 name; guint32 gtype_name; @@ -429,8 +429,8 @@ typedef struct typedef struct { guint16 blob_type; - guint deprecated : 1; - guint reserved :15; + guint16 deprecated : 1; + guint16 reserved :15; guint32 name; guint32 gtype_name; @@ -459,8 +459,8 @@ typedef struct typedef struct { guint16 blob_type; - guint deprecated : 1; - guint reserved :15; + guint16 deprecated : 1; + guint16 reserved :15; guint32 name; SimpleTypeBlob type; From fc1efcef595b5c7ec8b200cc27b99d445fabeea1 Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Thu, 28 Aug 2008 16:55:37 +0000 Subject: [PATCH 070/692] Use binary mode for output file on Windows. 2008-08-28 Tor Lillqvist * tools/compiler.c (write_out_typelib): Use binary mode for output file on Windows. * girepository/girnode.c: Don't print NULL strings. * tests/invoke/Makefile.am * tests/scanner/Makefile.am: Use -no-undefined on Windows to convince libtool to build shared libraries. * tests/invoke/invoke.c: Don't needlessly include . Use g_assert() instead of printing out expected errors. svn path=/trunk/; revision=509 --- girnode.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/girnode.c b/girnode.c index ce3e9ba00..fd74dd9ff 100644 --- a/girnode.c +++ b/girnode.c @@ -821,8 +821,11 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size = 0; } - g_debug ("node '%s' %p type '%s' full size %d", node->name, node, - g_ir_node_type_to_string (node->type), size); + g_debug ("node %s%s%s%p type '%s' full size %d", + node->name ? "'" : "", + node->name ? node->name : "", + node->name ? "' " : "", + node, g_ir_node_type_to_string (node->type), size); return size; } @@ -1170,8 +1173,9 @@ g_ir_node_build_typelib (GIrNode *node, g_assert (node != NULL); - g_debug ("build_typelib: %s (%s)", - node->name, + g_debug ("build_typelib: %s%s(%s)", + node->name ? node->name : "", + node->name ? " " : "", g_ir_node_type_to_string (node->type)); switch (node->type) @@ -2122,8 +2126,11 @@ g_ir_node_build_typelib (GIrNode *node, g_assert_not_reached (); } - g_debug ("node '%s' %p type '%s', offset %d -> %d, offset2 %d -> %d", - node->name, node, g_ir_node_type_to_string (node->type), + g_debug ("node %s%s%s%p type '%s', offset %d -> %d, offset2 %d -> %d", + node->name ? "'" : "", + node->name ? node->name : "", + node->name ? "' " : "", + node, g_ir_node_type_to_string (node->type), old_offset, *offset, old_offset2, *offset2); if (*offset2 - old_offset2 + *offset - old_offset > g_ir_node_get_full_size (node)) From 7fd9cd094d3a8e1b49005a83a50e4a591ea17cb5 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 28 Aug 2008 21:19:22 +0000 Subject: [PATCH 071/692] Expand aliases when generating typelibs * gir/Makefile.am: Use --includedir * girepository/girparser.c: Recursively parse includes to pull in aliases and expand them. We need this to avoid putting unknown names in the typelibs. * tools/compiler.c: Add --includedir option. svn path=/trunk/; revision=512 --- girparser.c | 225 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 184 insertions(+), 41 deletions(-) diff --git a/girparser.c b/girparser.c index 247f896c9..7f20ce9ab 100644 --- a/girparser.c +++ b/girparser.c @@ -68,15 +68,94 @@ struct _ParseContext ParseState state; ParseState prev_state; + const char **includes; + GList *modules; + gboolean prefix_aliases; GHashTable *aliases; + const char *namespace; GIrModule *current_module; GIrNode *current_node; GIrNode *current_typed; int type_depth; }; +static gboolean +start_alias (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error); + +static void +firstpass_start_element_handler (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + ParseContext *ctx = user_data; + + if (strcmp (element_name, "alias") == 0) + { + start_alias (context, element_name, attribute_names, attribute_values, + ctx, error); + } +} + +static void +firstpass_end_element_handler (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + ParseContext *ctx = user_data; + +} + +static GMarkupParser firstpass_parser = +{ + firstpass_start_element_handler, + firstpass_end_element_handler, + NULL, + NULL, + NULL, +}; + +static char * +locate_gir (const char *name, const char **extra_paths) +{ + const gchar *const *datadirs; + const gchar *const *dir; + char *girname; + char *path = NULL; + GSList *link; + gboolean firstpass = TRUE; + + datadirs = g_get_system_data_dirs (); + + girname = g_strdup_printf ("%s.gir", name); + + for (dir = datadirs; *dir; dir++) + { + path = g_build_filename (*dir, "gir", girname, NULL); + if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) + return path; + g_free (path); + path = NULL; + if (firstpass && !*dir) + { + firstpass = FALSE; + dir = extra_paths; + } + } + g_free (girname); + return path; +} + #define MISSING_ATTRIBUTE(ctx,error,element,attribute) \ do { \ int line_number, char_number; \ @@ -946,6 +1025,8 @@ start_alias (GMarkupParseContext *context, const gchar *name; const gchar *target; const gchar *type; + char *key; + char *value; name = find_attribute ("name", attribute_names, attribute_values); if (name == NULL) @@ -961,7 +1042,12 @@ start_alias (GMarkupParseContext *context, return FALSE; } - g_hash_table_insert (ctx->aliases, g_strdup (name), g_strdup (target)); + if (ctx->prefix_aliases) + key = g_strdup_printf ("%s.%s", ctx->namespace, name); + else + key = g_strdup (name); + + g_hash_table_insert (ctx->aliases, key, g_strdup (target)); return TRUE; } @@ -1847,6 +1933,63 @@ start_discriminator (GMarkupParseContext *context, return FALSE; } + +static gboolean +parse_include (GMarkupParseContext *context, + ParseContext *ctx, + const char *name, + GError **error) +{ + ParseContext sub_ctx = { 0 }; + GMarkupParseContext *sub_context; + gchar *buffer; + gsize length; + char *girpath; + + girpath = locate_gir (name, ctx->includes); + + if (girpath == NULL) + { + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Could not find GIR file '%s'; check XDG_DATA_DIRS or use --includedir", + name); + return FALSE; + } + + g_debug ("Parsing include %s", girpath); + + if (!g_file_get_contents (girpath, &buffer, &length, error)) + { + g_free (girpath); + return FALSE; + } + g_free (girpath); + + sub_ctx.state = STATE_START; + sub_ctx.prefix_aliases = TRUE; + sub_ctx.namespace = name; + sub_ctx.aliases = ctx->aliases; + sub_ctx.type_depth = 0; + + context = g_markup_parse_context_new (&firstpass_parser, 0, &sub_ctx, NULL); + + if (!g_markup_parse_context_parse (context, buffer, length, error)) + { + g_free (buffer); + return FALSE; + } + + if (!g_markup_parse_context_end_parse (context, error)) + { + g_free (buffer); + return FALSE; + } + + g_markup_parse_context_free (context); + return TRUE; +} extern GLogLevelFlags logged_levels; @@ -1972,6 +2115,19 @@ start_element_handler (GMarkupParseContext *context, if (strcmp (element_name, "include") == 0 && ctx->state == STATE_REPOSITORY) { + const gchar *name; + + name = find_attribute ("name", attribute_names, attribute_values); + + if (name == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "name"); + break; + } + + if (!parse_include (context, ctx, name, error)) + break; + state_switch (ctx, STATE_INCLUDE); goto out; } @@ -2464,44 +2620,6 @@ cleanup (GMarkupParseContext *context, ctx->current_module = NULL; } -static void -firstpass_start_element_handler (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error) -{ - ParseContext *ctx = user_data; - - if (strcmp (element_name, "alias") == 0) - { - start_alias (context, element_name, attribute_names, attribute_values, - ctx, error); - } -} - -static void -firstpass_end_element_handler (GMarkupParseContext *context, - const gchar *element_name, - gpointer user_data, - GError **error) -{ - ParseContext *ctx = user_data; - -} - - -static GMarkupParser firstpass_parser = -{ - firstpass_start_element_handler, - firstpass_end_element_handler, - NULL, - NULL, - NULL, -}; - - static GMarkupParser parser = { start_element_handler, @@ -2512,7 +2630,8 @@ static GMarkupParser parser = }; GList * -g_ir_parse_string (const gchar *buffer, +g_ir_parse_string (const char *namespace, + const gchar *buffer, gssize length, GError **error) { @@ -2520,6 +2639,8 @@ g_ir_parse_string (const gchar *buffer, GMarkupParseContext *context; ctx.state = STATE_START; + ctx.prefix_aliases = FALSE; + ctx.namespace = namespace; ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); ctx.type_depth = 0; @@ -2530,6 +2651,8 @@ g_ir_parse_string (const gchar *buffer, if (!g_markup_parse_context_end_parse (context, error)) goto out; + + g_markup_parse_context_free (context); context = g_markup_parse_context_new (&parser, 0, &ctx, NULL); if (!g_markup_parse_context_parse (context, buffer, length, error)) @@ -2554,13 +2677,33 @@ g_ir_parse_file (const gchar *filename, gchar *buffer; gsize length; GList *modules; + const char *slash; + char *namespace; + + if (!g_str_has_suffix (filename, ".gir")) + { + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Expected filename to end with '.gir'"); + return NULL; + } g_debug ("[parsing] filename %s", filename); + slash = g_strrstr (filename, "/"); + if (!slash) + namespace = g_strdup (filename); + else + namespace = g_strdup (slash+1); + namespace[strlen(namespace)-4] = '\0'; + if (!g_file_get_contents (filename, &buffer, &length, error)) return NULL; - modules = g_ir_parse_string (buffer, length, error); + modules = g_ir_parse_string (namespace, buffer, length, error); + + g_free (namespace); g_free (buffer); From b31a2ae395991490a7b9bc6886233dea8b5f4d87 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 28 Aug 2008 22:13:00 +0000 Subject: [PATCH 072/692] Fix --includedir handling * tests/scanner/Makefile.am: Pass the right --includedir args. Add a Makefile dep. * tools/compiler.c: Pass includedirs down. * girepository/girparser.c: Actually put includedirs in context, pass down. Fix locate_gir. svn path=/trunk/; revision=514 --- girparser.c | 25 ++++++++++++++++--------- girparser.h | 2 ++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/girparser.c b/girparser.c index 7f20ce9ab..f357cb1e9 100644 --- a/girparser.c +++ b/girparser.c @@ -68,7 +68,7 @@ struct _ParseContext ParseState state; ParseState prev_state; - const char **includes; + const char * const*includes; GList *modules; gboolean prefix_aliases; @@ -126,7 +126,7 @@ static GMarkupParser firstpass_parser = }; static char * -locate_gir (const char *name, const char **extra_paths) +locate_gir (const char *name, const char * const* extra_paths) { const gchar *const *datadirs; const gchar *const *dir; @@ -146,11 +146,14 @@ locate_gir (const char *name, const char **extra_paths) return path; g_free (path); path = NULL; - if (firstpass && !*dir) - { - firstpass = FALSE; - dir = extra_paths; - } + } + for (dir = extra_paths; *dir; dir++) + { + path = g_build_filename (*dir, girname, NULL); + if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) + return path; + g_free (path); + path = NULL; } g_free (girname); return path; @@ -1968,6 +1971,7 @@ parse_include (GMarkupParseContext *context, g_free (girpath); sub_ctx.state = STATE_START; + sub_ctx.includes = ctx->includes; sub_ctx.prefix_aliases = TRUE; sub_ctx.namespace = name; sub_ctx.aliases = ctx->aliases; @@ -2630,7 +2634,8 @@ static GMarkupParser parser = }; GList * -g_ir_parse_string (const char *namespace, +g_ir_parse_string (const gchar *namespace, + const gchar *const *includes, const gchar *buffer, gssize length, GError **error) @@ -2639,6 +2644,7 @@ g_ir_parse_string (const char *namespace, GMarkupParseContext *context; ctx.state = STATE_START; + ctx.includes = includes; ctx.prefix_aliases = FALSE; ctx.namespace = namespace; ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); @@ -2672,6 +2678,7 @@ g_ir_parse_string (const char *namespace, GList * g_ir_parse_file (const gchar *filename, + const gchar *const *includes, GError **error) { gchar *buffer; @@ -2701,7 +2708,7 @@ g_ir_parse_file (const gchar *filename, if (!g_file_get_contents (filename, &buffer, &length, error)) return NULL; - modules = g_ir_parse_string (namespace, buffer, length, error); + modules = g_ir_parse_string (namespace, includes, buffer, length, error); g_free (namespace); diff --git a/girparser.h b/girparser.h index ed9e6cebf..68b3acf5f 100644 --- a/girparser.h +++ b/girparser.h @@ -27,9 +27,11 @@ G_BEGIN_DECLS GList *g_ir_parse_string (const gchar *buffer, + const gchar *const *includes, gssize length, GError **error); GList *g_ir_parse_file (const gchar *filename, + const gchar *const *includes, GError **error); From a633e4b1f3e67d2214c564a56d9d7c31e2b283a4 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 29 Aug 2008 18:19:26 +0000 Subject: [PATCH 073/692] Correctly handle GLib.List, GLib.Error etc * girepository/girparser.c: Accept both List (for compiling GLib) and GLib.List (what the scanner generates). * tests/ - Update. * tools/generate.c: Generate canonical form. svn path=/trunk/; revision=522 --- girparser.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/girparser.c b/girparser.c index f357cb1e9..0e7c0308e 100644 --- a/girparser.c +++ b/girparser.c @@ -337,22 +337,26 @@ parse_type_internal (gchar *str, gchar **rest) if (i < n_basic) /* found a basic type */; - else if (g_str_has_prefix (*rest, "GList") || - g_str_has_prefix (*rest, "GSList")) + else if (g_str_has_prefix (*rest, "GLib.List") || + g_str_has_prefix (*rest, "GLib.SList") || + g_str_has_prefix (*rest, "List") || + g_str_has_prefix (*rest, "SList")) { - if (g_str_has_prefix (*rest, "GList")) + if (g_str_has_prefix (*rest, "GLib.")) + *rest += strlen ("GLib."); + if (g_str_has_prefix (*rest, "List")) { type->tag = GI_TYPE_TAG_GLIST; type->is_glist = TRUE; type->is_pointer = TRUE; - *rest += strlen ("GList"); + *rest += strlen ("List"); } else { type->tag = GI_TYPE_TAG_GSLIST; type->is_gslist = TRUE; type->is_pointer = TRUE; - *rest += strlen ("GSList"); + *rest += strlen ("SList"); } *rest = g_strchug (*rest); @@ -376,12 +380,16 @@ parse_type_internal (gchar *str, gchar **rest) type->parameter_type1 = create_pointer (); } } - else if (g_str_has_prefix (*rest, "GHashTable")) + else if (g_str_has_prefix (*rest, "HashTable") || + g_str_has_prefix (*rest, "GLib.HashTable")) { + if (g_str_has_prefix (*rest, "GLib.")) + *rest += strlen ("GLib."); + type->tag = GI_TYPE_TAG_GHASH; type->is_ghashtable = TRUE; type->is_pointer = TRUE; - *rest += strlen ("GHashTable"); + *rest += strlen ("HashTable"); *rest = g_strchug (*rest); @@ -414,8 +422,12 @@ parse_type_internal (gchar *str, gchar **rest) } } - else if (g_str_has_prefix (*rest, "GError")) + else if (g_str_has_prefix (*rest, "GLib.Error") + || g_str_has_prefix (*rest, "Error")) { + if (g_str_has_prefix (*rest, "GLib.")) + *rest += strlen ("GLib."); + type->tag = GI_TYPE_TAG_ERROR; type->is_error = TRUE; type->is_pointer = TRUE; From 295fc99a408d08b6472145e556e5e78d04649915 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 29 Aug 2008 18:49:22 +0000 Subject: [PATCH 074/692] More context information in validate * girepository/gtypelib.c: Add more context during validate. svn path=/trunk/; revision=525 --- gtypelib.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/gtypelib.c b/gtypelib.c index a6295cbba..96d44690f 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1246,11 +1246,12 @@ validate_struct_blob (ValidateContext *ctx, } static gboolean -validate_enum_blob (GTypelib *typelib, +validate_enum_blob (ValidateContext *ctx, guint32 offset, guint16 blob_type, GError **error) { + GTypelib *typelib = ctx->typelib; EnumBlob *blob; ValueBlob *v1, *v2; gint i, j; @@ -1307,6 +1308,8 @@ validate_enum_blob (GTypelib *typelib, "The buffer is too short"); return FALSE; } + + push_context (ctx, get_string_nofail (typelib, blob->name)); for (i = 0; i < blob->n_values; i++) { @@ -1337,6 +1340,8 @@ validate_enum_blob (GTypelib *typelib, } #endif } + + pop_context (ctx); return TRUE; } @@ -1382,7 +1387,7 @@ validate_object_blob (ValidateContext *ctx, if (!validate_name (typelib, "object", typelib->data, blob->name, error)) return FALSE; - + if (blob->parent > header->n_entries) { g_set_error (error, @@ -1457,6 +1462,8 @@ validate_object_blob (ValidateContext *ctx, offset2 += 2 * (blob->n_interfaces %2); + push_context (ctx, get_string_nofail (typelib, blob->name)); + for (i = 0; i < blob->n_fields; i++, offset2 += sizeof (FieldBlob)) { if (!validate_field_blob (typelib, offset2, error)) @@ -1493,6 +1500,8 @@ validate_object_blob (ValidateContext *ctx, return FALSE; } + pop_context (ctx); + return TRUE; } @@ -1586,6 +1595,8 @@ validate_interface_blob (ValidateContext *ctx, offset2 += 2 * (blob->n_prerequisites % 2); + push_context (ctx, get_string_nofail (typelib, blob->name)); + for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob)) { if (!validate_property_blob (typelib, offset2, error)) @@ -1616,6 +1627,8 @@ validate_interface_blob (ValidateContext *ctx, return FALSE; } + pop_context (ctx); + return TRUE; } @@ -1671,7 +1684,7 @@ validate_blob (ValidateContext *ctx, break; case BLOB_TYPE_ENUM: case BLOB_TYPE_FLAGS: - if (!validate_enum_blob (typelib, offset, common->blob_type, error)) + if (!validate_enum_blob (ctx, offset, common->blob_type, error)) return FALSE; break; case BLOB_TYPE_OBJECT: From da9249d5596af8217f1fbd077a32be08b20b0d8e Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 29 Aug 2008 19:33:09 +0000 Subject: [PATCH 075/692] Fix type parsing for both GLib case and GLib.List * girepository/girparser.c: Rewrite type parsing to handle both GLib parsing case as well as correctly handling GLib.List and friends. Don't try to treat e.g. ListStore as a List. svn path=/trunk/; revision=527 --- girparser.c | 220 +++++++++++++++++++++++++++------------------------- 1 file changed, 114 insertions(+), 106 deletions(-) diff --git a/girparser.c b/girparser.c index 0e7c0308e..0672b4948 100644 --- a/girparser.c +++ b/girparser.c @@ -216,20 +216,10 @@ state_switch (ParseContext *ctx, ParseState newstate) ctx->state = newstate; } -static GIrNodeType * parse_type_internal (gchar *str, gchar **rest); +static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib); static GIrNodeType * -create_pointer () -{ - char *pointer = g_strdup ("any"); - char *pointer_rest; - GIrNodeType *ret = parse_type_internal (pointer, &pointer_rest); - g_free (pointer); - return ret; -} - -static GIrNodeType * -parse_type_internal (gchar *str, gchar **rest) +parse_type_internal (const gchar *str, char **next, gboolean in_glib) { gint i; @@ -304,175 +294,186 @@ parse_type_internal (gchar *str, gchar **rest) }; gint n_basic = G_N_ELEMENTS (basic); - gchar *start, *end; + gchar *temporary_type = NULL; + const gchar *start; + const gchar *end; GIrNodeType *type; type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE); - str = g_strstrip (str); - type->unparsed = g_strdup (str); - - *rest = str; + + if (in_glib) + { + if (g_str_has_prefix (str, "List<") || + strcmp (str, "List") == 0) + { + temporary_type = g_strdup_printf ("GLib.List%s", str + 4); + str = temporary_type; + } + else if (g_str_has_prefix (str, "SList<") || + strcmp (str, "SList") == 0) + { + temporary_type = g_strdup_printf ("GLib.SList%s", str + 5); + str = temporary_type; + } + else if (g_str_has_prefix (str, "HashTable<") || + strcmp (str, "HashTable") == 0) + { + temporary_type = g_strdup_printf ("GLib.HashTable%s", str + 9); + str = temporary_type; + } + else if (g_str_has_prefix (str, "Error<") || + strcmp (str, "Error") == 0) + { + temporary_type = g_strdup_printf ("GLib.Error%s", str + 5); + str = temporary_type; + } + } + for (i = 0; i < n_basic; i++) { - if (g_str_has_prefix (*rest, basic[i].str)) + if (g_str_has_prefix (str, basic[i].str)) { type->is_basic = TRUE; type->tag = basic[i].tag; type->is_pointer = basic[i].pointer; - *rest += strlen(basic[i].str); - *rest = g_strchug (*rest); - if (**rest == '*' && !type->is_pointer) + str += strlen(basic[i].str); + if (*str == '*' && !type->is_pointer) { type->is_pointer = TRUE; - (*rest)++; + str++; } - break; } } if (i < n_basic) /* found a basic type */; - else if (g_str_has_prefix (*rest, "GLib.List") || - g_str_has_prefix (*rest, "GLib.SList") || - g_str_has_prefix (*rest, "List") || - g_str_has_prefix (*rest, "SList")) + else if (g_str_has_prefix (str, "GLib.List") || + g_str_has_prefix (str, "GLib.SList")) { - if (g_str_has_prefix (*rest, "GLib.")) - *rest += strlen ("GLib."); - if (g_str_has_prefix (*rest, "List")) + str += strlen ("GLib."); + if (g_str_has_prefix (str, "List")) { type->tag = GI_TYPE_TAG_GLIST; type->is_glist = TRUE; type->is_pointer = TRUE; - *rest += strlen ("List"); + str += strlen ("List"); } else { type->tag = GI_TYPE_TAG_GSLIST; type->is_gslist = TRUE; type->is_pointer = TRUE; - *rest += strlen ("SList"); + str += strlen ("SList"); } - *rest = g_strchug (*rest); - - if (**rest == '<') + if (*str == '<') { - (*rest)++; - - type->parameter_type1 = parse_type_internal (*rest, rest); + (str)++; + char *rest; + + type->parameter_type1 = parse_type_internal (str, &rest, in_glib); if (type->parameter_type1 == NULL) goto error; + str = rest; - *rest = g_strchug (*rest); - - if ((*rest)[0] != '>') + if (str[0] != '>') goto error; - (*rest)++; + (str)++; } else { - type->parameter_type1 = create_pointer (); + type->parameter_type1 = parse_type_internal ("any", NULL, in_glib); } } - else if (g_str_has_prefix (*rest, "HashTable") || - g_str_has_prefix (*rest, "GLib.HashTable")) + else if (g_str_has_prefix (str, "GLib.HashTable")) { - if (g_str_has_prefix (*rest, "GLib.")) - *rest += strlen ("GLib."); + str += strlen ("GLib."); type->tag = GI_TYPE_TAG_GHASH; type->is_ghashtable = TRUE; type->is_pointer = TRUE; - *rest += strlen ("HashTable"); + str += strlen ("HashTable"); - *rest = g_strchug (*rest); - - if (**rest == '<') + if (*str == '<') { - (*rest)++; + char *rest; + (str)++; - type->parameter_type1 = parse_type_internal (*rest, rest); + type->parameter_type1 = parse_type_internal (str, &rest, in_glib); if (type->parameter_type1 == NULL) goto error; + str = rest; - *rest = g_strchug (*rest); - - if ((*rest)[0] != ',') + if (str[0] != ',') goto error; - (*rest)++; + (str)++; - type->parameter_type2 = parse_type_internal (*rest, rest); + type->parameter_type2 = parse_type_internal (str, &rest, in_glib); if (type->parameter_type2 == NULL) goto error; + str = rest; - if ((*rest)[0] != '>') + if ((str)[0] != '>') goto error; - (*rest)++; + (str)++; } else { - type->parameter_type1 = create_pointer (); - type->parameter_type2 = create_pointer (); + type->parameter_type1 = parse_type_internal ("any", NULL, in_glib); + type->parameter_type2 = parse_type_internal ("any", NULL, in_glib); } - } - else if (g_str_has_prefix (*rest, "GLib.Error") - || g_str_has_prefix (*rest, "Error")) + else if (g_str_has_prefix (str, "GLib.Error")) { - if (g_str_has_prefix (*rest, "GLib.")) - *rest += strlen ("GLib."); + str += strlen ("GLib."); type->tag = GI_TYPE_TAG_ERROR; type->is_error = TRUE; type->is_pointer = TRUE; - *rest += strlen ("GError"); + str += strlen ("Error"); - *rest = g_strchug (*rest); - - if (**rest == '<') + if (*str == '<') { - (*rest)++; + (str)++; + char *tmp; - end = strchr (*rest, '>'); - str = g_strndup (*rest, end - *rest); - type->errors = g_strsplit (str, ",", 0); - g_free (str); - - *rest = end + 1; + end = strchr (str, '>'); + tmp = g_strndup (str, end - str); + type->errors = g_strsplit (tmp, ",", 0); + g_free (tmp); + + str = end; } } else { type->tag = GI_TYPE_TAG_INTERFACE; type->is_interface = TRUE; - start = *rest; + start = str; /* must be an interface type */ - while (g_ascii_isalnum (**rest) || - **rest == '.' || - **rest == '-' || - **rest == '_' || - **rest == ':') - (*rest)++; + while (g_ascii_isalnum (*str) || + *str == '.' || + *str == '-' || + *str == '_' || + *str == ':') + (str)++; - type->interface = g_strndup (start, *rest - start); + type->interface = g_strndup (start, str - start); - *rest = g_strchug (*rest); - if (**rest == '*') + if (*str == '*') { type->is_pointer = TRUE; - (*rest)++; + (str)++; } } - *rest = g_strchug (*rest); - if (g_str_has_prefix (*rest, "[")) + if (g_str_has_prefix (str, "[")) { GIrNodeType *array; @@ -488,15 +489,13 @@ parse_type_internal (gchar *str, gchar **rest) array->has_length = FALSE; array->length = 0; - if (!g_str_has_prefix (*rest, "[]")) + if (!g_str_has_prefix (str, "[]")) { - gchar *end, *str, **opts; + gchar *end, *tmp, **opts; - end = strchr (*rest, ']'); - str = g_strndup (*rest + 1, (end - *rest) - 1); - opts = g_strsplit (str, ",", 0); - - *rest = end + 1; + end = strchr (str, ']'); + tmp = g_strndup (str + 1, (end - str) - 1); + opts = g_strsplit (tmp, ",", 0); for (i = 0; opts[i]; i++) { @@ -515,19 +514,24 @@ parse_type_internal (gchar *str, gchar **rest) g_strfreev (vals); } - g_free (str); + g_free (tmp); g_strfreev (opts); + + str = end; } type = array; } + if (next) + *next = (char*)str; g_assert (type->tag >= 0 && type->tag <= GI_TYPE_TAG_ERROR); + g_free (temporary_type); return type; error: g_ir_node_free ((GIrNode *)type); - + g_free (temporary_type); return NULL; } @@ -556,14 +560,18 @@ static GIrNodeType * parse_type (ParseContext *ctx, const gchar *type) { gchar *str; - gchar *rest; GIrNodeType *node; - + gboolean in_glib; + gboolean matched_special = FALSE; + + in_glib = strcmp (ctx->namespace, "GLib") == 0; + type = resolve_aliases (ctx, type); - str = g_strdup (type); - node = parse_type_internal (str, &rest); - g_free (str); - g_debug ("Parsed type: %s => %d", type, node->tag); + node = parse_type_internal (type, NULL, in_glib); + if (node) + g_debug ("Parsed type: %s => %d", type, node->tag); + else + g_critical ("Failed to parse type: '%s'", type); return node; } From 63bb95c0db6b2724fb01df1e9245f6711ffeeff9 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 29 Aug 2008 20:06:10 +0000 Subject: [PATCH 076/692] Avoid searching aliases for basic types * girepository/girparser.c: Don't search aliases for basic types. svn path=/trunk/; revision=529 --- girparser.c | 89 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 34 deletions(-) diff --git a/girparser.c b/girparser.c index 0672b4948..9a18f4a2a 100644 --- a/girparser.c +++ b/girparser.c @@ -218,16 +218,13 @@ state_switch (ParseContext *ctx, ParseState newstate) static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib); -static GIrNodeType * -parse_type_internal (const gchar *str, char **next, gboolean in_glib) -{ - gint i; +typedef struct { + const gchar *str; + gint tag; + gboolean pointer; +} BasicTypeInfo; - static struct { - const gchar *str; - gint tag; - gboolean pointer; - } basic[] = { +static BasicTypeInfo basic_types[] = { { "none", GI_TYPE_TAG_VOID, 0 }, { "any", GI_TYPE_TAG_VOID, 1 }, @@ -291,21 +288,57 @@ parse_type_internal (const gchar *str, char **next, gboolean in_glib) { "gfloat", GI_TYPE_TAG_FLOAT, 0 }, { "gdouble", GI_TYPE_TAG_DOUBLE, 0 }, { "gchar*", GI_TYPE_TAG_UTF8, 1 } - }; +}; - gint n_basic = G_N_ELEMENTS (basic); +static const BasicTypeInfo * +parse_basic (const char *str) +{ + gint i; + gint n_basic = G_N_ELEMENTS (basic_types); gchar *temporary_type = NULL; const gchar *start; const gchar *end; + for (i = 0; i < n_basic; i++) + { + if (g_str_has_prefix (str, basic_types[i].str)) + return &(basic_types[i]); + } + return NULL; +} + +static GIrNodeType * +parse_type_internal (const gchar *str, char **next, gboolean in_glib) +{ + const BasicTypeInfo *basic; GIrNodeType *type; + char *temporary_type = NULL; type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE); type->unparsed = g_strdup (str); - if (in_glib) + basic = parse_basic (str); + if (basic != NULL) { + type->is_basic = TRUE; + type->tag = basic->tag; + type->is_pointer = basic->pointer; + + str += strlen(basic->str); + if (*str == '*' && !type->is_pointer) + { + type->is_pointer = TRUE; + (str)++; + } + } + else if (in_glib) + { + /* If we're inside GLib, handle "List" by prefixing it with + * "GLib." so the parsing code below doesn't have to get more + * special. + */ + if (g_str_has_prefix (str, "List<") || strcmp (str, "List") == 0) { @@ -332,25 +365,7 @@ parse_type_internal (const gchar *str, char **next, gboolean in_glib) } } - for (i = 0; i < n_basic; i++) - { - if (g_str_has_prefix (str, basic[i].str)) - { - type->is_basic = TRUE; - type->tag = basic[i].tag; - type->is_pointer = basic[i].pointer; - - str += strlen(basic[i].str); - if (*str == '*' && !type->is_pointer) - { - type->is_pointer = TRUE; - str++; - } - break; - } - } - - if (i < n_basic) + if (basic != NULL) /* found a basic type */; else if (g_str_has_prefix (str, "GLib.List") || g_str_has_prefix (str, "GLib.SList")) @@ -440,7 +455,7 @@ parse_type_internal (const gchar *str, char **next, gboolean in_glib) if (*str == '<') { (str)++; - char *tmp; + char *tmp, *end; end = strchr (str, '>'); tmp = g_strndup (str, end - str); @@ -454,7 +469,7 @@ parse_type_internal (const gchar *str, char **next, gboolean in_glib) { type->tag = GI_TYPE_TAG_INTERFACE; type->is_interface = TRUE; - start = str; + const char *start = str; /* must be an interface type */ while (g_ascii_isalnum (*str) || @@ -476,6 +491,7 @@ parse_type_internal (const gchar *str, char **next, gboolean in_glib) if (g_str_has_prefix (str, "[")) { GIrNodeType *array; + int i; array = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE); @@ -561,12 +577,17 @@ parse_type (ParseContext *ctx, const gchar *type) { gchar *str; GIrNodeType *node; + const BasicTypeInfo *basic; gboolean in_glib; gboolean matched_special = FALSE; in_glib = strcmp (ctx->namespace, "GLib") == 0; - type = resolve_aliases (ctx, type); + /* Do not search aliases for basic types */ + basic = parse_basic (type); + if (basic == NULL) + type = resolve_aliases (ctx, type); + node = parse_type_internal (type, NULL, in_glib); if (node) g_debug ("Parsed type: %s => %d", type, node->tag); From 8baadb86115ea7f33d1bb8e98d6131f14c4471e3 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 29 Aug 2008 20:41:26 +0000 Subject: [PATCH 077/692] Handle alias chains correctly * girepository/girparser.c: Handle chains of aliases across modules by ensuring we fully qualify aliases from includes. svn path=/trunk/; revision=531 --- girparser.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/girparser.c b/girparser.c index 9a18f4a2a..77a2b60d7 100644 --- a/girparser.c +++ b/girparser.c @@ -1086,12 +1086,27 @@ start_alias (GMarkupParseContext *context, return FALSE; } + value = g_strdup (target); if (ctx->prefix_aliases) - key = g_strdup_printf ("%s.%s", ctx->namespace, name); + { + key = g_strdup_printf ("%s.%s", ctx->namespace, name); + if (!strchr (target, '.')) + { + const BasicTypeInfo *basic = parse_basic (target); + if (!basic) + { + g_free (value); + /* For non-basic types, re-qualify the interface */ + value = g_strdup_printf ("%s.%s", ctx->namespace, target); + } + } + } else - key = g_strdup (name); + { + key = g_strdup (name); + } - g_hash_table_insert (ctx->aliases, key, g_strdup (target)); + g_hash_table_insert (ctx->aliases, key, value); return TRUE; } @@ -2213,9 +2228,8 @@ start_element_handler (GMarkupParseContext *context, ctx->modules = g_list_append (ctx->modules, ctx->current_module); state_switch (ctx, STATE_NAMESPACE); + goto out; } - - goto out; } break; @@ -2690,6 +2704,7 @@ g_ir_parse_string (const gchar *namespace, ctx.namespace = namespace; ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); ctx.type_depth = 0; + ctx.current_module = NULL; context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL); From ce86b80390092413865180e7c48865d371388ccb Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 29 Aug 2008 20:42:51 +0000 Subject: [PATCH 078/692] Don't crash if no shlib is embedded * girepository/gtypelib.c: Don't crash if no shlib is embedded svn path=/trunk/; revision=533 --- gtypelib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtypelib.c b/gtypelib.c index 96d44690f..e889d6998 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1962,7 +1962,7 @@ _g_typelib_init (GTypelib *typelib) } } - if (typelib->module == NULL) + if (typelib->module == NULL && shlib != NULL) { GString *shlib_full; From 2ee14706117fc5551a885741857e21816269678f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 30 Aug 2008 02:31:53 +0000 Subject: [PATCH 079/692] Add some assertions, blacklist a few more methods * girepository/ginfo.c: Add some assertions regarding refcounts, just to be sure. * giscanner/glibtransformer.py: Blacklist a few more odd Gio methods. svn path=/trunk/; revision=537 --- ginfo.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ginfo.c b/ginfo.c index b48541aa2..4625e8504 100644 --- a/ginfo.c +++ b/ginfo.c @@ -203,6 +203,7 @@ g_base_info_ref (GIBaseInfo *info) void g_base_info_unref (GIBaseInfo *info) { + g_assert (info->ref_count > 0); info->ref_count--; if (!info->ref_count) @@ -224,6 +225,7 @@ g_base_info_get_type (GIBaseInfo *info) const gchar * g_base_info_get_name (GIBaseInfo *info) { + g_assert (info->ref_count > 0); switch (info->type) { case GI_INFO_TYPE_FUNCTION: @@ -302,6 +304,7 @@ g_base_info_get_name (GIBaseInfo *info) case GI_INFO_TYPE_TYPE: default: ; + g_assert_not_reached (); /* unnamed */ } @@ -311,7 +314,9 @@ g_base_info_get_name (GIBaseInfo *info) const gchar * g_base_info_get_namespace (GIBaseInfo *info) { - Header *header = (Header *)info->typelib->data; + Header *header = (Header *)info->typelib->data; + + g_assert (info->ref_count > 0); if (info->type == GI_INFO_TYPE_UNRESOLVED) { From 6e656b4498965a342ed54649dda690c331ce44b6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 30 Aug 2008 20:31:07 +0000 Subject: [PATCH 080/692] Put dependencies in typelibs, resolve them when loading * gir/Makefile.am: Dep on Makefile * girepository/ginfo.c: Print out a nicer error message if we failed to load something. * girepository/girepository.c: Clean up default typelib handling; remove global default_typelib variable. Ensure we handle NULL repository in more places. Support dependency resolution. * tests/Makefile.am: Kill off gobject.gir, it conflicts with the real one. * tests/Object.gir: Depend on GObject. * tools/generate.c: Take --includedir argument to say which directories to search for typelibs. Print out dependencies. svn path=/trunk/; revision=541 --- ginfo.c | 33 ++------ girepository.c | 221 +++++++++++++++++++++++++++++++------------------ girepository.h | 13 +-- girmodule.c | 40 ++++++++- girmodule.h | 1 + girparser.c | 6 ++ gtypelib.c | 2 +- gtypelib.h | 2 + 8 files changed, 203 insertions(+), 115 deletions(-) diff --git a/ginfo.c b/ginfo.c index 4625e8504..e7d07dbb3 100644 --- a/ginfo.c +++ b/ginfo.c @@ -174,18 +174,14 @@ g_info_from_entry (GTypelib *typelib, 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; - unresolved->namespace = namespace; - - result = (GIBaseInfo*)unresolved; + char **all_namespaces = g_irepository_get_namespaces (repository); + char *namespaces_str = g_strjoinv (", ", all_namespaces); + g_critical ("Failed to find namespace: %s name: %s (currently loaded namespaces: %s)", namespace, + name, namespaces_str); + g_strfreev (all_namespaces); + g_free (namespaces_str); } + return result; } return result; @@ -294,14 +290,6 @@ g_base_info_get_name (GIBaseInfo *info) } break; - case GI_INFO_TYPE_UNRESOLVED: - { - GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info; - - return unresolved->name; - } - break; - case GI_INFO_TYPE_TYPE: default: ; g_assert_not_reached (); @@ -318,13 +306,6 @@ g_base_info_get_namespace (GIBaseInfo *info) g_assert (info->ref_count > 0); - if (info->type == GI_INFO_TYPE_UNRESOLVED) - { - GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info; - - return unresolved->namespace; - } - return g_typelib_get_string (info->typelib, header->namespace); } diff --git a/girepository.c b/girepository.c index e87df1c3f..be8ddca33 100644 --- a/girepository.c +++ b/girepository.c @@ -30,12 +30,11 @@ static GStaticMutex globals_lock = G_STATIC_MUTEX_INIT; static GIRepository *default_repository = NULL; -static GHashTable *default_typelib = NULL; static GSList *search_path = NULL; struct _GIRepositoryPrivate { - GHashTable *typelib; /* (string) namespace -> GTypelib */ + GHashTable *typelibs; /* (string) namespace -> GTypelib */ }; G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT); @@ -52,7 +51,7 @@ g_irepository_finalize (GObject *object) { GIRepository *repository = G_IREPOSITORY (object); - g_hash_table_destroy (repository->priv->typelib); + g_hash_table_destroy (repository->priv->typelibs); (* G_OBJECT_CLASS (g_irepository_parent_class)->finalize) (G_OBJECT (repository)); } @@ -77,11 +76,10 @@ init_globals () if (default_repository == NULL) { default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL); - if (default_typelib == NULL) - default_typelib = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) NULL, - (GDestroyNotify) g_typelib_free); - default_repository->priv->typelib = default_typelib; + default_repository->priv->typelibs + = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) NULL, + (GDestroyNotify) g_typelib_free); } if (search_path == NULL) @@ -102,6 +100,13 @@ init_globals () g_static_mutex_unlock (&globals_lock); } +void +g_irepository_prepend_search_path (const char *directory) +{ + init_globals (); + search_path = g_slist_prepend (search_path, g_strdup (directory)); +} + static char * build_typelib_key (const char *name, const char *source) { @@ -111,46 +116,79 @@ build_typelib_key (const char *name, const char *source) return g_string_free (str, FALSE); } -static const gchar * -register_internal (GIRepository *repository, - const char *source, - GTypelib *typelib) +static char ** +get_typelib_dependencies (GTypelib *typelib) { Header *header; - const gchar *name; - GHashTable *table; - GError *error = NULL; - - g_return_val_if_fail (typelib != NULL, NULL); - + const char *dependencies_glob; + header = (Header *)typelib->data; - g_return_val_if_fail (header != NULL, NULL); + if (header->dependencies == 0) + return NULL; + dependencies_glob = g_typelib_get_string (typelib, header->dependencies); + return g_strsplit (dependencies_glob, "|", 0); +} + +static GIRepository * +get_repository (GIRepository *repository) +{ if (repository != NULL) { - if (repository->priv->typelib == NULL) - repository->priv->typelib = g_hash_table_new_full (g_str_hash, g_str_equal, + if (repository->priv->typelibs == NULL) + repository->priv->typelibs = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) NULL, (GDestroyNotify) g_typelib_free); - table = repository->priv->typelib; + return repository; } else { init_globals (); - table = default_typelib; + return default_repository; } +} + +static const char * +register_internal (GIRepository *repository, + const char *source, + GTypelib *typelib, + GError **error) +{ + Header *header; + const gchar *name; + const char *dependencies_glob; + char **dependencies; + + g_return_val_if_fail (typelib != NULL, FALSE); + + header = (Header *)typelib->data; + + g_return_val_if_fail (header != NULL, FALSE); name = g_typelib_get_string (typelib, header->namespace); - if (g_hash_table_lookup (table, name)) + dependencies = get_typelib_dependencies (typelib); + if (dependencies != NULL) { - g_printerr ("typelib (%p) for '%s' already registered\n", - typelib, name); - - return NULL; + int i; + + for (i = 0; dependencies[i]; i++) + { + char *dependency = dependencies[i]; + + if (!g_irepository_require (repository, dependency, error)) + { + g_strfreev (dependencies); + return NULL; + } + } + g_strfreev (dependencies); } - g_hash_table_insert (table, build_typelib_key (name, source), (void *)typelib); + + g_assert (g_hash_table_lookup (repository->priv->typelibs, name) == NULL); + g_hash_table_insert (repository->priv->typelibs, + build_typelib_key (name, source), (void *)typelib); if (typelib->module == NULL) typelib->module = g_module_open (NULL, 0); @@ -158,28 +196,47 @@ register_internal (GIRepository *repository, return name; } -const gchar * -g_irepository_register (GIRepository *repository, - GTypelib *typelib) +char ** +g_irepository_get_dependencies (GIRepository *repository, + const char *namespace) { - return register_internal (repository, "", typelib); + GTypelib *typelib; + + g_return_val_if_fail (namespace != NULL, NULL); + + repository = get_repository (repository); + + typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); + g_return_val_if_fail (typelib != NULL, NULL); + + return get_typelib_dependencies (typelib); +} + +const char * +g_irepository_load_typelib (GIRepository *repository, + GTypelib *typelib, + GError **error) +{ + Header *header; + const char *namespace; + + repository = get_repository (repository); + + header = (Header *) typelib->data; + namespace = g_typelib_get_string (typelib, header->namespace); + + if (g_hash_table_lookup (repository->priv->typelibs, namespace)) + return namespace; + return register_internal (repository, "", typelib, error); } void g_irepository_unregister (GIRepository *repository, const gchar *namespace) { - GHashTable *table; + repository = get_repository (repository); - if (repository != NULL) - table = repository->priv->typelib; - else - { - init_globals (); - table = default_typelib; - } - - if (!g_hash_table_remove (table, namespace)) + if (!g_hash_table_remove (repository->priv->typelibs, namespace)) { g_printerr ("namespace '%s' not registered\n", namespace); } @@ -189,24 +246,15 @@ gboolean g_irepository_is_registered (GIRepository *repository, const gchar *namespace) { - GHashTable *table; + repository = get_repository (repository); - if (repository != NULL) - table = repository->priv->typelib; - else - { - init_globals (); - table = default_typelib; - } - - return g_hash_table_lookup (table, namespace) != NULL; + return g_hash_table_lookup (repository->priv->typelibs, namespace) != NULL; } GIRepository * g_irepository_get_default (void) { - init_globals (); - return default_repository; + return get_repository (NULL); } static void @@ -225,19 +273,21 @@ g_irepository_get_n_infos (GIRepository *repository, const gchar *namespace) { gint n_interfaces = 0; + + repository = get_repository (repository); if (namespace) { GTypelib *typelib; - typelib = g_hash_table_lookup (repository->priv->typelib, namespace); + typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); if (typelib) n_interfaces = ((Header *)typelib->data)->n_local_entries; } else { - g_hash_table_foreach (repository->priv->typelib, + g_hash_table_foreach (repository->priv->typelibs, count_interfaces, &n_interfaces); } @@ -323,6 +373,8 @@ g_irepository_get_info (GIRepository *repository, { IfaceData data; + repository = get_repository (repository); + data.name = NULL; data.type = NULL; data.index = index + 1; @@ -332,13 +384,13 @@ g_irepository_get_info (GIRepository *repository, { GTypelib *typelib; - typelib = g_hash_table_lookup (repository->priv->typelib, namespace); + typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); if (typelib) find_interface ((void *)namespace, typelib, &data); } else - g_hash_table_foreach (repository->priv->typelib, find_interface, &data); + g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); return data.iface; } @@ -349,12 +401,14 @@ g_irepository_find_by_gtype (GIRepository *repository, { IfaceData data; + repository = get_repository (repository); + data.name = NULL; data.type = g_type_name (type); data.index = -1; data.iface = NULL; - g_hash_table_foreach (repository->priv->typelib, find_interface, &data); + g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); return data.iface; } @@ -377,6 +431,8 @@ g_irepository_find_by_name (GIRepository *repository, { IfaceData data; + repository = get_repository (repository); + data.name = name; data.type = NULL; data.index = -1; @@ -386,13 +442,13 @@ g_irepository_find_by_name (GIRepository *repository, { GTypelib *typelib; - typelib = g_hash_table_lookup (repository->priv->typelib, namespace); + typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); if (typelib) find_interface ((void *)namespace, typelib, &data); } else - g_hash_table_foreach (repository->priv->typelib, find_interface, &data); + g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); return data.iface; } @@ -424,7 +480,9 @@ g_irepository_get_namespaces (GIRepository *repository) gchar **names; gint i; - g_hash_table_foreach (repository->priv->typelib, collect_namespaces, &list); + repository = get_repository (repository); + + g_hash_table_foreach (repository->priv->typelibs, collect_namespaces, &list); names = g_malloc0 (sizeof (gchar *) * (g_list_length (list) + 1)); i = 0; @@ -442,7 +500,9 @@ g_irepository_get_shared_library (GIRepository *repository, GTypelib *typelib; Header *header; - typelib = g_hash_table_lookup (repository->priv->typelib, namespace); + repository = get_repository (repository); + + typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); if (!typelib) return NULL; header = (Header *) typelib->data; @@ -471,7 +531,9 @@ g_irepository_get_typelib_path (GIRepository *repository, { gpointer orig_key, value; - if (!g_hash_table_lookup_extended (repository->priv->typelib, namespace, + repository = get_repository (repository); + + if (!g_hash_table_lookup_extended (repository->priv->typelibs, namespace, &orig_key, &value)) return NULL; return ((char*)orig_key) + strlen ((char *) orig_key) + 1; @@ -488,9 +550,9 @@ g_irepository_get_typelib_path (GIRepository *repository, * search for a ".typelib" file using the repository search * path. * - * Returns: Namespace if successful, NULL otherwise + * Returns: %TRUE if successful, %NULL otherwise */ -const gchar * +gboolean g_irepository_require (GIRepository *repository, const gchar *namespace, GError **error) @@ -506,17 +568,12 @@ g_irepository_require (GIRepository *repository, guint32 shlib; GHashTable *table; - if (repository != NULL) - table = repository->priv->typelib; - else - { - init_globals (); - table = default_typelib; - } + repository = get_repository (repository); + table = repository->priv->typelibs; /* don't bother loading a namespace if already registered */ if (g_hash_table_lookup (table, namespace)) - return namespace; + return TRUE; fname = g_strconcat (namespace, ".typelib", NULL); @@ -544,7 +601,7 @@ g_irepository_require (GIRepository *repository, "namespace '%s' which doesn't match the file name", full_path, namespace, typelib_namespace); g_free (full_path); - return NULL; + return FALSE; } break; } @@ -556,14 +613,18 @@ g_irepository_require (GIRepository *repository, "Typelib file for namespace '%s' was not found in search" " path or could not be openened", namespace); g_free (full_path); - return NULL; + return FALSE; } g_free (fname); - g_hash_table_remove (table, namespace); - register_internal (repository, full_path, typelib); + if (!register_internal (repository, full_path, typelib, error)) + { + g_typelib_free (typelib); + g_free (full_path); + return FALSE; + } g_free (full_path); - return namespace; + return TRUE; } diff --git a/girepository.h b/girepository.h index 4c6801697..f3b1f4844 100644 --- a/girepository.h +++ b/girepository.h @@ -72,8 +72,10 @@ struct _GIRepositoryClass GType g_irepository_get_type (void) G_GNUC_CONST; GIRepository *g_irepository_get_default (void); -const gchar * g_irepository_register (GIRepository *repository, - GTypelib *typelib); +void g_irepository_prepend_search_path (const char *directory); +const char * g_irepository_load_typelib (GIRepository *repository, + GTypelib *typelib, + GError **error); void g_irepository_unregister (GIRepository *repository, const gchar *namespace); gboolean g_irepository_is_registered (GIRepository *repository, @@ -81,9 +83,11 @@ gboolean g_irepository_is_registered (GIRepository *repository, GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, const gchar *namespace, const gchar *name); -const char * g_irepository_require (GIRepository *repository, +gboolean g_irepository_require (GIRepository *repository, const char *namespace, GError **error); +gchar ** g_irepository_get_dependencies (GIRepository *repository, + const char *namespace); gchar ** g_irepository_get_namespaces (GIRepository *repository); GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository, GType gtype); @@ -142,8 +146,7 @@ typedef enum GI_INFO_TYPE_PROPERTY, GI_INFO_TYPE_FIELD, GI_INFO_TYPE_ARG, - GI_INFO_TYPE_TYPE, - GI_INFO_TYPE_UNRESOLVED + GI_INFO_TYPE_TYPE } GIInfoType; diff --git a/girmodule.c b/girmodule.c index 1077a487f..65ee392d9 100644 --- a/girmodule.c +++ b/girmodule.c @@ -33,13 +33,14 @@ g_ir_module_new (const gchar *name, const gchar *shared_library) { GIrModule *module; - module = g_new (GIrModule, 1); + module = g_new0 (GIrModule, 1); module->name = g_strdup (name); if (shared_library) module->shared_library = g_strdup (shared_library); else module->shared_library = NULL; + module->dependencies = NULL; module->entries = NULL; return module; @@ -56,6 +57,7 @@ g_ir_module_free (GIrModule *module) g_ir_node_free ((GIrNode *)e->data); g_list_free (module->entries); + /* Don't free dependencies, we inherit that from the parser */ g_free (module); } @@ -77,18 +79,42 @@ g_ir_module_build_typelib (GIrModule *module, guint32 size, offset, offset2, old_offset; GHashTable *strings; GHashTable *types; + char *dependencies; guchar *data; header_size = ALIGN_VALUE (sizeof (Header), 4); n_local_entries = g_list_length (module->entries); + /* Serialize dependencies into one string; this is convenient + * and not a major change to the typelib format. */ + { + GString *dependencies_str = g_string_new (""); + GList *link; + for (link = module->dependencies; link; link = link->next) + { + const char *dependency = link->data; + if (!strcmp (dependency, module->name)) + continue; + g_string_append (dependencies_str, dependency); + if (link->next) + g_string_append_c (dependencies_str, '|'); + } + dependencies = g_string_free (dependencies_str, FALSE); + if (!dependencies[0]) + { + g_free (dependencies); + dependencies = NULL; + } + } + 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); + g_message ("%d entries (%d local), %d dependencies\n", n_entries, n_local_entries, + g_list_length (module->dependencies)); dir_size = n_entries * 12; size = header_size + dir_size; @@ -106,6 +132,8 @@ g_ir_module_build_typelib (GIrModule *module, size += strlen (module->name); if (module->shared_library) size += strlen (module->shared_library); + if (dependencies != NULL) + size += strlen (dependencies); g_message ("allocating %d bytes (%d header, %d directory, %d entries)\n", size, header_size, dir_size, size - header_size - dir_size); @@ -122,6 +150,10 @@ g_ir_module_build_typelib (GIrModule *module, header->n_local_entries = n_local_entries; header->n_annotations = 0; header->annotations = 0; /* filled in later */ + if (dependencies != NULL) + header->dependencies = write_string (dependencies, strings, data, &header_size); + else + header->dependencies = 0; header->size = 0; /* filled in later */ header->namespace = write_string (module->name, strings, data, &header_size); header->shared_library = (module->shared_library? @@ -180,9 +212,11 @@ g_ir_module_build_typelib (GIrModule *module, if (node->type == G_IR_NODE_XREF) { + const char *namespace = ((GIrNodeXRef*)node)->namespace; + entry->blob_type = 0; entry->local = FALSE; - entry->offset = write_string (((GIrNodeXRef*)node)->namespace, strings, data, &offset2); + entry->offset = write_string (namespace, strings, data, &offset2); entry->name = write_string (node->name, strings, data, &offset2); } else diff --git a/girmodule.h b/girmodule.h index 67c6ef7a0..a4511e3b7 100644 --- a/girmodule.h +++ b/girmodule.h @@ -33,6 +33,7 @@ struct _GIrModule { gchar *name; gchar *shared_library; + GList *dependencies; GList *entries; }; diff --git a/girparser.c b/girparser.c index 77a2b60d7..267092c33 100644 --- a/girparser.c +++ b/girparser.c @@ -72,6 +72,7 @@ struct _ParseContext GList *modules; gboolean prefix_aliases; + GList *dependencies; GHashTable *aliases; const char *namespace; @@ -2188,6 +2189,9 @@ start_element_handler (GMarkupParseContext *context, if (!parse_include (context, ctx, name, error)) break; + ctx->dependencies = g_list_prepend (ctx->dependencies, g_strdup (name)); + + state_switch (ctx, STATE_INCLUDE); goto out; } @@ -2226,6 +2230,7 @@ start_element_handler (GMarkupParseContext *context, { ctx->current_module = g_ir_module_new (name, shared_library); ctx->modules = g_list_append (ctx->modules, ctx->current_module); + ctx->current_module->dependencies = ctx->dependencies; state_switch (ctx, STATE_NAMESPACE); goto out; @@ -2704,6 +2709,7 @@ g_ir_parse_string (const gchar *namespace, ctx.namespace = namespace; ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); ctx.type_depth = 0; + ctx.dependencies = NULL; ctx.current_module = NULL; context = g_markup_parse_context_new (&firstpass_parser, 0, &ctx, NULL); diff --git a/gtypelib.c b/gtypelib.c index e889d6998..3940a329d 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -152,7 +152,7 @@ g_typelib_check_sanity (void) size_check_ok = FALSE; \ } - CHECK_SIZE (Header, 100); + CHECK_SIZE (Header, 104); CHECK_SIZE (DirEntry, 12); CHECK_SIZE (SimpleTypeBlob, 4); CHECK_SIZE (ArgBlob, 12); diff --git a/gtypelib.h b/gtypelib.h index 9213bbbb0..31c484db4 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -57,6 +57,8 @@ typedef struct guint32 n_annotations; guint32 annotations; + guint32 dependencies; + guint32 size; guint32 namespace; guint32 shared_library; From e6a68106a2a9609225cff148055c66d334f6e74f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 30 Aug 2008 20:31:10 +0000 Subject: [PATCH 081/692] Don't lose on NULL shlib svn path=/trunk/; revision=542 --- gtypelib.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gtypelib.c b/gtypelib.c index 3940a329d..cc62b47a4 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1962,7 +1962,11 @@ _g_typelib_init (GTypelib *typelib) } } +<<<<<<< HEAD:girepository/gtypelib.c if (typelib->module == NULL && shlib != NULL) +======= + if (shlib != NULL && typelib->module == NULL) +>>>>>>> Don't lose on NULL shlib:girepository/gtypelib.c { GString *shlib_full; From 74651b01bdab5922ad8e14bbdacdb1916035bfe0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 30 Aug 2008 20:31:12 +0000 Subject: [PATCH 082/692] Remove g_irepository_unregister, add GIRepositoryLoadFlags svn path=/trunk/; revision=543 --- girepository.c | 196 +++++++++++++++++++++++++++++++++---------------- girepository.h | 8 +- 2 files changed, 139 insertions(+), 65 deletions(-) diff --git a/girepository.c b/girepository.c index be8ddca33..5320fd9a8 100644 --- a/girepository.c +++ b/girepository.c @@ -35,6 +35,7 @@ static GSList *search_path = NULL; struct _GIRepositoryPrivate { GHashTable *typelibs; /* (string) namespace -> GTypelib */ + GHashTable *lazy_typelibs; /* (string) namespace -> GTypelib */ }; G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT); @@ -44,6 +45,12 @@ g_irepository_init (GIRepository *repository) { repository->priv = G_TYPE_INSTANCE_GET_PRIVATE (repository, G_TYPE_IREPOSITORY, GIRepositoryPrivate); + repository->priv->typelibs + = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) NULL, + (GDestroyNotify) g_typelib_free); + repository->priv->lazy_typelibs + = g_hash_table_new (g_str_hash, g_str_equal); } static void @@ -76,10 +83,6 @@ init_globals () if (default_repository == NULL) { default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL); - default_repository->priv->typelibs - = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) NULL, - (GDestroyNotify) g_typelib_free); } if (search_path == NULL) @@ -135,13 +138,7 @@ static GIRepository * get_repository (GIRepository *repository) { if (repository != NULL) - { - if (repository->priv->typelibs == NULL) - repository->priv->typelibs = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) NULL, - (GDestroyNotify) g_typelib_free); - return repository; - } + return repository; else { init_globals (); @@ -149,16 +146,76 @@ get_repository (GIRepository *repository) } } +static GTypelib * +get_registered_status (GIRepository *repository, + const char *namespace, + gboolean allow_lazy, + gboolean *lazy_status) +{ + GTypelib *typelib; + repository = get_repository (repository); + if (lazy_status) + *lazy_status = FALSE; + typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); + if (typelib) + return typelib; + typelib = g_hash_table_lookup (repository->priv->lazy_typelibs, namespace); + if (!typelib) + return NULL; + if (lazy_status) + *lazy_status = TRUE; + if (!allow_lazy) + return NULL; + return typelib; +} + +static GTypelib * +get_registered (GIRepository *repository, + const char *namespace) +{ + return get_registered_status (repository, namespace, TRUE, NULL); +} + +static gboolean +load_dependencies_recurse (GIRepository *repository, + GTypelib *typelib, + GError **error) +{ + char **dependencies; + + dependencies = get_typelib_dependencies (typelib); + + if (dependencies != NULL) + { + int i; + + for (i = 0; dependencies[i]; i++) + { + char *dependency = dependencies[i]; + + if (!g_irepository_require (repository, dependency, + 0, error)) + { + g_strfreev (dependencies); + return FALSE; + } + } + g_strfreev (dependencies); + } + return TRUE; +} + static const char * register_internal (GIRepository *repository, const char *source, + gboolean lazy, GTypelib *typelib, GError **error) { Header *header; - const gchar *name; - const char *dependencies_glob; - char **dependencies; + const gchar *namespace; + gboolean was_loaded; + gboolean currently_lazy; g_return_val_if_fail (typelib != NULL, FALSE); @@ -166,34 +223,39 @@ register_internal (GIRepository *repository, g_return_val_if_fail (header != NULL, FALSE); - name = g_typelib_get_string (typelib, header->namespace); + namespace = g_typelib_get_string (typelib, header->namespace); - dependencies = get_typelib_dependencies (typelib); - if (dependencies != NULL) + if (lazy) { - int i; - - for (i = 0; dependencies[i]; i++) - { - char *dependency = dependencies[i]; - - if (!g_irepository_require (repository, dependency, error)) - { - g_strfreev (dependencies); - return NULL; - } - } - g_strfreev (dependencies); + g_assert (!g_hash_table_lookup (repository->priv->lazy_typelibs, + namespace)); + g_hash_table_insert (repository->priv->lazy_typelibs, + build_typelib_key (namespace, source), (void *)typelib); } + else + { + gpointer value; + char *key; - g_assert (g_hash_table_lookup (repository->priv->typelibs, name) == NULL); - g_hash_table_insert (repository->priv->typelibs, - build_typelib_key (name, source), (void *)typelib); + /* First, try loading all the dependencies */ + if (!load_dependencies_recurse (repository, typelib, error)) + return NULL; + + /* Check if we are transitioning from lazily loaded state */ + if (g_hash_table_lookup_extended (repository->priv->lazy_typelibs, + namespace, + (gpointer)&key, &value)) + g_hash_table_remove (repository->priv->lazy_typelibs, key); + else + key = build_typelib_key (namespace, source); + + g_hash_table_insert (repository->priv->typelibs, key, (void *)typelib); + } if (typelib->module == NULL) typelib->module = g_module_open (NULL, 0); - return name; + return namespace; } char ** @@ -206,7 +268,7 @@ g_irepository_get_dependencies (GIRepository *repository, repository = get_repository (repository); - typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); + typelib = get_registered (repository, namespace); g_return_val_if_fail (typelib != NULL, NULL); return get_typelib_dependencies (typelib); @@ -215,31 +277,23 @@ g_irepository_get_dependencies (GIRepository *repository, const char * g_irepository_load_typelib (GIRepository *repository, GTypelib *typelib, + GIRepositoryLoadFlags flags, GError **error) { Header *header; const char *namespace; + gboolean allow_lazy = flags & G_IREPOSITORY_LOAD_FLAG_LAZY; + gboolean is_lazy; repository = get_repository (repository); header = (Header *) typelib->data; namespace = g_typelib_get_string (typelib, header->namespace); - if (g_hash_table_lookup (repository->priv->typelibs, namespace)) + if (get_registered_status (repository, namespace, allow_lazy, &is_lazy)) return namespace; - return register_internal (repository, "", typelib, error); -} - -void -g_irepository_unregister (GIRepository *repository, - const gchar *namespace) -{ - repository = get_repository (repository); - - if (!g_hash_table_remove (repository->priv->typelibs, namespace)) - { - g_printerr ("namespace '%s' not registered\n", namespace); - } + return register_internal (repository, "", + allow_lazy, typelib, error); } gboolean @@ -247,8 +301,7 @@ g_irepository_is_registered (GIRepository *repository, const gchar *namespace) { repository = get_repository (repository); - - return g_hash_table_lookup (repository->priv->typelibs, namespace) != NULL; + return get_registered (repository, namespace) != NULL; } GIRepository * @@ -280,7 +333,7 @@ g_irepository_get_n_infos (GIRepository *repository, { GTypelib *typelib; - typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); + typelib = get_registered (repository, namespace); if (typelib) n_interfaces = ((Header *)typelib->data)->n_local_entries; @@ -289,6 +342,8 @@ g_irepository_get_n_infos (GIRepository *repository, { g_hash_table_foreach (repository->priv->typelibs, count_interfaces, &n_interfaces); + g_hash_table_foreach (repository->priv->lazy_typelibs, + count_interfaces, &n_interfaces); } return n_interfaces; @@ -384,13 +439,16 @@ g_irepository_get_info (GIRepository *repository, { GTypelib *typelib; - typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); + typelib = get_registered (repository, namespace); if (typelib) find_interface ((void *)namespace, typelib, &data); } else - g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); + { + g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); + g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data); + } return data.iface; } @@ -409,6 +467,7 @@ g_irepository_find_by_gtype (GIRepository *repository, data.iface = NULL; g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); + g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data); return data.iface; } @@ -442,13 +501,16 @@ g_irepository_find_by_name (GIRepository *repository, { GTypelib *typelib; - typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); + typelib = get_registered (repository, namespace); if (typelib) find_interface ((void *)namespace, typelib, &data); } else - g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); + { + g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); + g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data); + } return data.iface; } @@ -483,6 +545,7 @@ g_irepository_get_namespaces (GIRepository *repository) repository = get_repository (repository); g_hash_table_foreach (repository->priv->typelibs, collect_namespaces, &list); + g_hash_table_foreach (repository->priv->lazy_typelibs, collect_namespaces, &list); names = g_malloc0 (sizeof (gchar *) * (g_list_length (list) + 1)); i = 0; @@ -502,7 +565,7 @@ g_irepository_get_shared_library (GIRepository *repository, repository = get_repository (repository); - typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); + typelib = get_registered (repository, namespace); if (!typelib) return NULL; header = (Header *) typelib->data; @@ -535,7 +598,12 @@ g_irepository_get_typelib_path (GIRepository *repository, if (!g_hash_table_lookup_extended (repository->priv->typelibs, namespace, &orig_key, &value)) - return NULL; + { + if (!g_hash_table_lookup_extended (repository->priv->lazy_typelibs, namespace, + &orig_key, &value)) + + return NULL; + } return ((char*)orig_key) + strlen ((char *) orig_key) + 1; } @@ -543,6 +611,7 @@ g_irepository_get_typelib_path (GIRepository *repository, * g_irepository_require * @repository: Repository, may be %NULL for the default * @namespace: GI namespace to use, e.g. "Gtk" + * @flags: Set of %GIRepositoryLoadFlags, may be %0 * @error: a #GError. * * Force the namespace @namespace to be loaded if it isn't @@ -555,6 +624,7 @@ g_irepository_get_typelib_path (GIRepository *repository, gboolean g_irepository_require (GIRepository *repository, const gchar *namespace, + GIRepositoryLoadFlags flags, GError **error) { GSList *ldir; @@ -566,13 +636,12 @@ g_irepository_require (GIRepository *repository, const gchar *typelib_namespace, *shlib_fname; GModule *module; guint32 shlib; - GHashTable *table; + gboolean allow_lazy = flags & G_IREPOSITORY_LOAD_FLAG_LAZY; + gboolean is_lazy; repository = get_repository (repository); - table = repository->priv->typelibs; - /* don't bother loading a namespace if already registered */ - if (g_hash_table_lookup (table, namespace)) + if (get_registered_status (repository, namespace, allow_lazy, &is_lazy)) return TRUE; fname = g_strconcat (namespace, ".typelib", NULL); @@ -617,7 +686,8 @@ g_irepository_require (GIRepository *repository, } g_free (fname); - if (!register_internal (repository, full_path, typelib, error)) + if (!register_internal (repository, full_path, allow_lazy, + typelib, error)) { g_typelib_free (typelib); g_free (full_path); diff --git a/girepository.h b/girepository.h index f3b1f4844..ecbead0a8 100644 --- a/girepository.h +++ b/girepository.h @@ -67,6 +67,10 @@ struct _GIRepositoryClass GObjectClass parent; }; +typedef enum +{ + G_IREPOSITORY_LOAD_FLAG_LAZY = 1 << 0 +} GIRepositoryLoadFlags; /* Repository */ @@ -75,9 +79,8 @@ GIRepository *g_irepository_get_default (void); void g_irepository_prepend_search_path (const char *directory); const char * g_irepository_load_typelib (GIRepository *repository, GTypelib *typelib, + GIRepositoryLoadFlags flags, GError **error); -void g_irepository_unregister (GIRepository *repository, - const gchar *namespace); gboolean g_irepository_is_registered (GIRepository *repository, const gchar *namespace); GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, @@ -85,6 +88,7 @@ GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, const gchar *name); gboolean g_irepository_require (GIRepository *repository, const char *namespace, + GIRepositoryLoadFlags flags, GError **error); gchar ** g_irepository_get_dependencies (GIRepository *repository, const char *namespace); From 5a14ec555c5fdc8f50a2d59975ca0630f862a9e7 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 30 Aug 2008 20:31:14 +0000 Subject: [PATCH 083/692] Fix conflict svn path=/trunk/; revision=544 --- gtypelib.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gtypelib.c b/gtypelib.c index cc62b47a4..3940a329d 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1962,11 +1962,7 @@ _g_typelib_init (GTypelib *typelib) } } -<<<<<<< HEAD:girepository/gtypelib.c if (typelib->module == NULL && shlib != NULL) -======= - if (shlib != NULL && typelib->module == NULL) ->>>>>>> Don't lose on NULL shlib:girepository/gtypelib.c { GString *shlib_full; From dcd4fe622a68c666f688c72ef44bccab13a32546 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 30 Aug 2008 20:31:16 +0000 Subject: [PATCH 084/692] Add back unresolved svn path=/trunk/; revision=545 --- ginfo.c | 30 ++++++++++++++++++++++++------ girepository.h | 3 ++- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/ginfo.c b/ginfo.c index e7d07dbb3..95b9b7add 100644 --- a/ginfo.c +++ b/ginfo.c @@ -174,12 +174,17 @@ g_info_from_entry (GTypelib *typelib, result = g_irepository_find_by_name (repository, namespace, name); if (result == NULL) { - char **all_namespaces = g_irepository_get_namespaces (repository); - char *namespaces_str = g_strjoinv (", ", all_namespaces); - g_critical ("Failed to find namespace: %s name: %s (currently loaded namespaces: %s)", namespace, - name, namespaces_str); - g_strfreev (all_namespaces); - g_free (namespaces_str); + GIUnresolvedInfo *unresolved; + + unresolved = g_new0 (GIUnresolvedInfo, 1); + + unresolved->type = GI_INFO_TYPE_UNRESOLVED; + unresolved->ref_count = 1; + unresolved->container = NULL; + unresolved->name = name; + unresolved->namespace = namespace; + + return (GIBaseInfo*)unresolved; } return result; } @@ -289,7 +294,13 @@ g_base_info_get_name (GIBaseInfo *info) return g_typelib_get_string (info->typelib, blob->name); } break; + case GI_INFO_TYPE_UNRESOLVED: + { + GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info; + return unresolved->name; + } + break; case GI_INFO_TYPE_TYPE: default: ; g_assert_not_reached (); @@ -306,6 +317,13 @@ g_base_info_get_namespace (GIBaseInfo *info) g_assert (info->ref_count > 0); + if (info->type == GI_INFO_TYPE_UNRESOLVED) + { + GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info; + + return unresolved->namespace; + } + return g_typelib_get_string (info->typelib, header->namespace); } diff --git a/girepository.h b/girepository.h index ecbead0a8..0a7bbb78d 100644 --- a/girepository.h +++ b/girepository.h @@ -150,7 +150,8 @@ typedef enum GI_INFO_TYPE_PROPERTY, GI_INFO_TYPE_FIELD, GI_INFO_TYPE_ARG, - GI_INFO_TYPE_TYPE + GI_INFO_TYPE_TYPE, + GI_INFO_TYPE_UNRESOLVED } GIInfoType; From ae48f17999bd3262642f13127c9b1ac3befabd06 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 31 Aug 2008 16:01:02 +0000 Subject: [PATCH 085/692] Don't lose if we have no includedirs * girepository/girparser.c: Don't lose if we have no includedirs svn path=/trunk/; revision=551 --- girparser.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/girparser.c b/girparser.c index 267092c33..b7ad408f1 100644 --- a/girparser.c +++ b/girparser.c @@ -148,13 +148,16 @@ locate_gir (const char *name, const char * const* extra_paths) g_free (path); path = NULL; } - for (dir = extra_paths; *dir; dir++) + if (extra_paths != NULL) { - path = g_build_filename (*dir, girname, NULL); - if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) - return path; - g_free (path); - path = NULL; + for (dir = extra_paths; *dir; dir++) + { + path = g_build_filename (*dir, girname, NULL); + if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) + return path; + g_free (path); + path = NULL; + } } g_free (girname); return path; From 71473eb033ff1157470d67d6c200f7d51e0dcc8c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 1 Sep 2008 18:52:34 +0000 Subject: [PATCH 086/692] Look in c:type to determine pointer nature * girepository/girparser.c: Look at c:type to determine whether or not an item is a pointer. svn path=/trunk/; revision=571 --- girparser.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/girparser.c b/girparser.c index b7ad408f1..11152d84f 100644 --- a/girparser.c +++ b/girparser.c @@ -330,11 +330,6 @@ parse_type_internal (const gchar *str, char **next, gboolean in_glib) type->is_pointer = basic->pointer; str += strlen(basic->str); - if (*str == '*' && !type->is_pointer) - { - type->is_pointer = TRUE; - (str)++; - } } else if (in_glib) { @@ -484,12 +479,6 @@ parse_type_internal (const gchar *str, char **next, gboolean in_glib) (str)++; type->interface = g_strndup (start, str - start); - - if (*str == '*') - { - type->is_pointer = TRUE; - (str)++; - } } if (g_str_has_prefix (str, "[")) @@ -1552,6 +1541,9 @@ start_type (GMarkupParseContext *context, GError **error) { const gchar *name; + const gchar *ctype; + gboolean is_pointer; + GIrNodeType *typenode; if (strcmp (element_name, "type") != 0) return FALSE; @@ -1593,31 +1585,41 @@ start_type (GMarkupParseContext *context, if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); - + + ctype = find_attribute ("c:type", attribute_names, attribute_values); + if (ctype != NULL && strchr (ctype, '*')) + is_pointer = TRUE; + else + is_pointer = FALSE; + + typenode = parse_type (ctx, name); + if (is_pointer) + typenode->is_pointer = is_pointer; + switch (ctx->current_typed->type) { case G_IR_NODE_PARAM: { GIrNodeParam *param = (GIrNodeParam *)ctx->current_typed; - param->type = parse_type (ctx, name); + param->type = typenode; } break; case G_IR_NODE_FIELD: { GIrNodeField *field = (GIrNodeField *)ctx->current_typed; - field->type = parse_type (ctx, name); + field->type = typenode; } break; case G_IR_NODE_PROPERTY: { GIrNodeProperty *property = (GIrNodeProperty *) ctx->current_typed; - property->type = parse_type (ctx, name); + property->type = typenode; } break; case G_IR_NODE_CONSTANT: { GIrNodeConstant *constant = (GIrNodeConstant *)ctx->current_typed; - constant->type = parse_type (ctx, name); + constant->type = typenode; } break; default: @@ -1625,6 +1627,7 @@ start_type (GMarkupParseContext *context, g_assert_not_reached (); } + ctx->current_typed = NULL; return TRUE; } From 8f09203dda0e84552d74270490daa12f61bc3e57 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 6 Sep 2008 20:33:51 +0000 Subject: [PATCH 087/692] Allow both union and struct to be boxed or not * girepository/girnode.c: Allow gtype_name and gtype_init in struct and union. * girepository/girparser.c: Parse glib: boxed bits for both structure and union. * girepository/gtypelib.c: Don't barf if structure is boxed. * giscanner/girparser.py: Parse new XML format. * giscanner/girwriter.py: Write out new XML format. * giscanner/glibast.py: Define new classes which are both Boxed and Struct/Union, as well as an "Other" for everything else. * giscanner/glibtransformer.py: Handle boxed types specially; we try to merge them with a struct/union if one exists, otherwise fall back to generic boxed. * tests/*: Update. * tools/generate.c: Write out new format. svn path=/trunk/; revision=575 --- girnode.c | 26 +++++++++++++++++++++++--- girnode.h | 3 +++ girparser.c | 53 +++++++++++++++++++++++++++++++++++------------------ gtypelib.c | 12 +----------- 4 files changed, 62 insertions(+), 32 deletions(-) diff --git a/girnode.c b/girnode.c index fd74dd9ff..2c557b5c7 100644 --- a/girnode.c +++ b/girnode.c @@ -339,6 +339,9 @@ g_ir_node_free (GIrNode *node) GIrNodeStruct *struct_ = (GIrNodeStruct *)node; g_free (node->name); + g_free (struct_->gtype_name); + g_free (struct_->gtype_init); + for (l = struct_->members; l; l = l->next) g_ir_node_free ((GIrNode *)l->data); g_list_free (struct_->members); @@ -706,6 +709,10 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size = 20; size += ALIGN_VALUE (strlen (node->name) + 1, 4); + if (struct_->gtype_name) + size += ALIGN_VALUE (strlen (struct_->gtype_name) + 1, 4); + if (struct_->gtype_init) + size += ALIGN_VALUE (strlen (struct_->gtype_init) + 1, 4); for (l = struct_->members; l; l = l->next) size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); } @@ -809,6 +816,10 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size = 28; size += ALIGN_VALUE (strlen (node->name) + 1, 4); + if (union_->gtype_name) + size += ALIGN_VALUE (strlen (union_->gtype_name) + 1, 4); + if (union_->gtype_init) + size += ALIGN_VALUE (strlen (union_->gtype_init) + 1, 4); for (l = union_->members; l; l = l->next) size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); for (l = union_->discriminators; l; l = l->next) @@ -1594,11 +1605,20 @@ g_ir_node_build_typelib (GIrNode *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; + if (struct_->gtype_name) + { + blob->unregistered = FALSE; + blob->gtype_name = write_string (struct_->gtype_name, strings, data, offset2); + blob->gtype_init = write_string (struct_->gtype_init, strings, data, offset2); + } + else + { + blob->unregistered = TRUE; + blob->gtype_name = 0; + blob->gtype_init = 0; + } blob->n_fields = 0; blob->n_methods = 0; diff --git a/girnode.h b/girnode.h index 6079d367a..67027aecc 100644 --- a/girnode.h +++ b/girnode.h @@ -272,6 +272,9 @@ struct _GIrNodeStruct GIrNode node; gboolean deprecated; + + gchar *gtype_name; + gchar *gtype_init; GList *members; }; diff --git a/girparser.c b/girparser.c index 11152d84f..980d58d45 100644 --- a/girparser.c +++ b/girparser.c @@ -1889,30 +1889,47 @@ start_struct (GMarkupParseContext *context, { const gchar *name; const gchar *deprecated; + const gchar *gtype_name; + const gchar *gtype_init; + GIrNodeStruct *struct_; name = find_attribute ("name", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - + gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values); + gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values); + if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else { - GIrNodeStruct *struct_; - - struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT); - - ((GIrNode *)struct_)->name = g_strdup (name); - if (deprecated && strcmp (deprecated, "1") == 0) - struct_->deprecated = TRUE; - else - struct_->deprecated = FALSE; - - ctx->current_node = (GIrNode *)struct_; - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, struct_); - - state_switch (ctx, STATE_STRUCT); + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } + if ((gtype_name == NULL && gtype_init != NULL)) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); + return FALSE; + } + if ((gtype_name != NULL && gtype_init == NULL)) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); + return FALSE; + } + + struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT); + + ((GIrNode *)struct_)->name = g_strdup (name); + if (deprecated && strcmp (deprecated, "1") == 0) + struct_->deprecated = TRUE; + else + struct_->deprecated = FALSE; + + struct_->gtype_name = g_strdup (gtype_name); + struct_->gtype_init = g_strdup (gtype_init); + + ctx->current_node = (GIrNode *)struct_; + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, struct_); + + state_switch (ctx, STATE_STRUCT); return TRUE; } return FALSE; diff --git a/gtypelib.c b/gtypelib.c index 3940a329d..50abcb57e 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1173,23 +1173,13 @@ validate_struct_blob (ValidateContext *ctx, "Wrong blob type"); return FALSE; } - - if ((blob->blob_type == BLOB_TYPE_BOXED && blob->unregistered) || - (blob->blob_type == BLOB_TYPE_STRUCT && !blob->unregistered)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Registration/blob type mismatch"); - return FALSE; - } if (!validate_name (typelib, "struct", typelib->data, blob->name, error)) return FALSE; push_context (ctx, get_string_nofail (typelib, blob->name)); - if (blob_type == BLOB_TYPE_BOXED) + if (!blob->unregistered) { if (!validate_name (typelib, "boxed", typelib->data, blob->gtype_name, error)) return FALSE; From 7a55bd25d9e65e3c687e2f14a877aeb65d208883 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 8 Sep 2008 22:24:09 +0000 Subject: [PATCH 088/692] Write out and parse full GObject property information (readable, writable, etc) * girepository/girparser.c: Default to "readable" for properties. * giscanner/ast.py: Add readable, writable etc. * giscanner/girwriter.py: Writ them. * giscanner/glibtransformer.py: Inspect them. * tests/*: Update. svn path=/trunk/; revision=587 --- girparser.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index 980d58d45..b656dc2a2 100644 --- a/girparser.c +++ b/girparser.c @@ -1191,7 +1191,8 @@ start_property (GMarkupParseContext *context, ((GIrNode *)property)->name = g_strdup (name); - if (readable && strcmp (readable, "1") == 0) + /* Assume properties are readable */ + if (readable == NULL || strcmp (readable, "1") == 0) property->readable = TRUE; else property->readable = FALSE; From 0ab7337756bd9cb0fab3b47a21e7a055037b37b0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 15 Sep 2008 14:46:19 +0000 Subject: [PATCH 089/692] Bug 552065: Add deprecation information to GIR * giscanner/ast.py: Add deprecation attributes. * giscanner/girwriter.py: Write out deprecation data. * girepository/girparser.c: Relax parsing; deprecated attribute now includes freeform string. * giscanner/scannerlexer.l: Parse Deprecated. * giscanner/transformer.py: Look for deprecated attribute on functions. * tests/scanner/*: Add a Deprecated test. svn path=/trunk/; revision=603 --- girparser.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/girparser.c b/girparser.c index b656dc2a2..fb95903b4 100644 --- a/girparser.c +++ b/girparser.c @@ -634,7 +634,7 @@ start_glib_boxed (GMarkupParseContext *context, ((GIrNode *)boxed)->name = g_strdup (name); boxed->gtype_name = g_strdup (typename); boxed->gtype_init = g_strdup (typeinit); - if (deprecated && strcmp (deprecated, "1") == 0) + if (deprecated) boxed->deprecated = TRUE; else boxed->deprecated = FALSE; @@ -706,7 +706,7 @@ start_function (GMarkupParseContext *context, ((GIrNode *)function)->name = g_strdup (name); function->symbol = g_strdup (symbol); function->parameters = NULL; - if (deprecated && strcmp (deprecated, "1") == 0) + if (deprecated) function->deprecated = TRUE; else function->deprecated = FALSE; @@ -1138,7 +1138,7 @@ start_enum (GMarkupParseContext *context, ((GIrNode *)enum_)->name = g_strdup (name); enum_->gtype_name = g_strdup (typename); enum_->gtype_init = g_strdup (typeinit); - if (deprecated && strcmp (deprecated, "1") == 0) + if (deprecated) enum_->deprecated = TRUE; else enum_->deprecated = FALSE; @@ -1280,7 +1280,7 @@ start_member (GMarkupParseContext *context, value_->value = parse_value (value); - if (deprecated && strcmp (deprecated, "1") == 0) + if (deprecated) value_->deprecated = TRUE; else value_->deprecated = FALSE; @@ -1330,7 +1330,7 @@ start_constant (GMarkupParseContext *context, ctx->current_typed = (GIrNode*) constant; - if (deprecated && strcmp (deprecated, "1") == 0) + if (deprecated) constant->deprecated = TRUE; else constant->deprecated = FALSE; @@ -1408,7 +1408,7 @@ start_errordomain (GMarkupParseContext *context, domain->getquark = g_strdup (getquark); domain->codes = g_strdup (codes); - if (deprecated && strcmp (deprecated, "1") == 0) + if (deprecated) domain->deprecated = TRUE; else domain->deprecated = FALSE; @@ -1460,7 +1460,7 @@ start_interface (GMarkupParseContext *context, ((GIrNode *)iface)->name = g_strdup (name); iface->gtype_name = g_strdup (typename); iface->gtype_init = g_strdup (typeinit); - if (deprecated && strcmp (deprecated, "1") == 0) + if (deprecated) iface->deprecated = TRUE; else iface->deprecated = FALSE; @@ -1516,7 +1516,7 @@ start_class (GMarkupParseContext *context, iface->gtype_name = g_strdup (typename); iface->gtype_init = g_strdup (typeinit); iface->parent = g_strdup (parent); - if (deprecated && strcmp (deprecated, "1") == 0) + if (deprecated) iface->deprecated = TRUE; else iface->deprecated = FALSE; @@ -1918,7 +1918,7 @@ start_struct (GMarkupParseContext *context, struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT); ((GIrNode *)struct_)->name = g_strdup (name); - if (deprecated && strcmp (deprecated, "1") == 0) + if (deprecated) struct_->deprecated = TRUE; else struct_->deprecated = FALSE; @@ -1969,7 +1969,7 @@ start_union (GMarkupParseContext *context, ((GIrNode *)union_)->name = g_strdup (name); union_->gtype_name = g_strdup (typename); union_->gtype_init = g_strdup (typeinit); - if (deprecated && strcmp (deprecated, "1") == 0) + if (deprecated) union_->deprecated = TRUE; else union_->deprecated = FALSE; From 450476b1a7710e0c6adcf96d3250ef9e526edfef Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 16 Sep 2008 19:44:30 +0000 Subject: [PATCH 090/692] Don't add spurious * if type is pointer; the is_pointer flag is enough svn path=/trunk/; revision=611 --- girnode.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/girnode.c b/girnode.c index 2c557b5c7..47d40e1aa 100644 --- a/girnode.c +++ b/girnode.c @@ -1086,8 +1086,7 @@ serialize_type (GIrModule *module, if (node->tag < GI_TYPE_TAG_ARRAY) { - g_string_append_printf (str, "%s%s", - basic[node->tag], node->is_pointer ? "*" : ""); + g_string_append_printf (str, "%s", basic[node->tag]); } else if (node->tag == GI_TYPE_TAG_ARRAY) { @@ -1117,7 +1116,7 @@ serialize_type (GIrModule *module, name = node->interface; } - g_string_append_printf (str, "%s%s", name, node->is_pointer ? "*" : ""); + g_string_append_printf (str, "%s", name); } else if (node->tag == GI_TYPE_TAG_GLIST) { From 4e4c8c137df38f9375af65fe6ad18fd83294439b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 19 Sep 2008 02:24:05 +0000 Subject: [PATCH 091/692] Bug 522384: Use SHLIB_SUFFIX intead of G_MODULE_SUFFIX for Darwin On Darwin, the suffix for installed shared libraries (.dylib) is different from loadable modules (.so). We use a bit of magic shell script from Behdad Esfahbod to figure out the right suffix. svn path=/trunk/; revision=612 --- gtypelib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gtypelib.c b/gtypelib.c index 50abcb57e..fc829bf2b 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -24,6 +24,7 @@ #include +#include "config.h" #include "gtypelib.h" typedef struct { @@ -1977,7 +1978,7 @@ _g_typelib_init (GTypelib *typelib) g_string_append (shlib_full, ".la"); typelib->module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); if (typelib->module == NULL) - g_string_overwrite (shlib_full, strlen (shlib_full->str)-2, G_MODULE_SUFFIX); + g_string_overwrite (shlib_full, strlen (shlib_full->str)-2, SHLIB_SUFFIX); typelib->module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); g_string_free (shlib_full, TRUE); From c760a31723a57b1168d79938d118097367f2271a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 19 Sep 2008 14:55:20 +0000 Subject: [PATCH 092/692] Validate the "this" argument for methods svn path=/trunk/; revision=615 --- gtypelib.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/gtypelib.c b/gtypelib.c index fc829bf2b..e35fe79d0 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -705,6 +705,7 @@ validate_function_blob (ValidateContext *ctx, GTypelib *typelib = ctx->typelib; FunctionBlob *blob; SignatureBlob *sigblob; + gboolean is_method; if (typelib->len < offset + sizeof (FunctionBlob)) { @@ -733,6 +734,17 @@ validate_function_blob (ValidateContext *ctx, if (!validate_name (typelib, "function symbol", typelib->data, blob->symbol, error)) return FALSE; + + switch (container_type) + { + case BLOB_TYPE_BOXED: + case BLOB_TYPE_OBJECT: + case BLOB_TYPE_INTERFACE: + is_method = !(blob->constructor || blob->setter || blob->getter || blob->wraps_vfunc); + break; + default: + is_method = FALSE; + } if (blob->constructor) { @@ -780,7 +792,6 @@ validate_function_blob (ValidateContext *ctx, } /* FIXME: validate index range */ - /* FIXME: validate "this" argument for methods */ if (!validate_signature_blob (typelib, blob->signature, error)) return FALSE; @@ -810,6 +821,53 @@ validate_function_blob (ValidateContext *ctx, return FALSE; } } + else if (is_method) + { + guint32 this_offset; + guint32 this_type_offset; + ArgBlob *this; + SimpleTypeBlob *thistype; + InterfaceTypeBlob *thistype_iface; + + if (sigblob->n_arguments == 0) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID, + "Invalid 0-argument method"); + } + + this_offset = blob->signature + sizeof (SignatureBlob); + this = (ArgBlob*) &typelib->data[this_offset]; + this_type_offset = this_offset + G_STRUCT_OFFSET (ArgBlob, arg_type); + thistype = (SimpleTypeBlob *)&typelib->data[this_type_offset]; + + if (thistype->reserved == 0 && + thistype->reserved2 == 0) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Non-reference type tag %d found for \"this\" argument", + thistype->tag); + return FALSE; + } + + thistype_iface = (InterfaceTypeBlob*)&typelib->data[thistype->offset]; + + switch (thistype_iface->tag) + { + case GI_TYPE_TAG_INTERFACE: + break; + default: + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Invalid type tag %d found for \"this\" argument", + thistype_iface->tag); + return FALSE; + } + } pop_context (ctx); From bfb6271201c6b841937dda63d7c4c5f27adfab31 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 19 Sep 2008 23:43:38 +0000 Subject: [PATCH 093/692] Strengthen check for interface vs basic types Previously we were just checking "reserved", but to be more correct we should check whether reserved2 is zero as well because it is possible for offsets to have reserved = 0 but reserved2 != 0. svn path=/trunk/; revision=620 --- ginfo.c | 20 ++++++++++---------- gtypelib.c | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ginfo.c b/ginfo.c index 95b9b7add..943d1c71b 100644 --- a/ginfo.c +++ b/ginfo.c @@ -548,7 +548,7 @@ g_type_info_new (GIBaseInfo *container, SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset]; return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, typelib, - type->reserved == 0 ? offset : type->offset); + (type->reserved == 0 && type->reserved2 == 0) ? offset : type->offset); } /** @@ -735,7 +735,7 @@ g_type_info_is_pointer (GITypeInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (type->reserved == 0) + if (type->reserved == 0 && type->reserved2 == 0) return type->pointer; else { @@ -751,7 +751,7 @@ g_type_info_get_tag (GITypeInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (type->reserved == 0) + if (type->reserved == 0 && type->reserved2 == 0) return type->tag; else { @@ -768,7 +768,7 @@ g_type_info_get_param_type (GITypeInfo *info, GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (type->reserved != 0) + if (!(type->reserved == 0 && type->reserved2 == 0)) { ParamTypeBlob *param = (ParamTypeBlob *)&base->typelib->data[base->offset]; @@ -794,7 +794,7 @@ g_type_info_get_interface (GITypeInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (type->reserved != 0) + if (!(type->reserved == 0 && type->reserved2 == 0)) { InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->typelib->data[base->offset]; @@ -811,7 +811,7 @@ g_type_info_get_array_length (GITypeInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (type->reserved != 0) + if (!(type->reserved == 0 && type->reserved2 == 0)) { ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset]; @@ -831,7 +831,7 @@ g_type_info_is_zero_terminated (GITypeInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (type->reserved != 0) + if (!(type->reserved == 0 && type->reserved2 == 0)) { ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset]; @@ -848,7 +848,7 @@ g_type_info_get_n_error_domains (GITypeInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (type->reserved != 0) + if (!(type->reserved == 0 && type->reserved2 == 0)) { ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->typelib->data[base->offset]; @@ -866,7 +866,7 @@ g_type_info_get_error_domain (GITypeInfo *info, GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (type->reserved != 0) + if (!(type->reserved == 0 && type->reserved2 == 0)) { ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->typelib->data[base->offset]; @@ -1679,7 +1679,7 @@ g_constant_info_get_value (GIConstantInfo *info, ConstantBlob *blob = (ConstantBlob *)&base->typelib->data[base->offset]; /* FIXME non-basic types ? */ - if (blob->type.reserved == 0) + if (blob->type.reserved == 0 && blob->type.reserved2 == 0) { if (blob->type.pointer) value->v_pointer = g_memdup (&base->typelib->data[blob->offset], blob->size); diff --git a/gtypelib.c b/gtypelib.c index e35fe79d0..3b7107e3a 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -968,7 +968,7 @@ validate_constant_blob (GTypelib *typelib, } type = (SimpleTypeBlob *)&typelib->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)]; - if (type->reserved == 0) + if (type->reserved == 0 && type->reserved2 == 0) { if (type->tag == 0) { From 8fc943f9415cc2f3782c99ef4f3c78df1d027d71 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 23 Sep 2008 18:20:25 +0000 Subject: [PATCH 094/692] Merge branch 'bug552566-timet/wip' svn path=/trunk/; revision=624 --- ginfo.c | 3 +++ ginvoke.c | 1 + girepository.c | 2 ++ girepository.h | 17 +++++++++-------- girnode.c | 1 + girparser.c | 1 + 6 files changed, 17 insertions(+), 8 deletions(-) diff --git a/ginfo.c b/ginfo.c index 943d1c71b..bc3847226 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1720,6 +1720,9 @@ g_constant_info_get_value (GIConstantInfo *info, case GI_TYPE_TAG_DOUBLE: value->v_double = *(gdouble*)&base->typelib->data[blob->offset]; break; + case GI_TYPE_TAG_TIME_T: + value->v_long = *(long*)&base->typelib->data[blob->offset]; + break; case GI_TYPE_TAG_INT: value->v_int = *(gint*)&base->typelib->data[blob->offset]; break; diff --git a/ginvoke.c b/ginvoke.c index 919ca8884..bbf152bfa 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -89,6 +89,7 @@ get_ffi_type (GITypeInfo *info) rettype = &ffi_type_slong; break; case GI_TYPE_TAG_SIZE: /* FIXME */ + case GI_TYPE_TAG_TIME_T: /* May not be portable */ case GI_TYPE_TAG_ULONG: rettype = &ffi_type_ulong; break; diff --git a/girepository.c b/girepository.c index 5320fd9a8..251702761 100644 --- a/girepository.c +++ b/girepository.c @@ -748,6 +748,8 @@ g_type_tag_to_string (GITypeTag type) return "float"; case GI_TYPE_TAG_DOUBLE: return "double"; + case GI_TYPE_TAG_TIME_T: + return "time_t"; case GI_TYPE_TAG_UTF8: return "utf8"; case GI_TYPE_TAG_FILENAME: diff --git a/girepository.h b/girepository.h index 0a7bbb78d..d3f68185c 100644 --- a/girepository.h +++ b/girepository.h @@ -285,14 +285,15 @@ typedef enum { GI_TYPE_TAG_SIZE = 15, GI_TYPE_TAG_FLOAT = 16, GI_TYPE_TAG_DOUBLE = 17, - GI_TYPE_TAG_UTF8 = 18, - GI_TYPE_TAG_FILENAME = 19, - 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, - GI_TYPE_TAG_ERROR = 25 + GI_TYPE_TAG_TIME_T = 18, + GI_TYPE_TAG_UTF8 = 19, + GI_TYPE_TAG_FILENAME = 20, + GI_TYPE_TAG_ARRAY = 21, + GI_TYPE_TAG_INTERFACE = 22, + GI_TYPE_TAG_GLIST = 23, + GI_TYPE_TAG_GSLIST = 24, + GI_TYPE_TAG_GHASH = 25, + GI_TYPE_TAG_ERROR = 26 } GITypeTag; const gchar* g_type_tag_to_string (GITypeTag type); diff --git a/girnode.c b/girnode.c index 47d40e1aa..fe618ad3b 100644 --- a/girnode.c +++ b/girnode.c @@ -2117,6 +2117,7 @@ g_ir_node_build_typelib (GIrNode *node, *(glong*)&data[blob->offset] = (glong) parse_int_value (constant->value); break; case GI_TYPE_TAG_SIZE: /* FIXME */ + case GI_TYPE_TAG_TIME_T: case GI_TYPE_TAG_ULONG: blob->size = sizeof (gulong); *(gulong*)&data[blob->offset] = (gulong) parse_uint_value (constant->value); diff --git a/girparser.c b/girparser.c index fb95903b4..e960fb50e 100644 --- a/girparser.c +++ b/girparser.c @@ -252,6 +252,7 @@ static BasicTypeInfo basic_types[] = { { "size", GI_TYPE_TAG_SIZE, 0 }, { "float", GI_TYPE_TAG_FLOAT, 0 }, { "double", GI_TYPE_TAG_DOUBLE, 0 }, + { "time_t", GI_TYPE_TAG_TIME_T, 0 }, { "utf8", GI_TYPE_TAG_UTF8, 1 }, { "filename", GI_TYPE_TAG_FILENAME,1 }, From f32239577e4a3d66dfc5dfaada4aae13360b3460 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 25 Sep 2008 22:33:57 +0000 Subject: [PATCH 095/692] Remove non-repository types from GIR * giscanner/ast.py: The canonical name is 'utf8', not 'string'. * giscanner/glibast.py: A few more glib type mappings. * girepository/girparser.c: We only parse repository types. * tests/*.gir: Update. svn path=/trunk/; revision=628 --- girparser.c | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/girparser.c b/girparser.c index e960fb50e..a64de0edc 100644 --- a/girparser.c +++ b/girparser.c @@ -255,44 +255,6 @@ static BasicTypeInfo basic_types[] = { { "time_t", GI_TYPE_TAG_TIME_T, 0 }, { "utf8", GI_TYPE_TAG_UTF8, 1 }, { "filename", GI_TYPE_TAG_FILENAME,1 }, - - /* FIXME: merge - do we still want this? */ - { "string", GI_TYPE_TAG_UTF8, 1 }, - - /* FIXME: Remove these */ - { "void", GI_TYPE_TAG_VOID, 0 }, - { "int8_t", GI_TYPE_TAG_INT8, 0 }, - { "uint8_t", GI_TYPE_TAG_UINT8, 0 }, - { "int16_t", GI_TYPE_TAG_INT16, 0 }, - { "uint16_t", GI_TYPE_TAG_UINT16, 0 }, - { "int32_t", GI_TYPE_TAG_INT32, 0 }, - { "uint32_t", GI_TYPE_TAG_UINT32, 0 }, - { "int64_t", GI_TYPE_TAG_INT64, 0 }, - { "uint64_t", GI_TYPE_TAG_UINT64, 0 }, - { "gpointer", GI_TYPE_TAG_VOID, 1 }, - { "gboolean", GI_TYPE_TAG_BOOLEAN, 0 }, - { "gchar", GI_TYPE_TAG_INT8, 0 }, - { "guchar", GI_TYPE_TAG_UINT8, 0 }, - { "gunichar", GI_TYPE_TAG_UINT32, 0 }, - { "gint", GI_TYPE_TAG_INT, 0 }, - { "guint", GI_TYPE_TAG_UINT, 0 }, - { "gshort", GI_TYPE_TAG_INT16, 0 }, - { "gushort", GI_TYPE_TAG_UINT16, 0 }, - { "gint8", GI_TYPE_TAG_INT8, 0 }, - { "guint8", GI_TYPE_TAG_UINT8, 0 }, - { "gint16", GI_TYPE_TAG_INT16, 0 }, - { "guint16", GI_TYPE_TAG_UINT16, 0 }, - { "gint32", GI_TYPE_TAG_INT32, 0 }, - { "guint32", GI_TYPE_TAG_UINT32, 0 }, - { "gint64", GI_TYPE_TAG_INT64, 0 }, - { "guint64", GI_TYPE_TAG_UINT64, 0 }, - { "glong", GI_TYPE_TAG_LONG, 0 }, - { "gulong", GI_TYPE_TAG_ULONG, 0 }, - { "gssize", GI_TYPE_TAG_SSIZE, 0 }, - { "gsize", GI_TYPE_TAG_SIZE, 0 }, - { "gfloat", GI_TYPE_TAG_FLOAT, 0 }, - { "gdouble", GI_TYPE_TAG_DOUBLE, 0 }, - { "gchar*", GI_TYPE_TAG_UTF8, 1 } }; static const BasicTypeInfo * From ff654e2d4e894e5b0b7bbd18d56e6cd58834c60e Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 29 Sep 2008 19:03:44 +0000 Subject: [PATCH 096/692] Rework to use recursive XML svn path=/trunk/; revision=637 --- girparser.c | 262 +++++++++++++++++++++++++++------------------------- 1 file changed, 134 insertions(+), 128 deletions(-) diff --git a/girparser.c b/girparser.c index a64de0edc..88f7c78a2 100644 --- a/girparser.c +++ b/girparser.c @@ -59,7 +59,7 @@ typedef enum STATE_CLASS_CONSTANT, STATE_INTERFACE_CONSTANT, STATE_ALIAS, - STATE_TYPE, + STATE_TYPE } ParseState; typedef struct _ParseContext ParseContext; @@ -79,6 +79,8 @@ struct _ParseContext GIrModule *current_module; GIrNode *current_node; GIrNode *current_typed; + GList *type_stack; + GList *type_parameters; int type_depth; }; @@ -347,25 +349,6 @@ parse_type_internal (const gchar *str, char **next, gboolean in_glib) type->is_pointer = TRUE; str += strlen ("SList"); } - - if (*str == '<') - { - (str)++; - char *rest; - - type->parameter_type1 = parse_type_internal (str, &rest, in_glib); - if (type->parameter_type1 == NULL) - goto error; - str = rest; - - if (str[0] != '>') - goto error; - (str)++; - } - else - { - type->parameter_type1 = parse_type_internal ("any", NULL, in_glib); - } } else if (g_str_has_prefix (str, "GLib.HashTable")) { @@ -375,35 +358,6 @@ parse_type_internal (const gchar *str, char **next, gboolean in_glib) type->is_ghashtable = TRUE; type->is_pointer = TRUE; str += strlen ("HashTable"); - - if (*str == '<') - { - char *rest; - (str)++; - - type->parameter_type1 = parse_type_internal (str, &rest, in_glib); - if (type->parameter_type1 == NULL) - goto error; - str = rest; - - if (str[0] != ',') - goto error; - (str)++; - - type->parameter_type2 = parse_type_internal (str, &rest, in_glib); - if (type->parameter_type2 == NULL) - goto error; - str = rest; - - if ((str)[0] != '>') - goto error; - (str)++; - } - else - { - type->parameter_type1 = parse_type_internal ("any", NULL, in_glib); - type->parameter_type2 = parse_type_internal ("any", NULL, in_glib); - } } else if (g_str_has_prefix (str, "GLib.Error")) { @@ -444,57 +398,6 @@ parse_type_internal (const gchar *str, char **next, gboolean in_glib) type->interface = g_strndup (start, str - start); } - if (g_str_has_prefix (str, "[")) - { - GIrNodeType *array; - int i; - - array = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE); - - array->tag = GI_TYPE_TAG_ARRAY; - array->is_pointer = TRUE; - array->is_array = TRUE; - - array->parameter_type1 = type; - - array->zero_terminated = FALSE; - array->has_length = FALSE; - array->length = 0; - - if (!g_str_has_prefix (str, "[]")) - { - gchar *end, *tmp, **opts; - - end = strchr (str, ']'); - tmp = g_strndup (str + 1, (end - str) - 1); - opts = g_strsplit (tmp, ",", 0); - - for (i = 0; opts[i]; i++) - { - gchar **vals; - - vals = g_strsplit (opts[i], "=", 0); - - if (strcmp (vals[0], "zero-terminated") == 0) - array->zero_terminated = (strcmp (vals[1], "1") == 0); - else if (strcmp (vals[0], "length") == 0) - { - array->has_length = TRUE; - array->length = atoi (vals[1]); - } - - g_strfreev (vals); - } - - g_free (tmp); - g_strfreev (opts); - - str = end; - } - - type = array; - } - if (next) *next = (char*)str; g_assert (type->tag >= 0 && type->tag <= GI_TYPE_TAG_ERROR); @@ -1506,14 +1409,20 @@ start_type (GMarkupParseContext *context, { const gchar *name; const gchar *ctype; - gboolean is_pointer; + gboolean is_array; GIrNodeType *typenode; - if (strcmp (element_name, "type") != 0) + is_array = strcmp (element_name, "array") == 0; + + if (!(is_array || (strcmp (element_name, "type") == 0))) return FALSE; - if (ctx->state == STATE_TYPE) - ctx->type_depth++; + if (ctx->state == STATE_TYPE) + { + ctx->type_depth++; + ctx->type_stack = g_list_prepend (ctx->type_stack, ctx->type_parameters); + ctx->type_parameters = NULL; + } else if (ctx->state == STATE_FUNCTION_PARAMETER || ctx->state == STATE_FUNCTION_RETURN || ctx->state == STATE_STRUCT_FIELD || @@ -1530,12 +1439,10 @@ start_type (GMarkupParseContext *context, { state_switch (ctx, STATE_TYPE); ctx->type_depth = 1; + ctx->type_stack = NULL; + ctx->type_parameters = NULL; } - /* FIXME handle recursive types */ - if (ctx->type_depth > 1) - return TRUE; - if (!ctx->current_typed) { g_set_error (error, @@ -1544,22 +1451,69 @@ start_type (GMarkupParseContext *context, "The element is invalid here"); return FALSE; } - - name = find_attribute ("name", attribute_names, attribute_values); - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); + if (is_array) + { + const char *zero; + const char *len; + int i; - ctype = find_attribute ("c:type", attribute_names, attribute_values); - if (ctype != NULL && strchr (ctype, '*')) - is_pointer = TRUE; + typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE); + + typenode->tag = GI_TYPE_TAG_ARRAY; + typenode->is_pointer = TRUE; + typenode->is_array = TRUE; + + zero = find_attribute ("zero-terminated", attribute_names, attribute_values); + len = find_attribute ("length", attribute_names, attribute_values); + + typenode->zero_terminated = !(zero && strcmp (zero, "1") != 0); + typenode->has_length = len != NULL; + typenode->length = typenode->has_length ? atoi (len) : -1; + } else - is_pointer = FALSE; + { + gboolean is_pointer; + name = find_attribute ("name", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + + ctype = find_attribute ("c:type", attribute_names, attribute_values); + if (ctype != NULL && strchr (ctype, '*')) + is_pointer = TRUE; + else + is_pointer = FALSE; + + typenode = parse_type (ctx, name); + + if (is_pointer) + typenode->is_pointer = is_pointer; + } + + ctx->type_parameters = g_list_append (ctx->type_parameters, typenode); + + return TRUE; +} + +static void +end_type_top (ParseContext *ctx) +{ + GIrNodeType *typenode = (GIrNodeType*)ctx->type_parameters->data; + + /* Default to pointer for unspecified containers */ + if (typenode->tag == GI_TYPE_TAG_ARRAY || + typenode->tag == GI_TYPE_TAG_GLIST || + typenode->tag == GI_TYPE_TAG_GSLIST) + { + typenode->parameter_type1 = parse_type (ctx, "any"); + } + else if (typenode->tag == GI_TYPE_TAG_GHASH) + { + typenode->parameter_type1 = parse_type (ctx, "any"); + typenode->parameter_type2 = parse_type (ctx, "any"); + } - typenode = parse_type (ctx, name); - if (is_pointer) - typenode->is_pointer = is_pointer; - switch (ctx->current_typed->type) { case G_IR_NODE_PARAM: @@ -1590,10 +1544,61 @@ start_type (GMarkupParseContext *context, g_printerr("current node is %d\n", ctx->current_node->type); g_assert_not_reached (); } - - + g_list_free (ctx->type_parameters); + + ctx->type_depth = 0; + ctx->type_parameters = NULL; ctx->current_typed = NULL; - return TRUE; +} + +static void +end_type_recurse (ParseContext *ctx) +{ + GList *types; + GIrNodeType *parent; + + parent = (GIrNodeType *) ((GList*)ctx->type_stack->data)->data; + + if (parent->tag == GI_TYPE_TAG_ARRAY || + parent->tag == GI_TYPE_TAG_GLIST || + parent->tag == GI_TYPE_TAG_GSLIST) + { + if (ctx->type_parameters == NULL) + parent->parameter_type1 = parse_type (ctx, "pointer"); + else + parent->parameter_type1 = (GIrNodeType*)ctx->type_parameters->data; + } + else if (parent->tag == GI_TYPE_TAG_GHASH) + { + if (ctx->type_parameters == NULL) + { + parent->parameter_type1 = parse_type (ctx, "pointer"); + parent->parameter_type2 = parse_type (ctx, "pointer"); + } + else + { + parent->parameter_type1 = (GIrNodeType*) ctx->type_parameters->data; + parent->parameter_type2 = (GIrNodeType*) ctx->type_parameters->next->data; + } + } + g_list_free (ctx->type_parameters); + ctx->type_parameters = (GList *)ctx->type_stack->data; + ctx->type_stack = g_list_delete_link (ctx->type_stack, ctx->type_stack); +} + +static void +end_type (ParseContext *ctx) +{ + if (ctx->type_depth == 1) + { + end_type_top (ctx); + state_switch (ctx, ctx->prev_state); + } + else + { + end_type_recurse (ctx); + ctx->type_depth--; + } } static gboolean @@ -2078,6 +2083,10 @@ start_element_handler (GMarkupParseContext *context, state_switch (ctx, STATE_ALIAS); goto out; } + if (start_type (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; break; case 'b': if (start_enum (context, element_name, @@ -2631,12 +2640,9 @@ end_element_handler (GMarkupParseContext *context, } break; case STATE_TYPE: - if (strcmp ("type", element_name) == 0) + if ((strcmp ("type", element_name) == 0) || (strcmp ("array", element_name) == 0)) { - if (ctx->type_depth == 1) - state_switch (ctx, ctx->prev_state); - else - ctx->type_depth -= 1; + end_type (ctx); break; } default: From 9893df46cb5de4427334777c98bea61f2019852f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 29 Sep 2008 19:03:46 +0000 Subject: [PATCH 097/692] Ensure we always have types for container nodes svn path=/trunk/; revision=638 --- girparser.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/girparser.c b/girparser.c index 88f7c78a2..fbdea5878 100644 --- a/girparser.c +++ b/girparser.c @@ -1506,12 +1506,16 @@ end_type_top (ParseContext *ctx) typenode->tag == GI_TYPE_TAG_GLIST || typenode->tag == GI_TYPE_TAG_GSLIST) { - typenode->parameter_type1 = parse_type (ctx, "any"); + if (typenode->parameter_type1 == NULL) + typenode->parameter_type1 = parse_type (ctx, "any"); } else if (typenode->tag == GI_TYPE_TAG_GHASH) { - typenode->parameter_type1 = parse_type (ctx, "any"); - typenode->parameter_type2 = parse_type (ctx, "any"); + if (typenode->parameter_type1 == NULL) + { + typenode->parameter_type1 = parse_type (ctx, "any"); + typenode->parameter_type2 = parse_type (ctx, "any"); + } } switch (ctx->current_typed->type) From b26d8d2dcedd4d144ffe2ba65ceb3aed8d2056ea Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 2 Oct 2008 13:25:46 +0000 Subject: [PATCH 098/692] Bug 554632: Create type tag for GType svn path=/trunk/; revision=641 --- girepository.c | 2 ++ girepository.h | 23 +++++++++++++++-------- girparser.c | 22 ++++++++++++++++------ 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/girepository.c b/girepository.c index 251702761..3bde15bec 100644 --- a/girepository.c +++ b/girepository.c @@ -750,6 +750,8 @@ g_type_tag_to_string (GITypeTag type) return "double"; case GI_TYPE_TAG_TIME_T: return "time_t"; + case GI_TYPE_TAG_GTYPE: + return "GType"; case GI_TYPE_TAG_UTF8: return "utf8"; case GI_TYPE_TAG_FILENAME: diff --git a/girepository.h b/girepository.h index d3f68185c..54baab4ac 100644 --- a/girepository.h +++ b/girepository.h @@ -267,6 +267,7 @@ GITypeInfo * g_arg_info_get_type (GIArgInfo *info); /* GITypeInfo */ typedef enum { + /* Basic types */ GI_TYPE_TAG_VOID = 0, GI_TYPE_TAG_BOOLEAN = 1, GI_TYPE_TAG_INT8 = 2, @@ -286,16 +287,22 @@ typedef enum { GI_TYPE_TAG_FLOAT = 16, GI_TYPE_TAG_DOUBLE = 17, GI_TYPE_TAG_TIME_T = 18, - GI_TYPE_TAG_UTF8 = 19, - GI_TYPE_TAG_FILENAME = 20, - GI_TYPE_TAG_ARRAY = 21, - GI_TYPE_TAG_INTERFACE = 22, - GI_TYPE_TAG_GLIST = 23, - GI_TYPE_TAG_GSLIST = 24, - GI_TYPE_TAG_GHASH = 25, - GI_TYPE_TAG_ERROR = 26 + GI_TYPE_TAG_GTYPE = 19, + GI_TYPE_TAG_UTF8 = 20, + GI_TYPE_TAG_FILENAME = 21, + /* Non-basic types */ + GI_TYPE_TAG_ARRAY = 22, + GI_TYPE_TAG_INTERFACE = 23, + GI_TYPE_TAG_GLIST = 24, + GI_TYPE_TAG_GSLIST = 25, + GI_TYPE_TAG_GHASH = 26, + GI_TYPE_TAG_ERROR = 27 + /* Note - there is only room currently for 32 tags. + * See docs/typelib-format.txt SimpleTypeBlob definition */ } GITypeTag; +#define G_TYPE_TAG_IS_BASIC(tag) (tag < GI_TYPE_TAG_ARRAY) + const gchar* g_type_tag_to_string (GITypeTag type); gboolean g_type_info_is_pointer (GITypeInfo *info); diff --git a/girparser.c b/girparser.c index fbdea5878..52f2294c0 100644 --- a/girparser.c +++ b/girparser.c @@ -222,7 +222,8 @@ state_switch (ParseContext *ctx, ParseState newstate) ctx->state = newstate; } -static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib); +static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib, + gboolean in_gobject); typedef struct { const gchar *str; @@ -255,6 +256,7 @@ static BasicTypeInfo basic_types[] = { { "float", GI_TYPE_TAG_FLOAT, 0 }, { "double", GI_TYPE_TAG_DOUBLE, 0 }, { "time_t", GI_TYPE_TAG_TIME_T, 0 }, + { "GType", GI_TYPE_TAG_GTYPE, 0 }, { "utf8", GI_TYPE_TAG_UTF8, 1 }, { "filename", GI_TYPE_TAG_FILENAME,1 }, }; @@ -277,7 +279,8 @@ parse_basic (const char *str) } static GIrNodeType * -parse_type_internal (const gchar *str, char **next, gboolean in_glib) +parse_type_internal (const gchar *str, char **next, gboolean in_glib, + gboolean in_gobject) { const BasicTypeInfo *basic; GIrNodeType *type; @@ -287,6 +290,13 @@ parse_type_internal (const gchar *str, char **next, gboolean in_glib) type->unparsed = g_strdup (str); + /* See comment below on GLib.List handling */ + if (in_gobject && strcmp (str, "Type") == 0) + { + temporary_type = g_strdup ("GLib.Type"); + str = temporary_type; + } + basic = parse_basic (str); if (basic != NULL) { @@ -298,11 +308,10 @@ parse_type_internal (const gchar *str, char **next, gboolean in_glib) } else if (in_glib) { - /* If we're inside GLib, handle "List" by prefixing it with + /* If we're inside GLib, handle "List" etc. by prefixing with * "GLib." so the parsing code below doesn't have to get more * special. */ - if (g_str_has_prefix (str, "List<") || strcmp (str, "List") == 0) { @@ -437,17 +446,18 @@ parse_type (ParseContext *ctx, const gchar *type) gchar *str; GIrNodeType *node; const BasicTypeInfo *basic; - gboolean in_glib; + gboolean in_glib, in_gobject; gboolean matched_special = FALSE; in_glib = strcmp (ctx->namespace, "GLib") == 0; + in_gobject = strcmp (ctx->namespace, "GObject") == 0; /* Do not search aliases for basic types */ basic = parse_basic (type); if (basic == NULL) type = resolve_aliases (ctx, type); - node = parse_type_internal (type, NULL, in_glib); + node = parse_type_internal (type, NULL, in_glib, in_gobject); if (node) g_debug ("Parsed type: %s => %d", type, node->tag); else From a99fdaf755c8499ecf0e6a1d46e72e71a2a3cf59 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 2 Oct 2008 14:07:38 +0000 Subject: [PATCH 099/692] Merge branch 'bug552393-varargs' svn path=/trunk/; revision=643 --- girnode.h | 2 + girparser.c | 182 ++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 149 insertions(+), 35 deletions(-) diff --git a/girnode.h b/girnode.h index 67027aecc..eba8c6b96 100644 --- a/girnode.h +++ b/girnode.h @@ -85,6 +85,7 @@ struct _GIrNodeFunction GIrNode node; gboolean deprecated; + gboolean is_varargs; /* Not in typelib yet */ gboolean is_method; gboolean is_setter; @@ -183,6 +184,7 @@ struct _GIrNodeVFunc { GIrNode node; + gboolean is_varargs; /* Not in typelib yet */ gboolean must_chain_up; gboolean must_be_implemented; gboolean must_not_be_implemented; diff --git a/girparser.c b/girparser.c index 52f2294c0..1644f5d6c 100644 --- a/girparser.c +++ b/girparser.c @@ -79,6 +79,7 @@ struct _ParseContext GIrModule *current_module; GIrNode *current_node; GIrNode *current_typed; + gboolean is_varargs; GList *type_stack; GList *type_parameters; int type_depth; @@ -1420,11 +1421,13 @@ start_type (GMarkupParseContext *context, const gchar *name; const gchar *ctype; gboolean is_array; + gboolean is_varargs; GIrNodeType *typenode; is_array = strcmp (element_name, "array") == 0; + is_varargs = strcmp (element_name, "varargs") == 0; - if (!(is_array || (strcmp (element_name, "type") == 0))) + if (!(is_array || is_varargs || (strcmp (element_name, "type") == 0))) return FALSE; if (ctx->state == STATE_TYPE) @@ -1449,6 +1452,25 @@ start_type (GMarkupParseContext *context, { state_switch (ctx, STATE_TYPE); ctx->type_depth = 1; + if (is_varargs) + { + switch (ctx->current_node->type) + { + case G_IR_NODE_FUNCTION: + case G_IR_NODE_CALLBACK: + { + GIrNodeFunction *func = (GIrNodeFunction *)ctx->current_node; + func->is_varargs = TRUE; + } + break; + case G_IR_NODE_VFUNC: + { + GIrNodeVFunc *vfunc = (GIrNodeVFunc *)ctx->current_node; + vfunc->is_varargs = TRUE; + } + break; + } + } ctx->type_stack = NULL; ctx->type_parameters = NULL; } @@ -1462,6 +1484,9 @@ start_type (GMarkupParseContext *context, return FALSE; } + if (is_varargs) + return TRUE; + if (is_array) { const char *zero; @@ -1509,7 +1534,12 @@ start_type (GMarkupParseContext *context, static void end_type_top (ParseContext *ctx) { - GIrNodeType *typenode = (GIrNodeType*)ctx->type_parameters->data; + GIrNodeType *typenode; + + if (!ctx->type_parameters) + goto out; + + typenode = (GIrNodeType*)ctx->type_parameters->data; /* Default to pointer for unspecified containers */ if (typenode->tag == GI_TYPE_TAG_ARRAY || @@ -1559,7 +1589,8 @@ end_type_top (ParseContext *ctx) g_assert_not_reached (); } g_list_free (ctx->type_parameters); - + + out: ctx->type_depth = 0; ctx->type_parameters = NULL; ctx->current_typed = NULL; @@ -2322,7 +2353,11 @@ start_element_handler (GMarkupParseContext *context, if (start_vfunc (context, element_name, attribute_names, attribute_values, ctx, error)) - goto out; + goto out; + if (start_type (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; break; } @@ -2464,36 +2499,43 @@ end_element_handler (GMarkupParseContext *context, break; case STATE_FUNCTION: - if (ctx->current_node == g_list_last (ctx->current_module->entries)->data) - { - ctx->current_node = NULL; - state_switch (ctx, STATE_NAMESPACE); - } - else - { - ctx->current_node = g_list_last (ctx->current_module->entries)->data; - if (ctx->current_node->type == G_IR_NODE_INTERFACE) - state_switch (ctx, STATE_INTERFACE); - else if (ctx->current_node->type == G_IR_NODE_OBJECT) - state_switch (ctx, STATE_CLASS); - else if (ctx->current_node->type == G_IR_NODE_BOXED) - state_switch (ctx, STATE_BOXED); - else if (ctx->current_node->type == G_IR_NODE_STRUCT) - state_switch (ctx, STATE_STRUCT); - else if (ctx->current_node->type == G_IR_NODE_UNION) - state_switch (ctx, STATE_UNION); - else - { - int line_number, char_number; - g_markup_parse_context_get_position (context, &line_number, &char_number); - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Unexpected end tag '%s' on line %d char %d", - element_name, - line_number, char_number); - } - } + { + gboolean current_is_toplevel; + GList *last = g_list_last (ctx->current_module->entries); + + current_is_toplevel = ctx->current_node == last->data; + + if (current_is_toplevel) + { + ctx->current_node = NULL; + state_switch (ctx, STATE_NAMESPACE); + } + else + { + ctx->current_node = g_list_last (ctx->current_module->entries)->data; + if (ctx->current_node->type == G_IR_NODE_INTERFACE) + state_switch (ctx, STATE_INTERFACE); + else if (ctx->current_node->type == G_IR_NODE_OBJECT) + state_switch (ctx, STATE_CLASS); + else if (ctx->current_node->type == G_IR_NODE_BOXED) + state_switch (ctx, STATE_BOXED); + else if (ctx->current_node->type == G_IR_NODE_STRUCT) + state_switch (ctx, STATE_STRUCT); + else if (ctx->current_node->type == G_IR_NODE_UNION) + state_switch (ctx, STATE_UNION); + else + { + int line_number, char_number; + g_markup_parse_context_get_position (context, &line_number, &char_number); + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Unexpected end tag '%s' on line %d char %d", + element_name, + line_number, char_number); + } + } + } break; case STATE_CLASS_FIELD: @@ -2654,7 +2696,8 @@ end_element_handler (GMarkupParseContext *context, } break; case STATE_TYPE: - if ((strcmp ("type", element_name) == 0) || (strcmp ("array", element_name) == 0)) + if ((strcmp ("type", element_name) == 0) || (strcmp ("array", element_name) == 0) || + (strcmp ("varargs", element_name) == 0)) { end_type (ctx); break; @@ -2700,6 +2743,69 @@ static GMarkupParser parser = cleanup }; +static GList * +post_filter_varargs_functions (GList *list) +{ + GList *iter; + + iter = list; + while (iter) + { + GList *link = iter; + GIrNode *node = iter->data; + + iter = iter->next; + + if (node->type == G_IR_NODE_FUNCTION) + { + if (((GIrNodeFunction*)node)->is_varargs) + { + g_printerr ("deleting varargs function\n"); + list = g_list_delete_link (list, link); + } + } + } + return list; +} + +static void +post_filter (GIrModule *module) +{ + GList *iter; + + module->entries = post_filter_varargs_functions (module->entries); + iter = module->entries; + while (iter) + { + GList *link = iter; + GIrNode *node = iter->data; + + iter = iter->next; + + if (node->type == G_IR_NODE_OBJECT || + node->type == G_IR_NODE_INTERFACE) + { + GIrNodeInterface *iface = (GIrNodeInterface*)node; + iface->members = post_filter_varargs_functions (iface->members); + } + else if (node->type == G_IR_NODE_BOXED) + { + GIrNodeBoxed *boxed = (GIrNodeBoxed*)node; + boxed->members = post_filter_varargs_functions (boxed->members); + } + else if (node->type == G_IR_NODE_STRUCT) + { + GIrNodeStruct *iface = (GIrNodeStruct*)node; + iface->members = post_filter_varargs_functions (iface->members); + } + else if (node->type == G_IR_NODE_UNION) + { + GIrNodeUnion *iface = (GIrNodeUnion*)node; + iface->members = post_filter_varargs_functions (iface->members); + } + } +} + GList * g_ir_parse_string (const gchar *namespace, const gchar *const *includes, @@ -2753,6 +2859,7 @@ g_ir_parse_file (const gchar *filename, gchar *buffer; gsize length; GList *modules; + GList *iter; const char *slash; char *namespace; @@ -2779,6 +2886,11 @@ g_ir_parse_file (const gchar *filename, modules = g_ir_parse_string (namespace, includes, buffer, length, error); + for (iter = modules; iter; iter = iter->next) + { + post_filter ((GIrModule*)iter->data); + } + g_free (namespace); g_free (buffer); From d982b65391364a5966318478c131444f3b5503cb Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 2 Oct 2008 14:07:42 +0000 Subject: [PATCH 100/692] Remove debug print svn path=/trunk/; revision=644 --- girparser.c | 1 - 1 file changed, 1 deletion(-) diff --git a/girparser.c b/girparser.c index 1644f5d6c..d4cc34a4d 100644 --- a/girparser.c +++ b/girparser.c @@ -2760,7 +2760,6 @@ post_filter_varargs_functions (GList *list) { if (((GIrNodeFunction*)node)->is_varargs) { - g_printerr ("deleting varargs function\n"); list = g_list_delete_link (list, link); } } From ec679636ef80360e33b74a122c9177df5fc871f0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 2 Oct 2008 21:24:20 +0000 Subject: [PATCH 101/692] Merge branch 'bug552961-methods/wip' svn path=/trunk/; revision=647 --- ginvoke.c | 62 ++++++++++++++++++++++++++++++++++++++---------------- gtypelib.c | 47 ----------------------------------------- 2 files changed, 44 insertions(+), 65 deletions(-) diff --git a/ginvoke.c b/ginvoke.c index bbf152bfa..c2eba44a3 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -158,7 +158,8 @@ g_function_info_invoke (GIFunctionInfo *info, gpointer func; GITypeInfo *tinfo; GIArgInfo *ainfo; - gint n_args, in_pos, out_pos, i; + gboolean is_method; + gint n_args, n_invoke_args, in_pos, out_pos, i; gpointer *args; gboolean success = FALSE; @@ -199,24 +200,49 @@ g_function_info_invoke (GIFunctionInfo *info, g_module_close (entire_app); } + is_method = (g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0 + && (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR) == 0; + tinfo = g_callable_info_get_return_type ((GICallableInfo *)info); rtype = get_ffi_type (tinfo); g_base_info_unref ((GIBaseInfo *)tinfo); - n_args = g_callable_info_get_n_args ((GICallableInfo *)info); - atypes = g_new (ffi_type*, n_args); - args = g_new (gpointer, n_args); - in_pos = 0; out_pos = 0; + + n_args = g_callable_info_get_n_args ((GICallableInfo *)info); + if (is_method) + { + if (n_in_args == 0) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too few \"in\" arguments (handling this)"); + goto out; + } + n_invoke_args = n_args+1; + in_pos++; + } + else + n_invoke_args = n_args; + atypes = g_new (ffi_type*, n_invoke_args); + args = g_new (gpointer, n_invoke_args); + + if (is_method) + { + atypes[0] = &ffi_type_pointer; + args[0] = (gpointer) &in_args[0]; + } for (i = 0; i < n_args; i++) { + int offset = (is_method ? 1 : 0); ainfo = g_callable_info_get_arg ((GICallableInfo *)info, i); switch (g_arg_info_get_direction (ainfo)) { case GI_DIRECTION_IN: tinfo = g_arg_info_get_type (ainfo); - atypes[i] = get_ffi_type (tinfo); + atypes[i+offset] = get_ffi_type (tinfo); g_base_info_unref ((GIBaseInfo *)tinfo); if (in_pos >= n_in_args) @@ -224,38 +250,38 @@ g_function_info_invoke (GIFunctionInfo *info, g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too few \"in\" arguments"); + "Too few \"in\" arguments (handling in)"); goto out; } - args[i] = (gpointer)&in_args[in_pos]; + args[i+offset] = (gpointer)&in_args[in_pos]; in_pos++; break; case GI_DIRECTION_OUT: - atypes[i] = &ffi_type_pointer; + atypes[i+offset] = &ffi_type_pointer; if (out_pos >= n_out_args) { g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too few \"out\" arguments"); + "Too few \"out\" arguments (handling out)"); goto out; } - args[i] = (gpointer)&out_args[out_pos]; + args[i+offset] = (gpointer)&out_args[out_pos+offset]; out_pos++; break; case GI_DIRECTION_INOUT: - atypes[i] = &ffi_type_pointer; + atypes[i+offset] = &ffi_type_pointer; if (in_pos >= n_in_args) { g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too few \"in\" arguments"); + "Too few \"in\" arguments (handling inout)"); goto out; } @@ -264,11 +290,11 @@ g_function_info_invoke (GIFunctionInfo *info, g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too few \"in\" arguments"); + "Too few \"out\" arguments (handling inout)"); goto out; } - args[i] = (gpointer)&in_args[in_pos]; + args[i+offset] = (gpointer)&in_args[in_pos]; in_pos++; out_pos++; break; @@ -282,7 +308,7 @@ g_function_info_invoke (GIFunctionInfo *info, g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too many \"in\" arguments"); + "Too many \"in\" arguments (at end)"); goto out; } if (out_pos < n_out_args) @@ -290,11 +316,11 @@ g_function_info_invoke (GIFunctionInfo *info, g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too many \"out\" arguments"); + "Too many \"out\" arguments (at end)"); goto out; } - if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, rtype, atypes) != FFI_OK) + if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_invoke_args, rtype, atypes) != FFI_OK) goto out; ffi_call (&cif, func, return_value, args); diff --git a/gtypelib.c b/gtypelib.c index 3b7107e3a..983c6954d 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -821,53 +821,6 @@ validate_function_blob (ValidateContext *ctx, return FALSE; } } - else if (is_method) - { - guint32 this_offset; - guint32 this_type_offset; - ArgBlob *this; - SimpleTypeBlob *thistype; - InterfaceTypeBlob *thistype_iface; - - if (sigblob->n_arguments == 0) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID, - "Invalid 0-argument method"); - } - - this_offset = blob->signature + sizeof (SignatureBlob); - this = (ArgBlob*) &typelib->data[this_offset]; - this_type_offset = this_offset + G_STRUCT_OFFSET (ArgBlob, arg_type); - thistype = (SimpleTypeBlob *)&typelib->data[this_type_offset]; - - if (thistype->reserved == 0 && - thistype->reserved2 == 0) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Non-reference type tag %d found for \"this\" argument", - thistype->tag); - return FALSE; - } - - thistype_iface = (InterfaceTypeBlob*)&typelib->data[thistype->offset]; - - switch (thistype_iface->tag) - { - case GI_TYPE_TAG_INTERFACE: - break; - default: - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid type tag %d found for \"this\" argument", - thistype_iface->tag); - return FALSE; - } - } pop_context (ctx); From aceef77051a27d10c7432dae5ef534ba3d03eee2 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 2 Oct 2008 21:24:24 +0000 Subject: [PATCH 102/692] Use g_alloca, suggested by Havoc Pennington svn path=/trunk/; revision=649 --- ginvoke.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/ginvoke.c b/ginvoke.c index c2eba44a3..c9180d9f5 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -226,8 +226,8 @@ g_function_info_invoke (GIFunctionInfo *info, } else n_invoke_args = n_args; - atypes = g_new (ffi_type*, n_invoke_args); - args = g_new (gpointer, n_invoke_args); + atypes = g_alloca (sizeof (ffi_type*) * n_invoke_args); + args = g_alloca (sizeof (gpointer) * n_invoke_args); if (is_method) { @@ -326,10 +326,6 @@ g_function_info_invoke (GIFunctionInfo *info, ffi_call (&cif, func, return_value, args); success = TRUE; - out: - g_free (atypes); - g_free (args); - return success; } From ea99326529258d168f685d9909d10da4a047a5d0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 3 Oct 2008 19:30:12 +0000 Subject: [PATCH 103/692] Merge branch 'bug551744-boxed-ctors' svn path=/trunk/; revision=654 --- gtypelib.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gtypelib.c b/gtypelib.c index 983c6954d..9a2e73c56 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -738,6 +738,8 @@ validate_function_blob (ValidateContext *ctx, switch (container_type) { case BLOB_TYPE_BOXED: + case BLOB_TYPE_STRUCT: + case BLOB_TYPE_UNION: case BLOB_TYPE_OBJECT: case BLOB_TYPE_INTERFACE: is_method = !(blob->constructor || blob->setter || blob->getter || blob->wraps_vfunc); @@ -751,6 +753,8 @@ validate_function_blob (ValidateContext *ctx, switch (container_type) { case BLOB_TYPE_BOXED: + case BLOB_TYPE_STRUCT: + case BLOB_TYPE_UNION: case BLOB_TYPE_OBJECT: case BLOB_TYPE_INTERFACE: break; From 728beb04246823264fa351eca417ffe94a52ac7e Mon Sep 17 00:00:00 2001 From: Lucas Rocha Date: Tue, 7 Oct 2008 21:25:01 +0000 Subject: [PATCH 104/692] Bug 555294: Add support for multiple shared libraries per typelib. 2008-10-06 Lucas Rocha Bug 555294: Add support for multiple shared libraries per typelib. * girepository/ginvoke.c (g_function_info_invoke), girepository/ginfo.c(g_registered_type_info_get_g_type): use g_typelib_symbol instead of g_module_symbol. * girepository/girepository.h: remove g_typelib_set_module and add g_typelib_symbol. * girepository/gtypelib.[ch] (find_some_symbol, _g_typelib_init, g_typelib_new_from_memory, g_typelib_new_from_const_memory, g_typelib_free, g_typelib_symbol): chnage GTypeLib to hold a list of modules instead of just one. The symbol lookup is now abstracted behind g_typelib_symbol which tries to find the passed symbol name in one of its modules. * giscanner/girwriter.py, tools/g-ir-scanner: change scanner to read and write shared_library attribute as a comma-separated list of libs. svn path=/trunk/; revision=660 --- ginfo.c | 6 +- ginvoke.c | 40 ++------- girepository.c | 3 - girepository.h | 5 +- gtypelib.c | 217 ++++++++++++++++++++++++------------------------- gtypelib.h | 2 +- 6 files changed, 119 insertions(+), 154 deletions(-) diff --git a/ginfo.c b/ginfo.c index bc3847226..75ced84e8 100644 --- a/ginfo.c +++ b/ginfo.c @@ -992,9 +992,9 @@ g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info) return G_TYPE_NONE; get_type_func = NULL; - if (!g_module_symbol (((GIBaseInfo*)info)->typelib->module, - type_init, - (void**) &get_type_func)) + if (!g_typelib_symbol (((GIBaseInfo*)info)->typelib, + type_init, + (void**) &get_type_func)) return G_TYPE_NONE; return (* get_type_func) (); diff --git a/ginvoke.c b/ginvoke.c index c9180d9f5..d5182dbf7 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -162,42 +162,18 @@ g_function_info_invoke (GIFunctionInfo *info, gint n_args, n_invoke_args, in_pos, out_pos, i; gpointer *args; gboolean success = FALSE; - + symbol = g_function_info_get_symbol (info); - if (!g_module_symbol (g_base_info_get_typelib((GIBaseInfo *) info)->module, - symbol, &func)) + if (!g_typelib_symbol (g_base_info_get_typelib((GIBaseInfo *) info), + symbol, &func)) { - GModule *entire_app; + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_SYMBOL_NOT_FOUND, + "Could not locate %s: %s", symbol, g_module_error ()); - /* - * We want to be able to add symbols to an app or an auxiliary - * library to fill in gaps in an introspected library. However, - * normally we would only look for symbols in the main library - * (typelib->module). - * - * A more elaborate solution is probably possible, but as a - * simple approach for now, if we fail to find a symbol we look - * for it in the global module. - * - * This would not be very efficient if it happened often, since - * we always do the failed lookup above first, but very few - * symbols should be outside of typelib->module so it doesn't - * matter. - */ - entire_app = g_module_open (NULL, 0); - if (!g_module_symbol (entire_app, symbol, &func)) - { - g_set_error (error, - G_INVOKE_ERROR, - G_INVOKE_ERROR_SYMBOL_NOT_FOUND, - "Could not locate %s: %s", symbol, g_module_error ()); - - g_module_close (entire_app); - - return FALSE; - } - g_module_close (entire_app); + return FALSE; } is_method = (g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0 diff --git a/girepository.c b/girepository.c index 3bde15bec..15e043554 100644 --- a/girepository.c +++ b/girepository.c @@ -252,9 +252,6 @@ register_internal (GIRepository *repository, g_hash_table_insert (repository->priv->typelibs, key, (void *)typelib); } - if (typelib->module == NULL) - typelib->module = g_module_open (NULL, 0); - return namespace; } diff --git a/girepository.h b/girepository.h index 54baab4ac..28848d5e9 100644 --- a/girepository.h +++ b/girepository.h @@ -112,8 +112,9 @@ GTypelib * g_typelib_new_from_const_memory (const guchar *memory, gsize len); GTypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile); void g_typelib_free (GTypelib *typelib); -void g_typelib_set_module (GTypelib *typelib, - GModule *module); +gboolean g_typelib_symbol (GTypelib *typelib, + const gchar *symbol_name, + gpointer *symbol); const gchar * g_typelib_get_namespace (GTypelib *typelib); typedef enum diff --git a/gtypelib.c b/gtypelib.c index 9a2e73c56..34a65e880 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1886,44 +1886,6 @@ g_typelib_error_quark (void) return quark; } -static const char* -find_some_symbol (GTypelib *typelib) -{ - Header *header = (Header *) typelib->data; - gint i; - - for (i = 0; i < header->n_entries; i++) - { - DirEntry *entry; - - entry = g_typelib_get_dir_entry (typelib, i + 1); - - switch (entry->blob_type) - { - case BLOB_TYPE_FUNCTION: - { - FunctionBlob *blob = (FunctionBlob *) &typelib->data[entry->offset]; - - if (blob->symbol) - return g_typelib_get_string (typelib, blob->symbol); - } - break; - case BLOB_TYPE_OBJECT: - { - RegisteredTypeBlob *blob = (RegisteredTypeBlob *) &typelib->data[entry->offset]; - - if (blob->gtype_init) - return g_typelib_get_string (typelib, blob->gtype_init); - } - break; - default: - break; - } - } - - return NULL; -} - static inline void _g_typelib_init (GTypelib *typelib) { @@ -1932,76 +1894,75 @@ _g_typelib_init (GTypelib *typelib) header = (Header *) typelib->data; if (header->shared_library) { - const gchar *shlib; + const gchar *shlib_str; + GModule *app_module = NULL; - shlib = g_typelib_get_string (typelib, header->shared_library); + shlib_str = g_typelib_get_string (typelib, header->shared_library); /* note that NULL shlib means to open the main app, which is allowed */ - /* If we do have a shared lib, first be sure the main app isn't already linked to it */ - if (shlib != NULL) + if (shlib_str != NULL) { - const char *symbol_in_module; - - symbol_in_module = find_some_symbol (typelib); - if (symbol_in_module != NULL) + gchar **shlibs; + gint i; + + /* shared-library is a comma-separated list of libraries */ + shlibs = g_strsplit (shlib_str, ",", 0); + + /* We load all passed libs unconditionally as if the same library is loaded + * again with dlopen(), the same file handle will be returned. See bug: + * http://bugzilla.gnome.org/show_bug.cgi?id=555294 + */ + for (i = 0; shlibs[i]; i++) { - typelib->module = g_module_open (NULL, G_MODULE_BIND_LAZY); - if (typelib->module == NULL) + GModule *module; + + /* Glade's autoconnect feature and OpenGL's extension mechanism + * as used by Clutter rely on dlopen(NULL) to work as a means of + * accessing the app's symbols. This keeps us from using + * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well; + * in general libraries are not expecting multiple copies of + * themselves and are not expecting to be unloaded. So we just + * load modules globally for now. + */ + + module = g_module_open (shlibs[i], G_MODULE_BIND_LAZY); + + if (module == NULL) + { + GString *shlib_full = g_string_new (shlibs[i]); + + /* Prefix with "lib", try both .la and .so */ + if (!g_str_has_prefix (shlib_full->str, "lib")) + g_string_prepend (shlib_full, "lib"); + g_string_append (shlib_full, ".la"); + module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); + if (module == NULL) + g_string_overwrite (shlib_full, strlen (shlib_full->str)-2, SHLIB_SUFFIX); + module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); + + g_string_free (shlib_full, TRUE); + } + + if (module == NULL) { - g_warning ("Could not open main app as GModule: %s", - g_module_error ()); + g_warning ("Failed to load shared library '%s' referenced by the typelib: %s", + shlibs[i], g_module_error ()); } else { - void *sym; - if (!g_module_symbol (typelib->module, symbol_in_module, &sym)) - { - /* we will try opening the shlib, symbol is not in app already */ - g_module_close (typelib->module); - typelib->module = NULL; - } + typelib->modules = g_list_append (typelib->modules, module); } - } - else - { - g_warning ("Could not find any symbols in typelib"); - } + } + + g_strfreev (shlibs); } - - if (typelib->module == NULL && shlib != NULL) - { - GString *shlib_full; - /* Glade's autoconnect feature and OpenGL's extension mechanism - * as used by Clutter rely on dlopen(NULL) to work as a means of - * accessing the app's symbols. This keeps us from using - * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well; - * in general libraries are not expecting multiple copies of - * themselves and are not expecting to be unloaded. So we just - * load modules globally for now. - */ - - typelib->module = g_module_open (shlib, G_MODULE_BIND_LAZY); - - if (typelib->module == NULL) - { - shlib_full = g_string_new (shlib); - - /* Prefix with "lib", try both .la and .so */ - if (!g_str_has_prefix (shlib_full->str, "lib")) - g_string_prepend (shlib_full, "lib"); - g_string_append (shlib_full, ".la"); - typelib->module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); - if (typelib->module == NULL) - g_string_overwrite (shlib_full, strlen (shlib_full->str)-2, SHLIB_SUFFIX); - typelib->module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); - - g_string_free (shlib_full, TRUE); - } - if (typelib->module == NULL) - g_warning ("Failed to load shared library '%s' referenced by the typelib: %s", - shlib, g_module_error ()); - } + /* we should make sure the app_module in the end of list so that + * it's last symbol source when loading any symbols from modules. + * See comments in g_typelib_symbol */ + app_module = g_module_open (NULL, G_MODULE_BIND_LAZY); + if (app_module) + typelib->modules = g_list_append (typelib->modules, app_module); } } @@ -2025,6 +1986,7 @@ g_typelib_new_from_memory (guchar *memory, gsize len) meta->data = memory; meta->len = len; meta->owns_memory = TRUE; + meta->modules = NULL; _g_typelib_init (meta); return meta; } @@ -2047,6 +2009,7 @@ g_typelib_new_from_const_memory (const guchar *memory, gsize len) meta->data = (guchar *) memory; meta->len = len; meta->owns_memory = FALSE; + meta->modules = NULL; _g_typelib_init (meta); return meta; } @@ -2087,28 +2050,56 @@ g_typelib_free (GTypelib *typelib) else if (typelib->owns_memory) g_free (typelib->data); - if (typelib->module) - g_module_close (typelib->module); + if (typelib->modules) + { + g_list_foreach (typelib->modules, (GFunc) g_module_close, NULL); + g_list_free (typelib->modules); + } g_free (typelib); } -/** - * g_typelib_set_module: - * @typelib: a #GTypelib instance - * @module: a #GModule; takes ownership of this module - * - * Sets the target module for all symbols referenced by the typelib. - **/ -void -g_typelib_set_module (GTypelib *typelib, GModule *module) -{ - if (typelib->module) - g_module_close (typelib->module); - typelib->module = module; -} - const gchar * g_typelib_get_namespace(GTypelib *typelib) { return g_typelib_get_string (typelib, ((Header *) typelib->data)->namespace); } + +/** + * g_typelib_symbol: + * @symbol_name: name of symbol to be loaded + * @symbol: returns a pointer to the symbol value + * + * Loads a symbol from #GTypelib. + * + * Return value: #TRUE on success + **/ +gboolean +g_typelib_symbol(GTypelib *typelib, const char *symbol_name, gpointer *symbol) +{ + GList *l; + + /* + * We want to be able to add symbols to an app or an auxiliary + * library to fill in gaps in an introspected library. However, + * normally we would only look for symbols in the main library + * (the first items in typelib->modules). + * + * A more elaborate solution is probably possible, but as a + * simple approach for now, if we fail to find a symbol we look + * for it in the global module (the last item in type->modules). + * + * This would not be very efficient if it happened often, since + * we always do the failed lookup above first, but very few + * symbols should be outside of the main libraries in + * typelib->modules so it doesn't matter. + */ + for (l = typelib->modules; l; l = l->next) + { + GModule *module = l->data; + + if (g_module_symbol (module, symbol_name, symbol)) + return TRUE; + } + + return FALSE; +} diff --git a/gtypelib.h b/gtypelib.h index 31c484db4..823e8a26a 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -484,7 +484,7 @@ struct _GTypelib { gsize len; gboolean owns_memory; GMappedFile *mfile; - GModule *module; + GList *modules; }; DirEntry *g_typelib_get_dir_entry (GTypelib *typelib, From a0d5227db524a7cda96900414de8dd13e06f8b58 Mon Sep 17 00:00:00 2001 From: Lucas Rocha Date: Thu, 9 Oct 2008 16:44:11 +0000 Subject: [PATCH 105/692] fix regression on invoke test case by making sure we load the global 2008-10-09 Lucas Rocha * girepository/girepository.c (register_internal): fix regression on invoke test case by making sure we load the global module in the typelib when dealing with inline typelibs. * girepository/gtypelib.c: a couple of coding style fixes. svn path=/trunk/; revision=661 --- girepository.c | 3 +++ gtypelib.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/girepository.c b/girepository.c index 15e043554..7cb81f30d 100644 --- a/girepository.c +++ b/girepository.c @@ -252,6 +252,9 @@ register_internal (GIRepository *repository, g_hash_table_insert (repository->priv->typelibs, key, (void *)typelib); } + if (typelib->modules == NULL) + typelib->modules = g_list_append(typelib->modules, g_module_open (NULL, 0)); + return namespace; } diff --git a/gtypelib.c b/gtypelib.c index 34a65e880..df99eb433 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -2059,7 +2059,7 @@ g_typelib_free (GTypelib *typelib) } const gchar * -g_typelib_get_namespace(GTypelib *typelib) +g_typelib_get_namespace (GTypelib *typelib) { return g_typelib_get_string (typelib, ((Header *) typelib->data)->namespace); } @@ -2074,7 +2074,7 @@ g_typelib_get_namespace(GTypelib *typelib) * Return value: #TRUE on success **/ gboolean -g_typelib_symbol(GTypelib *typelib, const char *symbol_name, gpointer *symbol) +g_typelib_symbol (GTypelib *typelib, const char *symbol_name, gpointer *symbol) { GList *l; From 1b2aa595343cd7c624d97181e352a3252ec7c6ca Mon Sep 17 00:00:00 2001 From: Johan Bilien Date: Sat, 11 Oct 2008 23:19:59 +0000 Subject: [PATCH 106/692] ignore non-UTF-8 string constants 2008-10-11 Johan Bilien * giscanner/scannerparser.y: ignore non-UTF-8 string constants 2008-10-11 Johan Bilien Bug 552347: Parse #defines constants * girepository/gtypelib.c: update the list of value_size with recently defined type tags * giscanner/scannerparser.y: brought back parsing of #defined, as present in older version * giscanner/giscannermodule.c: bind gi_source_scanner_append_filename * giscanner/girwriter.py: write out constant tags in the gir * giscanner/sourcescanner.py: add accessor for const_string * giscanner/transformer.py, giscanner/glibtransformer.py: handle constant svn path=/trunk/; revision=673 --- gtypelib.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/gtypelib.c b/gtypelib.c index df99eb433..e3f52aa5c 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -878,13 +878,35 @@ validate_constant_blob (GTypelib *typelib, GError **error) { gint value_size[] = { - 0, 4, 1, 1, 2, 2, 4, 4, 8, 8, - sizeof (gint), sizeof (guint), - sizeof (glong), sizeof (gulong), - sizeof (gssize), sizeof (gsize), - sizeof (gfloat), sizeof (gdouble), - 0, 0 - }; + 0, /* VOID */ + 4, /* BOOLEAN */ + 1, /* INT8 */ + 1, /* UINT8 */ + 2, /* INT16 */ + 2, /* UINT16 */ + 4, /* INT32 */ + 4, /* UINT32 */ + 8, /* INT64 */ + 8, /* UINT64 */ + sizeof (gint), + sizeof (guint), + sizeof (glong), + sizeof (gulong), + sizeof (gssize), + sizeof (gsize), + sizeof (gfloat), + sizeof (gdouble), + sizeof (time_t), + 0, /* GTYPE */ + 0, /* UTF8 */ + 0, /* FILENAME */ + 0, /* ARRAY */ + 0, /* INTERFACE */ + 0, /* GLIST */ + 0, /* GSLIST */ + 0, /* GHASH */ + 0, /* ERROR */ + }; ConstantBlob *blob; SimpleTypeBlob *type; From 3be641f8367e9f555c1dc4887f5afc8324fd4534 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 12 Oct 2008 04:51:48 +0000 Subject: [PATCH 107/692] Bug 552858: versioning This is a big patch. You should probably remove your installation tree to be cleaner. * docs/typelib-format.txt: Add nsversion entry which holds version of namespace. * girepository/girepository.h: Add 'version' parameter to g_irepository_require. This may be NULL. Normally bindings should pass an explicit version though. * girepository/girepository.c: Lots of infrastructure to support versioning. Add some more documentation. Disallow some usage of NULL namespaces. * girepository/girmodule.c: Add version parameter. * girepository/gtypelib.c: Update header size. * giscanner/ast.py: Add version to Namespace. * giscanner/girparser.py: Parse version attribute from XML, pass to Namespace. * giscanner/girwriter.py: Write out version parameter. * giscanner/transformer.py: Clean up include registration. * tests/*: Add version attribute. * tests/invoke/invoke.c: Don't try looking up test before it's loaded in repository. * tools/generate.c: Output version parameter. * gir/Makefile.am: Add 2.0 version to .gir files. svn path=/trunk/; revision=677 --- girepository.c | 641 +++++++++++++++++++++++++++++++++++++++---------- girepository.h | 15 +- girmodule.c | 6 +- girmodule.h | 2 + girparser.c | 9 +- gtypelib.c | 2 +- gtypelib.h | 1 + 7 files changed, 542 insertions(+), 134 deletions(-) diff --git a/girepository.c b/girepository.c index 7cb81f30d..5bbad5328 100644 --- a/girepository.c +++ b/girepository.c @@ -2,6 +2,8 @@ /* GObject introspection: Repository implementation * * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008 Colin Walters + * Copyright (C) 2008 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -35,7 +37,7 @@ static GSList *search_path = NULL; struct _GIRepositoryPrivate { GHashTable *typelibs; /* (string) namespace -> GTypelib */ - GHashTable *lazy_typelibs; /* (string) namespace -> GTypelib */ + GHashTable *lazy_typelibs; /* (string) namespace-version -> GTypelib */ }; G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT); @@ -59,6 +61,7 @@ g_irepository_finalize (GObject *object) GIRepository *repository = G_IREPOSITORY (object); g_hash_table_destroy (repository->priv->typelibs); + g_hash_table_destroy (repository->priv->lazy_typelibs); (* G_OBJECT_CLASS (g_irepository_parent_class)->finalize) (G_OBJECT (repository)); } @@ -146,19 +149,52 @@ get_repository (GIRepository *repository) } } +static GTypelib * +check_version_conflict (GTypelib *typelib, + const gchar *namespace, + const gchar *expected_version, + char **version_conflict) +{ + Header *header; + const char *loaded_version; + + if (expected_version == NULL) + { + if (version_conflict) + *version_conflict = NULL; + return typelib; + } + + header = (Header*)typelib->data; + loaded_version = g_typelib_get_string (typelib, header->nsversion); + g_assert (loaded_version != NULL); + + if (strcmp (expected_version, loaded_version) != 0) + { + if (version_conflict) + *version_conflict = (char*)loaded_version; + return NULL; + } + if (version_conflict) + *version_conflict = NULL; + return typelib; +} + static GTypelib * get_registered_status (GIRepository *repository, const char *namespace, + const char *version, gboolean allow_lazy, - gboolean *lazy_status) + gboolean *lazy_status, + char **version_conflict) { GTypelib *typelib; repository = get_repository (repository); if (lazy_status) *lazy_status = FALSE; typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); - if (typelib) - return typelib; + if (typelib) + return check_version_conflict (typelib, namespace, version, version_conflict); typelib = g_hash_table_lookup (repository->priv->lazy_typelibs, namespace); if (!typelib) return NULL; @@ -166,14 +202,15 @@ get_registered_status (GIRepository *repository, *lazy_status = TRUE; if (!allow_lazy) return NULL; - return typelib; + return check_version_conflict (typelib, namespace, version, version_conflict); } static GTypelib * get_registered (GIRepository *repository, - const char *namespace) + const char *namespace, + const char *version) { - return get_registered_status (repository, namespace, TRUE, NULL); + return get_registered_status (repository, namespace, version, TRUE, NULL, NULL); } static gboolean @@ -192,19 +229,28 @@ load_dependencies_recurse (GIRepository *repository, for (i = 0; dependencies[i]; i++) { char *dependency = dependencies[i]; + const char *last_dash; + char *dependency_namespace; + const char *dependency_version; + + last_dash = strrchr (dependency, '-'); + dependency_namespace = g_strndup (dependency, last_dash - dependency); + dependency_version = last_dash+1; - if (!g_irepository_require (repository, dependency, + if (!g_irepository_require (repository, dependency_namespace, dependency_version, 0, error)) { + g_free (dependency_namespace); g_strfreev (dependencies); return FALSE; } + g_free (dependency_namespace); } g_strfreev (dependencies); } return TRUE; } - + static const char * register_internal (GIRepository *repository, const char *source, @@ -214,6 +260,7 @@ register_internal (GIRepository *repository, { Header *header; const gchar *namespace; + const gchar *version; gboolean was_loaded; gboolean currently_lazy; @@ -224,6 +271,7 @@ register_internal (GIRepository *repository, g_return_val_if_fail (header != NULL, FALSE); namespace = g_typelib_get_string (typelib, header->namespace); + version = g_typelib_get_string (typelib, header->nsversion); if (lazy) { @@ -268,7 +316,7 @@ g_irepository_get_dependencies (GIRepository *repository, repository = get_repository (repository); - typelib = get_registered (repository, namespace); + typelib = get_registered (repository, namespace, NULL); g_return_val_if_fail (typelib != NULL, NULL); return get_typelib_dependencies (typelib); @@ -282,28 +330,74 @@ g_irepository_load_typelib (GIRepository *repository, { Header *header; const char *namespace; + const char *nsversion; gboolean allow_lazy = flags & G_IREPOSITORY_LOAD_FLAG_LAZY; gboolean is_lazy; + char *version_conflict; repository = get_repository (repository); header = (Header *) typelib->data; namespace = g_typelib_get_string (typelib, header->namespace); + nsversion = g_typelib_get_string (typelib, header->nsversion); - if (get_registered_status (repository, namespace, allow_lazy, &is_lazy)) - return namespace; + if (get_registered_status (repository, namespace, nsversion, allow_lazy, + &is_lazy, &version_conflict)) + { + if (version_conflict != NULL) + { + g_set_error (error, G_IREPOSITORY_ERROR, + G_IREPOSITORY_ERROR_NAMESPACE_VERSION_CONFLICT, + "Attempting to load namespace '%s', version '%s', but '%s' is already loaded", + namespace, nsversion, version_conflict); + return NULL; + } + return namespace; + } return register_internal (repository, "", allow_lazy, typelib, error); } +/** + * g_irepository_is_registered + * @repository: A #GIRepository, may be %NULL for the default + * @namespace: Namespace of interest + * @version: : Required version, may be %NULL for latest + * + * Check whether a particular namespace (and optionally, a specific + * version thereof) is currently loaded. This function is likely to + * only be useful in unusual circumstances; in order to act upon + * metadata in the namespace, you should call #g_irepository_require + * instead which will ensure the namespace is loaded, and return as + * quickly as this function will if it has already been loaded. + * + * Returns: %TRUE if namespace-version is loaded, %FALSE otherwise + */ gboolean g_irepository_is_registered (GIRepository *repository, - const gchar *namespace) + const gchar *namespace, + const gchar *version) { repository = get_repository (repository); - return get_registered (repository, namespace) != NULL; + return get_registered (repository, namespace, version) != NULL; } +/** + * g_irepository_get_default + * + * Returns the singleton process-global default #GIRepository. It is + * not currently supported to have multiple repositories in a + * particular process, but this function is provided in the unlikely + * eventuality that it would become possible, and as a convenience for + * higher level language bindings to conform to the GObject method + * call conventions. + + * All methods on #GIRepository also accept %NULL as an instance + * parameter to mean this default repository, which is usually more + * convenient for C. + * + * Returns: The global singleton #GIRepository + */ GIRepository * g_irepository_get_default (void) { @@ -321,30 +415,33 @@ count_interfaces (gpointer key, *n_interfaces += ((Header *)typelib)->n_local_entries; } +/** + * g_irepository_get_n_infos + * @repository: A #GIRepository, may be %NULL for the default + * @namespace: Namespace to inspect + * + * This function returns the number of metadata entries in + * given namespace @namespace. The namespace must have + * already been loaded before calling this function. + * + * Returns: number of metadata entries + */ gint g_irepository_get_n_infos (GIRepository *repository, const gchar *namespace) { + GTypelib *typelib; gint n_interfaces = 0; + g_return_val_if_fail (namespace != NULL, -1); + repository = get_repository (repository); - if (namespace) - { - GTypelib *typelib; + typelib = get_registered (repository, namespace, NULL); - typelib = get_registered (repository, namespace); + g_return_val_if_fail (typelib != NULL, -1); - if (typelib) - n_interfaces = ((Header *)typelib->data)->n_local_entries; - } - else - { - g_hash_table_foreach (repository->priv->typelibs, - count_interfaces, &n_interfaces); - g_hash_table_foreach (repository->priv->lazy_typelibs, - count_interfaces, &n_interfaces); - } + n_interfaces = ((Header *)typelib->data)->n_local_entries; return n_interfaces; } @@ -421,12 +518,27 @@ find_interface (gpointer key, } } +/** + * g_irepository_get_info + * @repository: A #GIRepository, may be %NULL for the default + * @namespace: Namespace to inspect + * @index: Offset into namespace metadata for entry + * + * This function returns a particular metadata entry in the + * given namespace @namespace. The namespace must have + * already been loaded before calling this function. + * + * Returns: #GIBaseInfo containing metadata + */ GIBaseInfo * g_irepository_get_info (GIRepository *repository, const gchar *namespace, gint index) { IfaceData data; + GTypelib *typelib; + + g_return_val_if_fail (namespace != NULL, NULL); repository = get_repository (repository); @@ -435,24 +547,29 @@ g_irepository_get_info (GIRepository *repository, data.index = index + 1; data.iface = NULL; - if (namespace) - { - GTypelib *typelib; - - typelib = get_registered (repository, namespace); - - if (typelib) - find_interface ((void *)namespace, typelib, &data); - } - else - { - g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); - g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data); - } + typelib = get_registered (repository, namespace, NULL); + + g_return_val_if_fail (typelib != NULL, NULL); + + find_interface ((void *)namespace, typelib, &data); return data.iface; } +/** + * g_irepository_find_by_gtype + * @repository: A #GIRepository, may be %NULL for the default + * @type: GType to search for + * + * Searches all loaded namespaces for a particular #GType. Note that + * in order to locate the metadata, the namespace corresponding to + * the type must first have been loaded. There is currently no + * mechanism for determining the namespace which corresponds to an + * arbitrary GType - thus, this function will function most reliably + * when you have expect the GType to be from a known namespace. + * + * Returns: #GIBaseInfo representing metadata about @type, or %NULL + */ GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository, GType type) @@ -475,12 +592,14 @@ g_irepository_find_by_gtype (GIRepository *repository, /** * g_irepository_find_by_name * @repository: A #GIRepository, may be %NULL for the default - * @namespace: Namespace to search in, may be %NULL for all - * @name: Name to find + * @namespace: Namespace which will be searched + * @name: Entry name to find + * + * Searches for a particular entry in a namespace. Before calling + * this function for a particular namespace, you must call + * #g_irepository_require once to load the namespace, or otherwise + * ensure the namespace has already been loaded. * - * Searches for a particular name in one or all namespaces. - * See #g_irepository_require to load metadata for namespaces. - * Returns: #GIBaseInfo representing metadata about @name, or %NULL */ GIBaseInfo * @@ -489,6 +608,9 @@ g_irepository_find_by_name (GIRepository *repository, const gchar *name) { IfaceData data; + GTypelib *typelib; + + g_return_val_if_fail (namespace != NULL, NULL); repository = get_repository (repository); @@ -497,20 +619,11 @@ g_irepository_find_by_name (GIRepository *repository, data.index = -1; data.iface = NULL; - if (namespace) - { - GTypelib *typelib; - - typelib = get_registered (repository, namespace); - - if (typelib) - find_interface ((void *)namespace, typelib, &data); - } - else - { - g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); - g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data); - } + typelib = get_registered (repository, namespace, NULL); + + g_return_val_if_fail (typelib != NULL, NULL); + + find_interface ((void *)namespace, typelib, &data); return data.iface; } @@ -529,14 +642,12 @@ collect_namespaces (gpointer key, * g_irepository_get_namespaces * @repository: A #GIRepository, may be %NULL for the default * - * Return the list of currently known namespaces. Normally - * if you want a particular namespace, you should call - * #g_irepository_require to load it in. - - * Returns: List of namespaces + * Return the list of currently loaded namespaces. + * + * Returns: : List of namespaces */ gchar ** -g_irepository_get_namespaces (GIRepository *repository) +g_irepository_get_loaded_namespaces (GIRepository *repository) { GList *l, *list = NULL; gchar **names; @@ -556,18 +667,68 @@ g_irepository_get_namespaces (GIRepository *repository) return names; } +/** + * g_irepository_get_version + * @repository: A #GIRepository, may be %NULL for the default + * @namespace: Namespace to inspect + * + * This function returns the loaded version associated with the given + * namespace @namespace. + * + * Note: The namespace must have already been loaded using a function + * such as #g_irepository_require before calling this function. + * + * Returns: Loaded version + */ const gchar * -g_irepository_get_shared_library (GIRepository *repository, - const gchar *namespace) +g_irepository_get_version (GIRepository *repository, + const gchar *namespace) { GTypelib *typelib; Header *header; + g_return_val_if_fail (namespace != NULL, NULL); + repository = get_repository (repository); - typelib = get_registered (repository, namespace); - if (!typelib) - return NULL; + typelib = get_registered (repository, namespace, NULL); + + g_return_val_if_fail (typelib != NULL, NULL); + + header = (Header *) typelib->data; + return g_typelib_get_string (typelib, header->nsversion); +} + +/** + * g_irepository_get_shared_library + * @repository: A #GIRepository, may be %NULL for the default + * @namespace: Namespace to inspect + * + * This function returns the full path to the shared C library + * associated with the given namespace @namespace. There may be no + * shared library path associated, in which case this function will + * return %NULL. + * + * Note: The namespace must have already been loaded using a function + * such as #g_irepository_require before calling this function. + * + * Returns: Full path to shared library, or %NULL if none associated + */ +const gchar * +g_irepository_get_shared_library (GIRepository *repository, + const gchar *namespace) +{ + GTypelib *typelib; + Header *header; + + g_return_val_if_fail (namespace != NULL, NULL); + + repository = get_repository (repository); + + typelib = get_registered (repository, namespace, NULL); + + g_return_val_if_fail (typelib != NULL, NULL); + header = (Header *) typelib->data; if (header->shared_library) return g_typelib_get_string (typelib, header->shared_library); @@ -579,13 +740,14 @@ g_irepository_get_shared_library (GIRepository *repository, * g_irepository_get_typelib_path * @repository: Repository, may be %NULL for the default * @namespace: GI namespace to use, e.g. "Gtk" + * @version: : Version of namespace to use, e.g. "0.8", may be %NULL * * If namespace @namespace is loaded, return the full path to the * .typelib file it was loaded from. If the typelib for * namespace @namespace was included in a shared library, return * the special string "". * - * Returns: Filesystem path (or ) if successful, %NULL otherwise + * Returns: Filesystem path (or ) if successful, %NULL if namespace is not loaded */ const gchar * @@ -607,94 +769,323 @@ g_irepository_get_typelib_path (GIRepository *repository, return ((char*)orig_key) + strlen ((char *) orig_key) + 1; } +/* This simple search function looks for a specified namespace-version; + it's faster than the full directory listing required for latest version. */ +static GMappedFile * +find_namespace_version (const gchar *namespace, + const gchar *version, + gchar **path_ret) +{ + GSList *ldir; + GError *error = NULL; + GMappedFile *mfile = NULL; + char *fname; + + fname = g_strdup_printf ("%s-%s.typelib", namespace, version); + + for (ldir = search_path; ldir; ldir = ldir->next) + { + Header *header; + char *path = g_build_filename (ldir->data, fname, NULL); + + mfile = g_mapped_file_new (path, FALSE, &error); + if (error) + { + g_free (path); + g_clear_error (&error); + continue; + } + *path_ret = path; + break; + } + g_free (fname); + return mfile; +} + +static gboolean +parse_version (const char *version, + int *major, + int *minor) +{ + const char *dot; + const char *end; + + *major = strtol (version, &end, 10); + dot = strchr (version, '.'); + if (dot == NULL) + { + *minor = 0; + return TRUE; + } + if (dot != end) + return FALSE; + *minor = strtol (dot+1, &end, 10); + if (end != (version + strlen (version))) + return FALSE; + return TRUE; +} + +static int +compare_version (const char *v1, + const char *v2) +{ + gboolean err; + int v1_major, v1_minor; + int v2_major, v2_minor; + + err = parse_version (v1, &v1_major, &v1_minor); + g_assert (!err); + + err = parse_version (v2, &v2_major, &v2_minor); + g_assert (!err); + + if (v1_major > v2_major) + return 1; + else if (v2_major > v1_major) + return -1; + else if (v1_minor > v2_minor) + return 1; + else if (v2_minor > v1_minor) + return -1; + return 0; +} + +struct NamespaceVersionCandidadate +{ + GMappedFile *mfile; + char *path; + char *version; +}; + +static int +compare_candidate_reverse (struct NamespaceVersionCandidadate *c1, + struct NamespaceVersionCandidadate *c2) +{ + int result = compare_version (c1->version, c2->version); + if (result > 0) + return -1; + else if (result < 0) + return 1; + else + return 0; +} + +static void +free_candidate (struct NamespaceVersionCandidadate *candidate) +{ + g_mapped_file_free (candidate->mfile); + g_free (candidate->path); + g_free (candidate->version); + g_free (candidate); +} + +static GMappedFile * +find_namespace_latest (const gchar *namespace, + gchar **version_ret, + gchar **path_ret) +{ + GSList *ldir; + GError *error = NULL; + char *namespace_dash; + char *namespace_typelib; + GSList *candidates = NULL; + GMappedFile *result = NULL; + + *version_ret = NULL; + *path_ret = NULL; + + namespace_dash = g_strdup_printf ("%s-", namespace); + namespace_typelib = g_strdup_printf ("%s.typelib", namespace); + + for (ldir = search_path; ldir; ldir = ldir->next) + { + GDir *dir; + const char *dirname; + const char *entry; + + dirname = (const char*)ldir->data; + dir = g_dir_open (dirname, 0, NULL); + if (dir == NULL) + continue; + while ((entry = g_dir_read_name (dir)) != NULL) + { + GMappedFile *mfile; + char *path, *version; + struct NamespaceVersionCandidadate *candidate; + + if (!g_str_has_suffix (entry, ".typelib")) + continue; + + if (g_str_has_prefix (entry, namespace_dash)) + { + const char *last_dash; + const char *name_end; + int major, minor; + + name_end = strrchr (entry, '.'); + last_dash = strrchr (entry, '-'); + version = g_strndup (last_dash+1, name_end-(last_dash+1)); + if (!parse_version (version, &major, &minor)) + continue; + } + else + continue; + + path = g_build_filename (dirname, entry, NULL); + mfile = g_mapped_file_new (path, FALSE, &error); + if (mfile == NULL) + { + g_free (path); + g_free (version); + g_clear_error (&error); + continue; + } + candidate = g_new0 (struct NamespaceVersionCandidadate, 1); + candidate->mfile = mfile; + candidate->path = path; + candidate->version = version; + candidates = g_slist_prepend (candidates, candidate); + } + g_dir_close (dir); + } + + if (candidates != NULL) + { + struct NamespaceVersionCandidadate *elected; + candidates = g_slist_sort (candidates, (GCompareFunc) compare_candidate_reverse); + + elected = (struct NamespaceVersionCandidadate *) candidates->data; + /* Remove the elected one so we don't try to free it */ + candidates = g_slist_delete_link (candidates, candidates); + + result = elected->mfile; + *path_ret = elected->path; + *version_ret = elected->version; + g_slist_foreach (candidates, (GFunc) free_candidate, NULL); + g_slist_free (candidates); + } + + g_free (namespace_dash); + g_free (namespace_typelib); + return result; +} + /** * g_irepository_require - * @repository: Repository, may be %NULL for the default + * @repository: : Repository, may be %NULL for the default * @namespace: GI namespace to use, e.g. "Gtk" + * @version: : Version of namespace, may be %NULL for latest * @flags: Set of %GIRepositoryLoadFlags, may be %0 * @error: a #GError. * - * Force the namespace @namespace to be loaded if it isn't - * already. If @namespace is not loaded, this function will - * search for a ".typelib" file using the repository search - * path. + * Force the namespace @namespace to be loaded if it isn't already. + * If @namespace is not loaded, this function will search for a + * ".typelib" file using the repository search path. In addition, a + * version @version of namespace may be specified. If @version is + * not specified, the latest will be used. * * Returns: %TRUE if successful, %NULL otherwise */ gboolean g_irepository_require (GIRepository *repository, const gchar *namespace, + const gchar *version, GIRepositoryLoadFlags flags, GError **error) { - GSList *ldir; const char *dir; - gchar *fname, *full_path; GMappedFile *mfile; + gboolean ret = FALSE; GError *error1 = NULL; + Header *header; GTypelib *typelib = NULL; - const gchar *typelib_namespace, *shlib_fname; + const gchar *typelib_namespace, *typelib_version, *shlib_fname; GModule *module; guint32 shlib; - gboolean allow_lazy = flags & G_IREPOSITORY_LOAD_FLAG_LAZY; + gboolean allow_lazy = (flags & G_IREPOSITORY_LOAD_FLAG_LAZY) > 0; gboolean is_lazy; + char *version_conflict = NULL; + char *path = NULL; + char *tmp_version = NULL; + + g_return_val_if_fail (namespace != NULL, FALSE); repository = get_repository (repository); - if (get_registered_status (repository, namespace, allow_lazy, &is_lazy)) + if (get_registered_status (repository, namespace, version, allow_lazy, + &is_lazy, &version_conflict)) return TRUE; - fname = g_strconcat (namespace, ".typelib", NULL); - - for (ldir = search_path; ldir; ldir = ldir->next) - { - Header *header; - - full_path = g_build_filename (ldir->data, fname, NULL); - mfile = g_mapped_file_new (full_path, FALSE, &error1); - if (error1) - { - g_clear_error (&error1); - continue; - } - - typelib = g_typelib_new_from_mapped_file (mfile); - header = (Header *) typelib->data; - typelib_namespace = g_typelib_get_string (typelib, header->namespace); - - if (strcmp (typelib_namespace, namespace) != 0) - { - g_set_error (error, G_IREPOSITORY_ERROR, - G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH, - "Typelib file %s for namespace '%s' contains " - "namespace '%s' which doesn't match the file name", - full_path, namespace, typelib_namespace); - g_free (full_path); - return FALSE; - } - break; - } - - if (typelib == NULL) + if (version_conflict != NULL) { g_set_error (error, G_IREPOSITORY_ERROR, - G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, - "Typelib file for namespace '%s' was not found in search" - " path or could not be openened", namespace); - g_free (full_path); + G_IREPOSITORY_ERROR_NAMESPACE_VERSION_CONFLICT, + "Requiring namespace '%s' version '%s', but '%s' is already loaded", + namespace, version, version_conflict); return FALSE; } - g_free (fname); - if (!register_internal (repository, full_path, allow_lazy, + if (version != NULL) + { + mfile = find_namespace_version (namespace, version, &path); + tmp_version = g_strdup (version); + } + else + { + mfile = find_namespace_latest (namespace, &tmp_version, &path); + } + + if (mfile == NULL) + { + const char *error_fmt; + if (version != NULL) + g_set_error (error, G_IREPOSITORY_ERROR, + G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, + "Typelib file %s for namespace '%s', version '%s' not found", + namespace, version); + else + g_set_error (error, G_IREPOSITORY_ERROR, + G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, + "Typelib file for namespace '%s' (any version) not found", + namespace); + goto out; + } + + typelib = g_typelib_new_from_mapped_file (mfile); + header = (Header *) typelib->data; + typelib_namespace = g_typelib_get_string (typelib, header->namespace); + typelib_version = g_typelib_get_string (typelib, header->nsversion); + + if (strcmp (typelib_namespace, namespace) != 0) + { + g_set_error (error, G_IREPOSITORY_ERROR, + G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH, + "Typelib file %s for namespace '%s' contains " + "namespace '%s' which doesn't match the file name", + path, namespace, typelib_namespace); + goto out; + } + if (version != NULL && strcmp (typelib_version, version) != 0) + { + g_set_error (error, G_IREPOSITORY_ERROR, + G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH, + "Typelib file %s for namespace '%s' contains " + "version '%s' which doesn't match the expected version '%s'", + path, namespace, typelib_version, version); + goto out; + } + + if (!register_internal (repository, path, allow_lazy, typelib, error)) { g_typelib_free (typelib); - g_free (full_path); - return FALSE; + goto out; } - g_free (full_path); - return TRUE; + ret = TRUE; + out: + g_free (tmp_version); + g_free (path); + return ret; } diff --git a/girepository.h b/girepository.h index 28848d5e9..fb95a4fee 100644 --- a/girepository.h +++ b/girepository.h @@ -82,17 +82,19 @@ const char * g_irepository_load_typelib (GIRepository *repository, GIRepositoryLoadFlags flags, GError **error); gboolean g_irepository_is_registered (GIRepository *repository, - const gchar *namespace); + const gchar *namespace, + const gchar *version); GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, const gchar *namespace, const gchar *name); gboolean g_irepository_require (GIRepository *repository, - const char *namespace, + const gchar *namespace, + const gchar *version, GIRepositoryLoadFlags flags, GError **error); gchar ** g_irepository_get_dependencies (GIRepository *repository, - const char *namespace); -gchar ** g_irepository_get_namespaces (GIRepository *repository); + const gchar *namespace); +gchar ** g_irepository_get_loaded_namespaces (GIRepository *repository); GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository, GType gtype); gint g_irepository_get_n_infos (GIRepository *repository, @@ -104,6 +106,9 @@ const gchar * g_irepository_get_typelib_path (GIRepository *repository, const gchar *namespace); const gchar * g_irepository_get_shared_library (GIRepository *repository, const gchar *namespace); +const gchar * g_irepository_get_version (GIRepository *repository, + const gchar *namespace); + /* Typelib */ GTypelib * g_typelib_new_from_memory (guchar *memory, @@ -112,6 +117,7 @@ GTypelib * g_typelib_new_from_const_memory (const guchar *memory, gsize len); GTypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile); void g_typelib_free (GTypelib *typelib); + gboolean g_typelib_symbol (GTypelib *typelib, const gchar *symbol_name, gpointer *symbol); @@ -121,6 +127,7 @@ typedef enum { G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH, + G_IREPOSITORY_ERROR_NAMESPACE_VERSION_CONFLICT, G_IREPOSITORY_ERROR_LIBRARY_NOT_FOUND } GIRepositoryError; diff --git a/girmodule.c b/girmodule.c index 65ee392d9..ad0ecf542 100644 --- a/girmodule.c +++ b/girmodule.c @@ -29,13 +29,16 @@ GIrModule * -g_ir_module_new (const gchar *name, const gchar *shared_library) +g_ir_module_new (const gchar *name, + const gchar *version, + const gchar *shared_library) { GIrModule *module; module = g_new0 (GIrModule, 1); module->name = g_strdup (name); + module->version = g_strdup (version); if (shared_library) module->shared_library = g_strdup (shared_library); else @@ -156,6 +159,7 @@ g_ir_module_build_typelib (GIrModule *module, header->dependencies = 0; header->size = 0; /* filled in later */ header->namespace = write_string (module->name, strings, data, &header_size); + header->nsversion = write_string (module->version, strings, data, &header_size); header->shared_library = (module->shared_library? write_string (module->shared_library, strings, data, &header_size) : 0); diff --git a/girmodule.h b/girmodule.h index a4511e3b7..5b63c36eb 100644 --- a/girmodule.h +++ b/girmodule.h @@ -32,12 +32,14 @@ typedef struct _GIrModule GIrModule; struct _GIrModule { gchar *name; + gchar *version; gchar *shared_library; GList *dependencies; GList *entries; }; GIrModule *g_ir_module_new (const gchar *name, + const gchar *nsversion, const gchar *module_filename); void g_ir_module_free (GIrModule *module); diff --git a/girparser.c b/girparser.c index d4cc34a4d..5b66fa682 100644 --- a/girparser.c +++ b/girparser.c @@ -2050,7 +2050,7 @@ parse_include (GMarkupParseContext *context, g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, - "Could not find GIR file '%s'; check XDG_DATA_DIRS or use --includedir", + "Could not find GIR file '%s.gir'; check XDG_DATA_DIRS or use --includedir", name); return FALSE; } @@ -2260,16 +2260,19 @@ start_element_handler (GMarkupParseContext *context, case 'n': if (strcmp (element_name, "namespace") == 0 && ctx->state == STATE_REPOSITORY) { - const gchar *name, *shared_library; + const gchar *name, *version, *shared_library; name = find_attribute ("name", attribute_names, attribute_values); + version = find_attribute ("version", attribute_names, attribute_values); shared_library = find_attribute ("shared-library", attribute_names, attribute_values); if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); + else if (version == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "version"); else { - ctx->current_module = g_ir_module_new (name, shared_library); + ctx->current_module = g_ir_module_new (name, version, shared_library); ctx->modules = g_list_append (ctx->modules, ctx->current_module); ctx->current_module->dependencies = ctx->dependencies; diff --git a/gtypelib.c b/gtypelib.c index e3f52aa5c..7a7a31f07 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -153,7 +153,7 @@ g_typelib_check_sanity (void) size_check_ok = FALSE; \ } - CHECK_SIZE (Header, 104); + CHECK_SIZE (Header, 108); CHECK_SIZE (DirEntry, 12); CHECK_SIZE (SimpleTypeBlob, 4); CHECK_SIZE (ArgBlob, 12); diff --git a/gtypelib.h b/gtypelib.h index 823e8a26a..16182d511 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -61,6 +61,7 @@ typedef struct guint32 size; guint32 namespace; + guint32 nsversion; guint32 shared_library; guint16 entry_blob_size; From 5cfc7580a3c81e83e811ca4f7da47e1043911001 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 12 Oct 2008 16:36:29 +0000 Subject: [PATCH 108/692] Add tests/repository which has some repository regression tests svn path=/trunk/; revision=683 --- girepository.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girepository.c b/girepository.c index 5bbad5328..d56482ece 100644 --- a/girepository.c +++ b/girepository.c @@ -490,7 +490,7 @@ find_interface (gpointer key, for (i = 1; i <= n_entries; i++) { entry = g_typelib_get_dir_entry (typelib, i); - if (entry->blob_type < 4) + if (entry->blob_type < BLOB_TYPE_BOXED) continue; offset = *(guint32*)&typelib->data[entry->offset + 8]; From 44172e786af178da9424cee4d1df0cb3c6785a4d Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Sun, 12 Oct 2008 19:30:22 +0000 Subject: [PATCH 109/692] make 'unregistered' one bit wide as everywhere else 2008-10-12 Tommi Komulainen * girepository/gtypelib.h (RegisteredTypeBlob): make 'unregistered' one bit wide as everywhere else svn path=/trunk/; revision=684 --- gtypelib.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gtypelib.h b/gtypelib.h index 16182d511..b71322313 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -270,7 +270,8 @@ typedef struct { guint16 blob_type; guint16 deprecated : 1; - guint16 unregistered :15; + guint16 unregistered : 1; + guint16 reserved :14; guint32 name; guint32 gtype_name; From 6a82099f9bfde0c6dfa3ab7bfffc1e37de16af98 Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Sun, 12 Oct 2008 20:53:26 +0000 Subject: [PATCH 110/692] =?UTF-8?q?Bug=20556048=20=E2=80=93=20Crash=20in?= =?UTF-8?q?=20g=5Firepository=5Ffind=5Fby=5Fgtype?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * girepository/gtypelib.h (BLOB_IS_REGISTERED_TYPE): added * girepository/girepository.c (find_interface): Fix find_by_gtype case to get the type name from right offset svn path=/trunk/; revision=686 --- girepository.c | 13 +++++++++---- gtypelib.h | 7 +++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/girepository.c b/girepository.c index d56482ece..97f2627db 100644 --- a/girepository.c +++ b/girepository.c @@ -489,12 +489,17 @@ find_interface (gpointer key, { for (i = 1; i <= n_entries; i++) { + RegisteredTypeBlob *blob; + entry = g_typelib_get_dir_entry (typelib, i); - if (entry->blob_type < BLOB_TYPE_BOXED) + if (!BLOB_IS_REGISTERED_TYPE (entry)) continue; - - offset = *(guint32*)&typelib->data[entry->offset + 8]; - type = g_typelib_get_string (typelib, offset); + + blob = (RegisteredTypeBlob *)entry; + if (!blob->gtype_name) + continue; + + type = g_typelib_get_string (typelib, blob->gtype_name); if (strcmp (type, iface_data->type) == 0) { index = i; diff --git a/gtypelib.h b/gtypelib.h index b71322313..54bf0523c 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -45,6 +45,13 @@ enum BLOB_TYPE_UNION }; +#define BLOB_IS_REGISTERED_TYPE(blob) \ + ((blob)->blob_type == BLOB_TYPE_STRUCT || \ + (blob)->blob_type == BLOB_TYPE_UNION || \ + (blob)->blob_type == BLOB_TYPE_ENUM || \ + (blob)->blob_type == BLOB_TYPE_OBJECT || \ + (blob)->blob_type == BLOB_TYPE_INTERFACE) + typedef struct { gchar magic[16]; From 1ff932e7a13c5fb05af3550c669a983519cfc842 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 12 Oct 2008 21:03:41 +0000 Subject: [PATCH 111/692] Fix inverted test for success in version parsing. svn path=/trunk/; revision=687 --- girepository.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/girepository.c b/girepository.c index 97f2627db..06c3e3356 100644 --- a/girepository.c +++ b/girepository.c @@ -834,15 +834,15 @@ static int compare_version (const char *v1, const char *v2) { - gboolean err; + gboolean success; int v1_major, v1_minor; int v2_major, v2_minor; - - err = parse_version (v1, &v1_major, &v1_minor); - g_assert (!err); - err = parse_version (v2, &v2_major, &v2_minor); - g_assert (!err); + success = parse_version (v1, &v1_major, &v1_minor); + g_assert (success); + + success = parse_version (v2, &v2_major, &v2_minor); + g_assert (success); if (v1_major > v2_major) return 1; From bc54751766b8e23495904db5ff0ff17357866638 Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Sun, 12 Oct 2008 21:07:22 +0000 Subject: [PATCH 112/692] Refactor handling of transfer=none/shallow/full to separate function 2008-10-12 Tommi Komulainen * girepository/girparser.c (parse_param_transfer, start_parameter): Refactor handling of transfer=none/shallow/full to separate function svn path=/trunk/; revision=688 --- girparser.c | 58 +++++++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/girparser.c b/girparser.c index 5b66fa682..b8bff22e7 100644 --- a/girparser.c +++ b/girparser.c @@ -658,6 +658,36 @@ start_function (GMarkupParseContext *context, return TRUE; } +static void +parse_param_transfer (GIrNodeParam *param, const gchar *transfer) +{ + if (transfer && strcmp (transfer, "none") == 0) + { + param->transfer = FALSE; + param->shallow_transfer = FALSE; + } + else if (transfer && strcmp (transfer, "shallow") == 0) + { + param->transfer = FALSE; + param->shallow_transfer = TRUE; + } + else + { + if (transfer) + { + if (strcmp (transfer, "full") != 0) + g_warning ("Unknown transfer %s", transfer); + else + param->transfer = TRUE; + } + else if (param->in && !param->out) + param->transfer = FALSE; + else + param->transfer = TRUE; + param->shallow_transfer = FALSE; + } +} + static gboolean start_parameter (GMarkupParseContext *context, const gchar *element_name, @@ -733,32 +763,8 @@ start_parameter (GMarkupParseContext *context, else param->null_ok = FALSE; - if (transfer && strcmp (transfer, "none") == 0) - { - param->transfer = FALSE; - param->shallow_transfer = FALSE; - } - else if (transfer && strcmp (transfer, "shallow") == 0) - { - param->transfer = FALSE; - param->shallow_transfer = TRUE; - } - else - { - if (transfer) - { - if (strcmp (transfer, "full") != 0) - g_warning ("Unknown transfer %s", transfer); - else - param->transfer = TRUE; - } - else if (param->in && !param->out) - param->transfer = FALSE; - else - param->transfer = TRUE; - param->shallow_transfer = FALSE; - } - + parse_param_transfer (param, transfer); + ((GIrNode *)param)->name = g_strdup (name); switch (ctx->current_node->type) From 25e43d53d17b04c3a97d0be4608af5847be02848 Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Sun, 12 Oct 2008 21:07:28 +0000 Subject: [PATCH 113/692] use "container" for container/shallow ownership transfer (not "shallow") 2008-10-12 Tommi Komulainen * girepository/girparser.c (parse_param_transfer): * tools/generate.c (write_callable_info): use "container" for container/shallow ownership transfer (not "shallow") svn path=/trunk/; revision=689 --- girparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index b8bff22e7..ead27f37a 100644 --- a/girparser.c +++ b/girparser.c @@ -666,7 +666,7 @@ parse_param_transfer (GIrNodeParam *param, const gchar *transfer) param->transfer = FALSE; param->shallow_transfer = FALSE; } - else if (transfer && strcmp (transfer, "shallow") == 0) + else if (transfer && strcmp (transfer, "container") == 0) { param->transfer = FALSE; param->shallow_transfer = TRUE; From a940cef8c721fa55f9d8a9199b5ba4f6b6e4bd61 Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Sun, 12 Oct 2008 21:07:33 +0000 Subject: [PATCH 114/692] handle "transfer-ownership" attribute 2008-10-12 Tommi Komulainen * girepository/girparser.c (start_return_value): handle "transfer-ownership" attribute svn path=/trunk/; revision=690 --- girparser.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/girparser.c b/girparser.c index ead27f37a..8e47ec91b 100644 --- a/girparser.c +++ b/girparser.c @@ -1664,6 +1664,7 @@ start_return_value (GMarkupParseContext *context, ctx->state == STATE_FUNCTION) { GIrNodeParam *param; + const gchar *transfer; param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM); param->in = FALSE; @@ -1674,6 +1675,9 @@ start_return_value (GMarkupParseContext *context, state_switch (ctx, STATE_FUNCTION_RETURN); + transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); + parse_param_transfer (param, transfer); + switch (ctx->current_node->type) { case G_IR_NODE_FUNCTION: From 0103bf1fe338e41421bdd388b0e8b4957a1fb048 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 12 Oct 2008 21:22:44 +0000 Subject: [PATCH 115/692] Don't cast DirEntry to Blob, actually look it up by offset svn path=/trunk/; revision=696 --- girepository.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girepository.c b/girepository.c index 06c3e3356..eda3fcd5f 100644 --- a/girepository.c +++ b/girepository.c @@ -495,7 +495,7 @@ find_interface (gpointer key, if (!BLOB_IS_REGISTERED_TYPE (entry)) continue; - blob = (RegisteredTypeBlob *)entry; + blob = (RegisteredTypeBlob *)(&typelib->data[entry->offset]); if (!blob->gtype_name) continue; From 5069680682d7bb94d422784b0429f1063e2e6ac9 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 13 Oct 2008 16:59:09 +0000 Subject: [PATCH 116/692] Document g_irepository_get_dependencies svn path=/trunk/; revision=701 --- girepository.c | 14 ++++++++++++++ girepository.h | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/girepository.c b/girepository.c index eda3fcd5f..6d4011400 100644 --- a/girepository.c +++ b/girepository.c @@ -306,6 +306,20 @@ register_internal (GIRepository *repository, return namespace; } +/** + * g_irepository_get_dependencies + * @repository: A #GIRepository, may be %NULL for the default + * @namespace: Namespace of interest + * + * Return an array of all (transitive) dependencies for namespace + * @namespace, including version. The returned strings are of the + * form namespace-version. + * + * Note: The namespace must have already been loaded using a function + * such as #g_irepository_require before calling this function. + * + * Returns: Zero-terminated string array of versioned dependencies + */ char ** g_irepository_get_dependencies (GIRepository *repository, const char *namespace) diff --git a/girepository.h b/girepository.h index fb95a4fee..0b28e40af 100644 --- a/girepository.h +++ b/girepository.h @@ -81,7 +81,7 @@ const char * g_irepository_load_typelib (GIRepository *repository, GTypelib *typelib, GIRepositoryLoadFlags flags, GError **error); -gboolean g_irepository_is_registered (GIRepository *repository, +gboolean g_irepository_is_registered (GIRepository *repository, const gchar *namespace, const gchar *version); GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, @@ -89,7 +89,7 @@ GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, const gchar *name); gboolean g_irepository_require (GIRepository *repository, const gchar *namespace, - const gchar *version, + const gchar *version, GIRepositoryLoadFlags flags, GError **error); gchar ** g_irepository_get_dependencies (GIRepository *repository, From 03d83791426f9d96ca47b4e41e4ad6e6cb6854d4 Mon Sep 17 00:00:00 2001 From: Johan Bilien Date: Tue, 14 Oct 2008 22:25:13 +0000 Subject: [PATCH 117/692] add g_union_info_find_method 2008-10-14 Johan Bilien * girepository/ginfo.c, girepository/girepository.h: add g_union_info_find_method svn path=/trunk/; revision=706 --- ginfo.c | 16 ++++++++++++++++ girepository.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/ginfo.c b/ginfo.c index 75ced84e8..aa03bc30b 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1838,3 +1838,19 @@ g_union_info_get_discriminator (GIUnionInfo *info, return NULL; } + +GIFunctionInfo * +g_union_info_find_method (GIUnionInfo *info, + const gchar *name) +{ + gint offset; + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->typelib->data; + StructBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; + + offset = base->offset + header->union_blob_size + + blob->n_fields * header->field_blob_size; + + return find_method (base, offset, blob->n_methods, name); +} + diff --git a/girepository.h b/girepository.h index 0b28e40af..42db8d33c 100644 --- a/girepository.h +++ b/girepository.h @@ -362,6 +362,8 @@ gint g_union_info_get_discriminator_offset (GIUnionInfo *info) GITypeInfo * g_union_info_get_discriminator_type (GIUnionInfo *info); GIConstantInfo * g_union_info_get_discriminator (GIUnionInfo *info, gint n); +GIFunctionInfo * g_union_info_find_method (GIUnionInfo *info, + const gchar *name); /* GIStructInfo */ From 6e266d5f53f2315b0a0f5c276d6ff89bb2b81db9 Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Wed, 15 Oct 2008 20:44:29 +0000 Subject: [PATCH 118/692] =?UTF-8?q?Bug=20556400=20=E2=80=93=20Fails=20to?= =?UTF-8?q?=20build=20on=20OS=20X=2010.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-10-15 Tommi Komulainen Bug 556400 – Fails to build on OS X 10.4 * configure.ac: check for functions backtrace and backtrace_symbols * girepository/girparser.c (backtrace_stderr): Comment out implementation if the functions are not available. * gcov.mak (clean-gcov, clean-gcno): always call 'find' with a directory for better portability svn path=/trunk/; revision=711 --- girparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index 8e47ec91b..cdc47318a 100644 --- a/girparser.c +++ b/girparser.c @@ -180,7 +180,7 @@ locate_gir (const char *name, const char * const* extra_paths) static void backtrace_stderr (void) { -#ifndef _WIN32 +#if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS) void *array[50]; int size; char **strings; From 9153ef51aefb0572e43934f446ab516ec9770cc7 Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Wed, 15 Oct 2008 22:08:26 +0000 Subject: [PATCH 119/692] =?UTF-8?q?Bug=20556174=20=E2=80=93=20parse=20type?= =?UTF-8?q?s=20for=20lists=20etc.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-10-15 Tommi Komulainen Bug 556174 – parse types for lists etc. * girepository/girparser.c (end_type_recurse): * tests/boxed.gir: * tools/generate.c (write_type_info, write_field_info, write_callable_info, write_callable_info, write_constant_info, write_property_info): use nested s for lists and hashes svn path=/trunk/; revision=717 --- girparser.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/girparser.c b/girparser.c index cdc47318a..35f882bea 100644 --- a/girparser.c +++ b/girparser.c @@ -1607,30 +1607,33 @@ end_type_recurse (ParseContext *ctx) { GList *types; GIrNodeType *parent; + GIrNodeType *param = NULL; parent = (GIrNodeType *) ((GList*)ctx->type_stack->data)->data; + if (ctx->type_parameters) + param = (GIrNodeType *) ctx->type_parameters->data; if (parent->tag == GI_TYPE_TAG_ARRAY || parent->tag == GI_TYPE_TAG_GLIST || parent->tag == GI_TYPE_TAG_GSLIST) { - if (ctx->type_parameters == NULL) - parent->parameter_type1 = parse_type (ctx, "pointer"); + g_assert (param != NULL); + + if (parent->parameter_type1 == NULL) + parent->parameter_type1 = param; else - parent->parameter_type1 = (GIrNodeType*)ctx->type_parameters->data; + g_assert_not_reached (); } else if (parent->tag == GI_TYPE_TAG_GHASH) { - if (ctx->type_parameters == NULL) - { - parent->parameter_type1 = parse_type (ctx, "pointer"); - parent->parameter_type2 = parse_type (ctx, "pointer"); - } + g_assert (param != NULL); + + if (parent->parameter_type1 == NULL) + parent->parameter_type1 = param; + else if (parent->parameter_type2 == NULL) + parent->parameter_type2 = param; else - { - parent->parameter_type1 = (GIrNodeType*) ctx->type_parameters->data; - parent->parameter_type2 = (GIrNodeType*) ctx->type_parameters->next->data; - } + g_assert_not_reached (); } g_list_free (ctx->type_parameters); ctx->type_parameters = (GList *)ctx->type_stack->data; From 7d89fdf64366b296473d0f10a3761c9a54d7727d Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Wed, 15 Oct 2008 22:28:41 +0000 Subject: [PATCH 120/692] refactor common code for processing members to a function 2008-10-15 Tommi Komulainen * a/girepository/girnode.c (g_ir_node_build_members, g_ir_node_build_typelib): refactor common code for processing members to a function svn path=/trunk/; revision=721 --- girnode.c | 286 ++++++++++++++++++++---------------------------------- 1 file changed, 103 insertions(+), 183 deletions(-) diff --git a/girnode.c b/girnode.c index fe618ad3b..1b569518d 100644 --- a/girnode.c +++ b/girnode.c @@ -1167,6 +1167,36 @@ serialize_type (GIrModule *module, } } +static void +g_ir_node_build_members (GList **members, + GIrNodeTypeId type, + guint16 *count, + GIrModule *module, + GList *modules, + GHashTable *strings, + GHashTable *types, + guchar *data, + guint32 *offset, + guint32 *offset2) +{ + GList *l = *members; + + while (l) + { + GIrNode *member = (GIrNode *)l->data; + GList *next = l->next; + + if (member->type == type) + { + (*count)++; + g_ir_node_build_typelib (member, module, modules, strings, + types, data, offset, offset2); + *members = g_list_delete_link (*members, l); + } + l = next; + } +} + void g_ir_node_build_typelib (GIrNode *node, GIrModule *module, @@ -1601,6 +1631,7 @@ g_ir_node_build_typelib (GIrNode *node, { StructBlob *blob = (StructBlob *)&data[*offset]; GIrNodeStruct *struct_ = (GIrNodeStruct *)node; + GList *members; blob->blob_type = BLOB_TYPE_STRUCT; blob->deprecated = struct_->deprecated; @@ -1623,29 +1654,18 @@ g_ir_node_build_typelib (GIrNode *node, blob->n_methods = 0; *offset += 20; - for (l = struct_->members; l; l = l->next) - { - GIrNode *member = (GIrNode *)l->data; - if (member->type == G_IR_NODE_FIELD) - { - blob->n_fields++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); - } - } + members = g_list_copy (struct_->members); - for (l = struct_->members; l; l = l->next) - { - GIrNode *member = (GIrNode *)l->data; - - if (member->type == G_IR_NODE_FUNCTION) - { - blob->n_methods++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); - } - } + g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, + module, modules, strings, + types, data, offset, offset2); + + g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, + module, modules, strings, + types, data, offset, offset2); + + g_list_free (members); } break; @@ -1653,6 +1673,7 @@ g_ir_node_build_typelib (GIrNode *node, { StructBlob *blob = (StructBlob *)&data[*offset]; GIrNodeBoxed *boxed = (GIrNodeBoxed *)node; + GList *members; blob->blob_type = BLOB_TYPE_BOXED; blob->deprecated = boxed->deprecated; @@ -1666,29 +1687,18 @@ g_ir_node_build_typelib (GIrNode *node, blob->n_methods = 0; *offset += 20; - for (l = boxed->members; l; l = l->next) - { - GIrNode *member = (GIrNode *)l->data; - if (member->type == G_IR_NODE_FIELD) - { - blob->n_fields++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); - } - } + members = g_list_copy (boxed->members); - for (l = boxed->members; l; l = l->next) - { - GIrNode *member = (GIrNode *)l->data; + g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, + module, modules, strings, + types, data, offset, offset2); - if (member->type == G_IR_NODE_FUNCTION) - { - blob->n_methods++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); - } - } + g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, + module, modules, strings, + types, data, offset, offset2); + + g_list_free (members); } break; @@ -1696,6 +1706,7 @@ g_ir_node_build_typelib (GIrNode *node, { UnionBlob *blob = (UnionBlob *)&data[*offset]; GIrNodeUnion *union_ = (GIrNodeUnion *)node; + GList *members; blob->blob_type = BLOB_TYPE_UNION; blob->deprecated = union_->deprecated; @@ -1734,30 +1745,17 @@ g_ir_node_build_typelib (GIrNode *node, blob->discriminator_type.offset = 0; } - - for (l = union_->members; l; l = l->next) - { - GIrNode *member = (GIrNode *)l->data; + members = g_list_copy (union_->members); - if (member->type == G_IR_NODE_FIELD) - { - blob->n_fields++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); - } - } + g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, + module, modules, strings, + types, data, offset, offset2); - for (l = union_->members; l; l = l->next) - { - GIrNode *member = (GIrNode *)l->data; + g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_functions, + module, modules, strings, + types, data, offset, offset2); - if (member->type == G_IR_NODE_FUNCTION) - { - blob->n_functions++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); - } - } + g_list_free (members); if (union_->discriminator_type) { @@ -1819,6 +1817,7 @@ g_ir_node_build_typelib (GIrNode *node, { ObjectBlob *blob = (ObjectBlob *)&data[*offset]; GIrNodeInterface *object = (GIrNodeInterface *)node; + GList *members; blob->blob_type = BLOB_TYPE_OBJECT; blob->deprecated = object->deprecated; @@ -1847,83 +1846,39 @@ g_ir_node_build_typelib (GIrNode *node, *offset += 2; } - *offset = ALIGN_VALUE (*offset, 4); - for (l = object->members; l; l = l->next) - { - GIrNode *member = (GIrNode *)l->data; - - if (member->type == G_IR_NODE_FIELD) - { - blob->n_fields++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); - } - } + members = g_list_copy (object->members); *offset = ALIGN_VALUE (*offset, 4); - for (l = object->members; l; l = l->next) - { - GIrNode *member = (GIrNode *)l->data; - - if (member->type == G_IR_NODE_PROPERTY) - { - blob->n_properties++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); - } - } + g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, + module, modules, strings, + types, data, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); - for (l = object->members; l; l = l->next) - { - GIrNode *member = (GIrNode *)l->data; - - if (member->type == G_IR_NODE_FUNCTION) - { - blob->n_methods++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); - } - } + g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties, + module, modules, strings, + types, data, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); - for (l = object->members; l; l = l->next) - { - GIrNode *member = (GIrNode *)l->data; - - if (member->type == G_IR_NODE_SIGNAL) - { - blob->n_signals++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); - } - } + g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, + module, modules, strings, + types, data, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); - for (l = object->members; l; l = l->next) - { - GIrNode *member = (GIrNode *)l->data; - - if (member->type == G_IR_NODE_VFUNC) - { - blob->n_vfuncs++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); - } - } + g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals, + module, modules, strings, + types, data, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); - for (l = object->members; l; l = l->next) - { - GIrNode *member = (GIrNode *)l->data; + g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs, + module, modules, strings, + types, data, offset, offset2); - if (member->type == G_IR_NODE_CONSTANT) - { - blob->n_constants++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); - } - } + *offset = ALIGN_VALUE (*offset, 4); + g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants, + module, modules, strings, + types, data, offset, offset2); + + g_list_free (members); } break; @@ -1931,6 +1886,7 @@ g_ir_node_build_typelib (GIrNode *node, { InterfaceBlob *blob = (InterfaceBlob *)&data[*offset]; GIrNodeInterface *iface = (GIrNodeInterface *)node; + GList *members; blob->blob_type = BLOB_TYPE_INTERFACE; blob->deprecated = iface->deprecated; @@ -1953,70 +1909,34 @@ g_ir_node_build_typelib (GIrNode *node, *offset += 2; } - *offset = ALIGN_VALUE (*offset, 4); - for (l = iface->members; l; l = l->next) - { - GIrNode *member = (GIrNode *)l->data; - - if (member->type == G_IR_NODE_PROPERTY) - { - blob->n_properties++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); - } - } + members = g_list_copy (iface->members); *offset = ALIGN_VALUE (*offset, 4); - for (l = iface->members; l; l = l->next) - { - GIrNode *member = (GIrNode *)l->data; - - if (member->type == G_IR_NODE_FUNCTION) - { - blob->n_methods++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); - } - } + g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties, + module, modules, strings, + types, data, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); - for (l = iface->members; l; l = l->next) - { - GIrNode *member = (GIrNode *)l->data; - - if (member->type == G_IR_NODE_SIGNAL) - { - blob->n_signals++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); - } - } + g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, + module, modules, strings, + types, data, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); - for (l = iface->members; l; l = l->next) - { - GIrNode *member = (GIrNode *)l->data; - - if (member->type == G_IR_NODE_VFUNC) - { - blob->n_vfuncs++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); - } - } + g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals, + module, modules, strings, + types, data, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); - for (l = iface->members; l; l = l->next) - { - GIrNode *member = (GIrNode *)l->data; + g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs, + module, modules, strings, + types, data, offset, offset2); - if (member->type == G_IR_NODE_CONSTANT) - { - blob->n_constants++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); - } - } + *offset = ALIGN_VALUE (*offset, 4); + g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants, + module, modules, strings, + types, data, offset, offset2); + + g_list_free (members); } break; From cab23be329e72a748d01700485fbed25e078460b Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Wed, 15 Oct 2008 22:28:53 +0000 Subject: [PATCH 121/692] =?UTF-8?q?Bug=20556434=20=E2=80=93=20unhandled=20?= =?UTF-8?q?interface/object/...=20member=20types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-10-15 Tommi Komulainen Bug 556434 – unhandled interface/object/... member types * girepository/girnode.c (g_ir_node_check_unhandled_members, g_ir_node_build_typelib): Check all interface/object/boxed/struct/union members are processed and abort if they are not. (Mostly callbacks in structs, but also fields in interfaces.) svn path=/trunk/; revision=722 --- girnode.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/girnode.c b/girnode.c index 1b569518d..929465204 100644 --- a/girnode.c +++ b/girnode.c @@ -1197,6 +1197,33 @@ g_ir_node_build_members (GList **members, } } +static void +g_ir_node_check_unhandled_members (GList **members, + GIrNodeTypeId container_type) +{ + if (*members) + { + GList *l; + + for (l = *members; l; l = l->next) + { + GIrNode *member = (GIrNode *)l->data; + + g_printerr ("Unhandled '%s' member '%s' type '%s'\n", + g_ir_node_type_to_string (container_type), + member->name, + g_ir_node_type_to_string (member->type)); + } + + g_list_free (*members); + *members = NULL; + + /* Commented out for now to not break the build. + g_error ("Unhandled members. Aborting."); + */ + } +} + void g_ir_node_build_typelib (GIrNode *node, GIrModule *module, @@ -1665,7 +1692,9 @@ g_ir_node_build_typelib (GIrNode *node, module, modules, strings, types, data, offset, offset2); - g_list_free (members); + g_ir_node_check_unhandled_members (&members, node->type); + + g_assert (members == NULL); } break; @@ -1698,7 +1727,9 @@ g_ir_node_build_typelib (GIrNode *node, module, modules, strings, types, data, offset, offset2); - g_list_free (members); + g_ir_node_check_unhandled_members (&members, node->type); + + g_assert (members == NULL); } break; @@ -1755,7 +1786,9 @@ g_ir_node_build_typelib (GIrNode *node, module, modules, strings, types, data, offset, offset2); - g_list_free (members); + g_ir_node_check_unhandled_members (&members, node->type); + + g_assert (members == NULL); if (union_->discriminator_type) { @@ -1878,7 +1911,9 @@ g_ir_node_build_typelib (GIrNode *node, module, modules, strings, types, data, offset, offset2); - g_list_free (members); + g_ir_node_check_unhandled_members (&members, node->type); + + g_assert (members == NULL); } break; @@ -1936,7 +1971,9 @@ g_ir_node_build_typelib (GIrNode *node, module, modules, strings, types, data, offset, offset2); - g_list_free (members); + g_ir_node_check_unhandled_members (&members, node->type); + + g_assert (members == NULL); } break; From 7db23628b051dcf442fb59906ebe94a0c37f05d9 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 16 Oct 2008 01:40:29 +0000 Subject: [PATCH 122/692] Merge branch 'bug556331-includecleanup' svn path=/trunk/; revision=724 --- girepository.c | 2 +- girparser.c | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/girepository.c b/girepository.c index 6d4011400..04c32c3b1 100644 --- a/girepository.c +++ b/girepository.c @@ -1060,7 +1060,7 @@ g_irepository_require (GIRepository *repository, if (version != NULL) g_set_error (error, G_IREPOSITORY_ERROR, G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, - "Typelib file %s for namespace '%s', version '%s' not found", + "Typelib file for namespace '%s', version '%s' not found", namespace, version); else g_set_error (error, G_IREPOSITORY_ERROR, diff --git a/girparser.c b/girparser.c index 35f882bea..0b9e6199c 100644 --- a/girparser.c +++ b/girparser.c @@ -130,7 +130,7 @@ static GMarkupParser firstpass_parser = }; static char * -locate_gir (const char *name, const char * const* extra_paths) +locate_gir (const char *name, const char *version, const char * const* extra_paths) { const gchar *const *datadirs; const gchar *const *dir; @@ -141,7 +141,7 @@ locate_gir (const char *name, const char * const* extra_paths) datadirs = g_get_system_data_dirs (); - girname = g_strdup_printf ("%s.gir", name); + girname = g_strdup_printf ("%s-%s.gir", name, version); for (dir = datadirs; *dir; dir++) { @@ -981,7 +981,6 @@ start_alias (GMarkupParseContext *context, { key = g_strdup (name); } - g_hash_table_insert (ctx->aliases, key, value); return TRUE; @@ -2048,6 +2047,7 @@ static gboolean parse_include (GMarkupParseContext *context, ParseContext *ctx, const char *name, + const char *version, GError **error) { ParseContext sub_ctx = { 0 }; @@ -2056,7 +2056,7 @@ parse_include (GMarkupParseContext *context, gsize length; char *girpath; - girpath = locate_gir (name, ctx->includes); + girpath = locate_gir (name, version, ctx->includes); if (girpath == NULL) { @@ -2231,19 +2231,27 @@ start_element_handler (GMarkupParseContext *context, ctx->state == STATE_REPOSITORY) { const gchar *name; - + const gchar *version; + name = find_attribute ("name", attribute_names, attribute_values); + version = find_attribute ("version", attribute_names, attribute_values); if (name == NULL) { MISSING_ATTRIBUTE (context, error, element_name, "name"); break; } + if (version == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "version"); + break; + } - if (!parse_include (context, ctx, name, error)) + if (!parse_include (context, ctx, name, version, error)) break; - ctx->dependencies = g_list_prepend (ctx->dependencies, g_strdup (name)); + ctx->dependencies = g_list_prepend (ctx->dependencies, + g_strdup_printf ("%s-%s", name, version)); state_switch (ctx, STATE_INCLUDE); From e8c772bdb64f3bef1ed4afe9013ffac285c71fa8 Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Thu, 16 Oct 2008 17:07:00 +0000 Subject: [PATCH 123/692] =?UTF-8?q?Bug=20556541=20=E2=80=93=20access=20uni?= =?UTF-8?q?on=20members=20through=20UnionBlob=20rather=20than?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-10-16 Tommi Komulainen Bug 556541 – access union members through UnionBlob rather than StructBlob * girepository/ginfo.c (g_union_info_find_method): access union members through UnionBlob rather than StructBlob svn path=/trunk/; revision=729 --- ginfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ginfo.c b/ginfo.c index aa03bc30b..86e2ed687 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1846,11 +1846,11 @@ g_union_info_find_method (GIUnionInfo *info, gint offset; GIBaseInfo *base = (GIBaseInfo *)info; Header *header = (Header *)base->typelib->data; - StructBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; + UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; offset = base->offset + header->union_blob_size + blob->n_fields * header->field_blob_size; - return find_method (base, offset, blob->n_methods, name); + return find_method (base, offset, blob->n_functions, name); } From 4fb5b001bb88f410bb3832cdd3af4da5ce07c1df Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Thu, 16 Oct 2008 17:07:05 +0000 Subject: [PATCH 124/692] =?UTF-8?q?Bug=20556543=20=E2=80=93=20reduce=20com?= =?UTF-8?q?piler=20warnings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-10-16 Tommi Komulainen Bug 556543 – reduce compiler warnings * girepository/ginfo.c: * girepository/girepository.c (register_internal, count_interfaces, find_interface, find_namespace_version, parse_version, g_irepository_require): * girepository/girmodule.c (g_ir_module_build_typelib): * girepository/girnode.c (init_stats, dump_stats, _g_irnode_init_stats, _g_irnode_dump_stats, g_ir_node_can_have_member): * girepository/girparser.c (firstpass_end_element_handler, locate_gir, parse_basic, parse_type_internal, resolve_aliases, start_alias, start_type, end_type_top, parse_include, cleanup, post_filter): * girepository/gtypelib.c (validate_function_blob, validate_enum_blob): * giscanner/giscannermodule.c (directive_get_options, type_get_child_list): * giscanner/scannerlexer.l (parse_gtkdoc): * giscanner/scannerparser.y (ctype_free): * giscanner/sourcescanner.c: * giscanner/sourcescanner.h (gi_source_scanner_parse_macros): * tests/types/gitesttypes.c: * tools/compiler.c (main): * tools/generate.c (write_repository): Remove unused variables and code, add missing includes, declarations and case statements. svn path=/trunk/; revision=730 --- ginfo.c | 1 + girepository.c | 25 +++---------------------- girmodule.c | 7 +++++-- girnode.c | 23 +++++++++++++++++++++-- girparser.c | 41 ++++++++++++++++++++++++----------------- gtypelib.c | 4 +--- 6 files changed, 55 insertions(+), 46 deletions(-) diff --git a/ginfo.c b/ginfo.c index 86e2ed687..ccb1760a9 100644 --- a/ginfo.c +++ b/ginfo.c @@ -19,6 +19,7 @@ */ #include +#include #include #include diff --git a/girepository.c b/girepository.c index 04c32c3b1..286417de6 100644 --- a/girepository.c +++ b/girepository.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -261,8 +262,6 @@ register_internal (GIRepository *repository, Header *header; const gchar *namespace; const gchar *version; - gboolean was_loaded; - gboolean currently_lazy; g_return_val_if_fail (typelib != NULL, FALSE); @@ -418,17 +417,6 @@ g_irepository_get_default (void) return get_repository (NULL); } -static void -count_interfaces (gpointer key, - gpointer value, - gpointer data) -{ - guchar *typelib = ((GTypelib *) value)->data; - gint *n_interfaces = (gint *)data; - - *n_interfaces += ((Header *)typelib)->n_local_entries; -} - /** * g_irepository_get_n_infos * @repository: A #GIRepository, may be %NULL for the default @@ -478,7 +466,6 @@ find_interface (gpointer key, IfaceData *iface_data = (IfaceData *)data; gint index; gint n_entries; - guint32 offset; const gchar *name; const gchar *type; DirEntry *entry; @@ -804,7 +791,6 @@ find_namespace_version (const gchar *namespace, for (ldir = search_path; ldir; ldir = ldir->next) { - Header *header; char *path = g_build_filename (ldir->data, fname, NULL); mfile = g_mapped_file_new (path, FALSE, &error); @@ -827,7 +813,7 @@ parse_version (const char *version, int *minor) { const char *dot; - const char *end; + char *end; *major = strtol (version, &end, 10); dot = strchr (version, '.'); @@ -1012,15 +998,11 @@ g_irepository_require (GIRepository *repository, GIRepositoryLoadFlags flags, GError **error) { - const char *dir; GMappedFile *mfile; gboolean ret = FALSE; - GError *error1 = NULL; Header *header; GTypelib *typelib = NULL; - const gchar *typelib_namespace, *typelib_version, *shlib_fname; - GModule *module; - guint32 shlib; + const gchar *typelib_namespace, *typelib_version; gboolean allow_lazy = (flags & G_IREPOSITORY_LOAD_FLAG_LAZY) > 0; gboolean is_lazy; char *version_conflict = NULL; @@ -1056,7 +1038,6 @@ g_irepository_require (GIRepository *repository, if (mfile == NULL) { - const char *error_fmt; if (version != NULL) g_set_error (error, G_IREPOSITORY_ERROR, G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, diff --git a/girmodule.c b/girmodule.c index ad0ecf542..382d186ee 100644 --- a/girmodule.c +++ b/girmodule.c @@ -24,6 +24,9 @@ #include "girmodule.h" #include "girnode.h" +void _g_irnode_init_stats (void); +void _g_irnode_dump_stats (void); + #define ALIGN_VALUE(this, boundary) \ (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) @@ -111,7 +114,7 @@ g_ir_module_build_typelib (GIrModule *module, } restart: - init_stats (); + _g_irnode_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); @@ -243,7 +246,7 @@ g_ir_module_build_typelib (GIrModule *module, entry++; } - dump_stats (); + _g_irnode_dump_stats (); header->annotations = offset2; diff --git a/girnode.c b/girnode.c index 929465204..f4f337a7e 100644 --- a/girnode.c +++ b/girnode.c @@ -34,7 +34,7 @@ static gulong types_count = 0; static gulong unique_types_count = 0; void -init_stats (void) +_g_irnode_init_stats (void) { string_count = 0; unique_string_count = 0; @@ -45,7 +45,7 @@ init_stats (void) } void -dump_stats (void) +_g_irnode_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); @@ -870,6 +870,25 @@ g_ir_node_can_have_member (GIrNode *node) case G_IR_NODE_STRUCT: case G_IR_NODE_UNION: return TRUE; + /* list others individually rather than with default: so that compiler + * warns if new node types are added without adding them to the switch + */ + case G_IR_NODE_INVALID: + case G_IR_NODE_FUNCTION: + case G_IR_NODE_CALLBACK: + case G_IR_NODE_ENUM: + case G_IR_NODE_FLAGS: + case G_IR_NODE_CONSTANT: + case G_IR_NODE_ERROR_DOMAIN: + case G_IR_NODE_PARAM: + case G_IR_NODE_TYPE: + case G_IR_NODE_PROPERTY: + case G_IR_NODE_SIGNAL: + case G_IR_NODE_VALUE: + case G_IR_NODE_VFUNC: + case G_IR_NODE_FIELD: + case G_IR_NODE_XREF: + return FALSE; }; return FALSE; } diff --git a/girparser.c b/girparser.c index 0b9e6199c..249aa1b31 100644 --- a/girparser.c +++ b/girparser.c @@ -116,8 +116,6 @@ firstpass_end_element_handler (GMarkupParseContext *context, gpointer user_data, GError **error) { - ParseContext *ctx = user_data; - } static GMarkupParser firstpass_parser = @@ -136,8 +134,6 @@ locate_gir (const char *name, const char *version, const char * const* extra_pat const gchar *const *dir; char *girname; char *path = NULL; - GSList *link; - gboolean firstpass = TRUE; datadirs = g_get_system_data_dirs (); @@ -267,9 +263,6 @@ parse_basic (const char *str) { gint i; gint n_basic = G_N_ELEMENTS (basic_types); - gchar *temporary_type = NULL; - const gchar *start; - const gchar *end; for (i = 0; i < n_basic; i++) { @@ -414,7 +407,7 @@ parse_type_internal (const gchar *str, char **next, gboolean in_glib, g_free (temporary_type); return type; - error: +/* error: */ g_ir_node_free ((GIrNode *)type); g_free (temporary_type); return NULL; @@ -430,7 +423,7 @@ resolve_aliases (ParseContext *ctx, const gchar *type) seen_values = g_slist_prepend (seen_values, (char*)type); while (g_hash_table_lookup_extended (ctx->aliases, type, &orig, &value)) { - g_debug ("Resolved: %s => %s", type, value); + g_debug ("Resolved: %s => %s", type, (char*)value); type = value; if (g_slist_find_custom (seen_values, type, (GCompareFunc)strcmp) != NULL) @@ -444,11 +437,9 @@ resolve_aliases (ParseContext *ctx, const gchar *type) static GIrNodeType * parse_type (ParseContext *ctx, const gchar *type) { - gchar *str; GIrNodeType *node; const BasicTypeInfo *basic; gboolean in_glib, in_gobject; - gboolean matched_special = FALSE; in_glib = strcmp (ctx->namespace, "GLib") == 0; in_gobject = strcmp (ctx->namespace, "GObject") == 0; @@ -944,7 +935,6 @@ start_alias (GMarkupParseContext *context, { const gchar *name; const gchar *target; - const gchar *type; char *key; char *value; @@ -1474,6 +1464,28 @@ start_type (GMarkupParseContext *context, vfunc->is_varargs = TRUE; } break; + /* list others individually rather than with default: so that compiler + * warns if new node types are added without adding them to the switch + */ + case G_IR_NODE_INVALID: + case G_IR_NODE_ENUM: + case G_IR_NODE_FLAGS: + case G_IR_NODE_CONSTANT: + case G_IR_NODE_ERROR_DOMAIN: + case G_IR_NODE_PARAM: + case G_IR_NODE_TYPE: + case G_IR_NODE_PROPERTY: + case G_IR_NODE_SIGNAL: + case G_IR_NODE_VALUE: + case G_IR_NODE_FIELD: + case G_IR_NODE_XREF: + case G_IR_NODE_STRUCT: + case G_IR_NODE_BOXED: + case G_IR_NODE_OBJECT: + case G_IR_NODE_INTERFACE: + case G_IR_NODE_UNION: + g_assert_not_reached (); + break; } } ctx->type_stack = NULL; @@ -1496,7 +1508,6 @@ start_type (GMarkupParseContext *context, { const char *zero; const char *len; - int i; typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE); @@ -1604,7 +1615,6 @@ end_type_top (ParseContext *ctx) static void end_type_recurse (ParseContext *ctx) { - GList *types; GIrNodeType *parent; GIrNodeType *param = NULL; @@ -2051,7 +2061,6 @@ parse_include (GMarkupParseContext *context, GError **error) { ParseContext sub_ctx = { 0 }; - GMarkupParseContext *sub_context; gchar *buffer; gsize length; char *girpath; @@ -2748,7 +2757,6 @@ cleanup (GMarkupParseContext *context, { ParseContext *ctx = user_data; GList *m; - int line_number, char_number; for (m = ctx->modules; m; m = m->next) g_ir_module_free (m->data); @@ -2800,7 +2808,6 @@ post_filter (GIrModule *module) iter = module->entries; while (iter) { - GList *link = iter; GIrNode *node = iter->data; iter = iter->next; diff --git a/gtypelib.c b/gtypelib.c index 7a7a31f07..1d3598380 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -808,7 +808,6 @@ validate_function_blob (ValidateContext *ctx, blob->signature, error); InterfaceTypeBlob *iface_type; - InterfaceBlob *iface; if (!simple) return FALSE; @@ -1281,8 +1280,7 @@ validate_enum_blob (ValidateContext *ctx, { GTypelib *typelib = ctx->typelib; EnumBlob *blob; - ValueBlob *v1, *v2; - gint i, j; + gint i; if (typelib->len < offset + sizeof (EnumBlob)) { From 0fa82c6a4cbfcb27ea72628d338399ac37b72e03 Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Fri, 17 Oct 2008 14:58:37 +0000 Subject: [PATCH 125/692] =?UTF-8?q?Bug=20556732=20=E2=80=93=20generate=20g?= =?UTF-8?q?ir=20files=20consistently?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-10-17 Tommi Komulainen Bug 556732 – generate gir files consistently * giscanner/ast.py (Field): add readable and writable properties * giscanner/girparser.py (_parse_field): copy 'readable' and 'writable' attributes * giscanner/transformer.py (_create_member): create fields as read-write * giscanner/glibtransformer.py (_introspect_object, _pair_class_struct): make object instance and class fields read-only * giscanner/girwriter.py (_write_field): * tools/generate.c (write_field_info): write field 'readable' and 'writable' attributes only if non-default (read-only) * girepository/girparser.c (start_field): in the absence of attributes assume fields are read-only * tests/boxed.gir: * tests/struct.gir: remove redundant readable="1" from fields * tests/scanner/foo-1.0-expected.gir: * tests/scanner/utility-1.0-expected.gir: add writable="1" to all record and union fields svn path=/trunk/; revision=743 --- girparser.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/girparser.c b/girparser.c index 249aa1b31..8dea9095c 100644 --- a/girparser.c +++ b/girparser.c @@ -839,15 +839,11 @@ start_field (GMarkupParseContext *context, field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD); ctx->current_typed = (GIrNode*) field; ((GIrNode *)field)->name = g_strdup (name); - if (readable && strcmp (readable, "1") == 0) - field->readable = TRUE; - else - field->readable = FALSE; - - if (writable && strcmp (writable, "1") == 0) - field->writable = TRUE; - else - field->writable = FALSE; + /* Fields are assumed to be read-only. + * (see also girwriter.py and generate.c) + */ + field->readable = readable == NULL || strcmp (readable, "0") == 0; + field->writable = writable != NULL && strcmp (writable, "1") == 0; if (bits) field->bits = atoi (bits); From 0de03983be90987a3ed4b7377cf2da8386779d15 Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Fri, 17 Oct 2008 14:59:23 +0000 Subject: [PATCH 126/692] =?UTF-8?q?Bug=20556732=20=E2=80=93=20generate=20g?= =?UTF-8?q?ir=20files=20consistently?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-10-17 Tommi Komulainen Bug 556732 – generate gir files consistently * girepository/girparser.c (start_parameter): * tests/boxed.gir: * tests/invoke/testfns-1.0.gir: * tools/generate.c (write_callable_info): write 'transfer-ownership' attribute consistently with both return-value and parameter elements svn path=/trunk/; revision=745 --- girparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index 8dea9095c..f5bd7ccab 100644 --- a/girparser.c +++ b/girparser.c @@ -706,7 +706,7 @@ start_parameter (GMarkupParseContext *context, dipper = find_attribute ("dipper", attribute_names, attribute_values); optional = find_attribute ("optional", attribute_names, attribute_values); nullok = find_attribute ("null-ok", attribute_names, attribute_values); - transfer = find_attribute ("transfer", attribute_names, attribute_values); + transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); if (name == NULL) name = "unknown"; From c3330c06c74f8fadaeca7c684622166b1aa2ebb4 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 20 Oct 2008 17:04:17 +0000 Subject: [PATCH 127/692] Bug 557011 - Add g_object_info_get_abstract svn path=/trunk/; revision=757 --- ginfo.c | 8 ++++++++ girepository.h | 1 + girnode.c | 1 + girnode.h | 1 + girparser.c | 6 +++++- gtypelib.h | 9 +++++---- 6 files changed, 21 insertions(+), 5 deletions(-) diff --git a/ginfo.c b/ginfo.c index ccb1760a9..c165ade0a 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1123,6 +1123,14 @@ g_object_info_get_parent (GIObjectInfo *info) return NULL; } +gboolean +g_object_info_get_abstract (GIObjectInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + return blob->abstract != 0; +} + const gchar * g_object_info_get_type_name (GIObjectInfo *info) { diff --git a/girepository.h b/girepository.h index 42db8d33c..2e6c5c8d5 100644 --- a/girepository.h +++ b/girepository.h @@ -392,6 +392,7 @@ GIValueInfo * g_enum_info_get_value (GIEnumInfo *in const gchar * g_object_info_get_type_name (GIObjectInfo *info); const gchar * g_object_info_get_type_init (GIObjectInfo *info); +gboolean g_object_info_get_abstract (GIObjectInfo *info); GIObjectInfo * g_object_info_get_parent (GIObjectInfo *info); gint g_object_info_get_n_interfaces (GIObjectInfo *info); GIInterfaceInfo * g_object_info_get_interface (GIObjectInfo *info, diff --git a/girnode.c b/girnode.c index f4f337a7e..ee1af3b37 100644 --- a/girnode.c +++ b/girnode.c @@ -1872,6 +1872,7 @@ g_ir_node_build_typelib (GIrNode *node, GList *members; blob->blob_type = BLOB_TYPE_OBJECT; + blob->abstract = object->abstract; blob->deprecated = object->deprecated; blob->reserved = 0; blob->name = write_string (node->name, strings, data, offset2); diff --git a/girnode.h b/girnode.h index eba8c6b96..905bf90a1 100644 --- a/girnode.h +++ b/girnode.h @@ -212,6 +212,7 @@ struct _GIrNodeInterface { GIrNode node; + gboolean abstract; gboolean deprecated; gchar *gtype_name; diff --git a/girparser.c b/girparser.c index f5bd7ccab..539d68d2e 100644 --- a/girparser.c +++ b/girparser.c @@ -1362,12 +1362,14 @@ start_class (GMarkupParseContext *context, const gchar *typename; const gchar *typeinit; const gchar *deprecated; + const gchar *abstract; name = find_attribute ("name", attribute_names, attribute_values); parent = find_attribute ("parent", attribute_names, attribute_values); typename = find_attribute ("glib:type-name", attribute_names, attribute_values); typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + abstract = find_attribute ("abstract", attribute_names, attribute_values); if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); @@ -1388,7 +1390,9 @@ start_class (GMarkupParseContext *context, iface->deprecated = TRUE; else iface->deprecated = FALSE; - + + iface->abstract = abstract && strcmp (abstract, "1") == 0; + ctx->current_node = (GIrNode *) iface; ctx->current_module->entries = g_list_append (ctx->current_module->entries, iface); diff --git a/gtypelib.h b/gtypelib.h index 54bf0523c..443d34b6c 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -407,9 +407,10 @@ typedef struct typedef struct { guint16 blob_type; /* 7 */ - guint16 deprecated : 1; - guint16 reserved :15; - guint32 name; + guint16 deprecated : 1; + guint16 abstract : 1; + guint16 reserved :14; + guint32 name; guint32 gtype_name; guint32 gtype_init; @@ -440,7 +441,7 @@ typedef struct typedef struct { guint16 blob_type; - guint16 deprecated : 1; + guint16 deprecated : 1; guint16 reserved :15; guint32 name; From 727bb018050de3af2107802d626ba3a5d594bcff Mon Sep 17 00:00:00 2001 From: Johan Bilien Date: Tue, 21 Oct 2008 17:04:11 +0000 Subject: [PATCH 128/692] =?UTF-8?q?Bug=20557241=20=E2=80=93=20"throws"=20f?= =?UTF-8?q?lag=20for=20functions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-10-21 Johan Bilien Bug 557241 – "throws" flag for functions * tests/scanner/drawable-1.0-expected.gir, tests/scanner/drawable-injected-1.0-expected.gir, tests/scanner/drawable.[ch]: add simple test for throwing function (has GError ** as last argument) * giscanner/ast.py: add a 'throws' flag to Function * giscanner/glibtransformer.py: if a function's last paramerter is a GError, set the 'throws' flag and remove that parameter * giscanner/girwriter.py: write out the 'throws' attribute * giscanner/girparser.py: support parsing the 'throws' attribute * tests/repository/gitestthrows.c: add a simple test to check the throws flag in a typelib and invoke the function * girepository/ginfo.c, girepository/girnode.[ch], girepository/girnode.h, girepository/girparser.c, girepository/girepository.h: Add and parse the GI_FUNCTION_THROWS flag * girepository/ginvoke.c: if a function throws, add a GError as last arguments, and propagate the error to the invoker. svn path=/trunk/; revision=773 --- ginfo.c | 3 +++ ginvoke.c | 27 ++++++++++++++++++++++++++- girepository.h | 3 ++- girnode.c | 2 +- girnode.h | 1 + girparser.c | 9 ++++++++- gtypelib.h | 4 ++-- 7 files changed, 43 insertions(+), 6 deletions(-) diff --git a/ginfo.c b/ginfo.c index c165ade0a..fc265ad19 100644 --- a/ginfo.c +++ b/ginfo.c @@ -492,6 +492,9 @@ g_function_info_get_flags (GIFunctionInfo *info) if (blob->wraps_vfunc) flags = flags | GI_FUNCTION_WRAPS_VFUNC; + if (blob->throws) + flags = flags | GI_FUNCTION_THROWS; + return flags; } diff --git a/ginvoke.c b/ginvoke.c index d5182dbf7..2626a956d 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -159,9 +159,11 @@ g_function_info_invoke (GIFunctionInfo *info, GITypeInfo *tinfo; GIArgInfo *ainfo; gboolean is_method; + gboolean throws; gint n_args, n_invoke_args, in_pos, out_pos, i; gpointer *args; gboolean success = FALSE; + GError *local_error; symbol = g_function_info_get_symbol (info); @@ -178,6 +180,7 @@ g_function_info_invoke (GIFunctionInfo *info, is_method = (g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0 && (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR) == 0; + throws = g_function_info_get_flags (info) & GI_FUNCTION_THROWS; tinfo = g_callable_info_get_return_type ((GICallableInfo *)info); rtype = get_ffi_type (tinfo); @@ -202,6 +205,11 @@ g_function_info_invoke (GIFunctionInfo *info, } else n_invoke_args = n_args; + + if (throws) + /* Add an argument for the GError */ + n_invoke_args ++; + atypes = g_alloca (sizeof (ffi_type*) * n_invoke_args); args = g_alloca (sizeof (gpointer) * n_invoke_args); @@ -279,6 +287,15 @@ g_function_info_invoke (GIFunctionInfo *info, } g_base_info_unref ((GIBaseInfo *)ainfo); } + + local_error = NULL; + if (throws) + { + gpointer address = &local_error; + args[n_invoke_args - 1] = &address; + atypes[n_invoke_args - 1] = &ffi_type_pointer; + } + if (in_pos < n_in_args) { g_set_error (error, @@ -301,7 +318,15 @@ g_function_info_invoke (GIFunctionInfo *info, ffi_call (&cif, func, return_value, args); - success = TRUE; + if (local_error) + { + g_propagate_error (error, local_error); + success = FALSE; + } + else + { + success = TRUE; + } out: return success; } diff --git a/girepository.h b/girepository.h index 2e6c5c8d5..1ab326b7a 100644 --- a/girepository.h +++ b/girepository.h @@ -190,7 +190,8 @@ typedef enum GI_FUNCTION_IS_CONSTRUCTOR = 1 << 1, GI_FUNCTION_IS_GETTER = 1 << 2, GI_FUNCTION_IS_SETTER = 1 << 3, - GI_FUNCTION_WRAPS_VFUNC = 1 << 4 + GI_FUNCTION_WRAPS_VFUNC = 1 << 4, + GI_FUNCTION_THROWS = 1 << 5 } GIFunctionInfoFlags; const gchar * g_function_info_get_symbol (GIFunctionInfo *info); diff --git a/girnode.c b/girnode.c index ee1af3b37..e6fc799d9 100644 --- a/girnode.c +++ b/girnode.c @@ -1477,7 +1477,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->getter = function->is_getter; blob->constructor = function->is_constructor; blob->wraps_vfunc = function->wraps_vfunc; - blob->reserved = 0; + blob->throws = function->throws; blob->index = 0; blob->name = write_string (node->name, strings, data, offset2); blob->symbol = write_string (function->symbol, strings, data, offset2); diff --git a/girnode.h b/girnode.h index 905bf90a1..0ef95df72 100644 --- a/girnode.h +++ b/girnode.h @@ -92,6 +92,7 @@ struct _GIrNodeFunction gboolean is_getter; gboolean is_constructor; gboolean wraps_vfunc; + gboolean throws; gchar *symbol; diff --git a/girparser.c b/girparser.c index 539d68d2e..fb5b68bee 100644 --- a/girparser.c +++ b/girparser.c @@ -527,6 +527,7 @@ start_function (GMarkupParseContext *context, const gchar *name; const gchar *symbol; const gchar *deprecated; + const gchar *throws; GIrNodeFunction *function; gboolean found = FALSE; @@ -557,6 +558,7 @@ start_function (GMarkupParseContext *context, name = find_attribute ("name", attribute_names, attribute_values); symbol = find_attribute ("c:identifier", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + throws = find_attribute ("throws", attribute_names, attribute_values); if (name == NULL) { @@ -598,7 +600,12 @@ start_function (GMarkupParseContext *context, if (strcmp (element_name, "callback") == 0) ((GIrNode *)function)->type = G_IR_NODE_CALLBACK; } - + + if (throws && strcmp (throws, "1") == 0) + function->throws = TRUE; + else + function->throws = FALSE; + if (ctx->current_node == NULL) { ctx->current_module->entries = diff --git a/gtypelib.h b/gtypelib.h index 443d34b6c..8bb877779 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -166,11 +166,11 @@ typedef struct guint16 blob_type; /* 1 */ guint16 deprecated : 1; - guint16 setter : 1; + guint16 setter : 1; guint16 getter : 1; guint16 constructor : 1; guint16 wraps_vfunc : 1; - guint16 reserved : 1; + guint16 throws : 1; guint16 index :10; guint32 name; From adc6a3e2efdc0e16a0f68dbdee5c7fc32d1e9eb9 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 21 Oct 2008 18:41:36 +0000 Subject: [PATCH 129/692] Respect path ordering for unversioned requires svn path=/trunk/; revision=778 --- girepository.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/girepository.c b/girepository.c index 286417de6..b43a451b1 100644 --- a/girepository.c +++ b/girepository.c @@ -858,6 +858,7 @@ compare_version (const char *v1, struct NamespaceVersionCandidadate { GMappedFile *mfile; + int path_index; char *path; char *version; }; @@ -867,12 +868,24 @@ compare_candidate_reverse (struct NamespaceVersionCandidadate *c1, struct NamespaceVersionCandidadate *c2) { int result = compare_version (c1->version, c2->version); + /* First, check the version */ if (result > 0) return -1; else if (result < 0) return 1; - else - return 0; + else + { + /* Now check the path index, which says how early in the search path + * we found it. This ensures that of equal version targets, we + * pick the earlier one. + */ + if (c1->path_index == c2->path_index) + return 0; + else if (c1->path_index > c2->path_index) + return 1; + else + return -1; + } } static void @@ -895,13 +908,15 @@ find_namespace_latest (const gchar *namespace, char *namespace_typelib; GSList *candidates = NULL; GMappedFile *result = NULL; + int index; *version_ret = NULL; *path_ret = NULL; namespace_dash = g_strdup_printf ("%s-", namespace); namespace_typelib = g_strdup_printf ("%s.typelib", namespace); - + + index = 0; for (ldir = search_path; ldir; ldir = ldir->next) { GDir *dir; @@ -947,11 +962,13 @@ find_namespace_latest (const gchar *namespace, } candidate = g_new0 (struct NamespaceVersionCandidadate, 1); candidate->mfile = mfile; + candidate->path_index = index; candidate->path = path; candidate->version = version; candidates = g_slist_prepend (candidates, candidate); } g_dir_close (dir); + index++; } if (candidates != NULL) From 04c5badd6925bd1f49f215f70304327ae011dd57 Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Wed, 22 Oct 2008 14:02:02 +0000 Subject: [PATCH 130/692] =?UTF-8?q?Bug=20557405=20=E2=80=93=20Use=20'allow?= =?UTF-8?q?-none'=20consistently?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-10-22 Tommi Komulainen * docs/typelib-format.txt: * girepository/ginfo.c (g_arg_info_may_be_null): * girepository/girnode.c (g_ir_node_build_typelib): * girepository/girnode.h (struct _GIrNodeParam): * girepository/girparser.c (start_parameter): * girepository/girwriter.c (function_generate): * girepository/gtypelib.h (ArgBlob): * tests/errors.gir: * tests/function.gir: * tools/generate.c (write_callable_info): Use 'allow-none' consistently throughout svn path=/trunk/; revision=782 --- ginfo.c | 2 +- girnode.c | 10 +++++----- girnode.h | 2 +- girparser.c | 10 +++++----- girwriter.c | 4 ++-- gtypelib.h | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ginfo.c b/ginfo.c index fc265ad19..b2a7431c9 100644 --- a/ginfo.c +++ b/ginfo.c @@ -707,7 +707,7 @@ g_arg_info_may_be_null (GIArgInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; - return blob->null_ok; + return blob->allow_none; } GITransfer diff --git a/girnode.c b/girnode.c index e6fc799d9..7b68e0c4d 100644 --- a/girnode.c +++ b/girnode.c @@ -1489,7 +1489,7 @@ g_ir_node_build_typelib (GIrNode *node, module, modules, strings, types, data, &signature, offset2); - blob2->may_return_null = function->result->null_ok; + blob2->may_return_null = function->result->allow_none; blob2->caller_owns_return_value = function->result->transfer; blob2->caller_owns_return_container = function->result->shallow_transfer; blob2->reserved = 0; @@ -1533,7 +1533,7 @@ g_ir_node_build_typelib (GIrNode *node, module, modules, strings, types, data, &signature, offset2); - blob2->may_return_null = function->result->null_ok; + blob2->may_return_null = function->result->allow_none; blob2->caller_owns_return_value = function->result->transfer; blob2->caller_owns_return_container = function->result->shallow_transfer; blob2->reserved = 0; @@ -1585,7 +1585,7 @@ g_ir_node_build_typelib (GIrNode *node, module, modules, strings, types, data, &signature, offset2); - blob2->may_return_null = signal->result->null_ok; + blob2->may_return_null = signal->result->allow_none; blob2->caller_owns_return_value = signal->result->transfer; blob2->caller_owns_return_container = signal->result->shallow_transfer; blob2->reserved = 0; @@ -1632,7 +1632,7 @@ g_ir_node_build_typelib (GIrNode *node, module, modules, strings, types, data, &signature, offset2); - blob2->may_return_null = vfunc->result->null_ok; + blob2->may_return_null = vfunc->result->allow_none; blob2->caller_owns_return_value = vfunc->result->transfer; blob2->caller_owns_return_container = vfunc->result->shallow_transfer; blob2->reserved = 0; @@ -1661,7 +1661,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->in = param->in; blob->out = param->out; blob->dipper = param->dipper; - blob->null_ok = param->null_ok; + blob->allow_none = param->allow_none; blob->optional = param->optional; blob->transfer_ownership = param->transfer; blob->transfer_container_ownership = param->shallow_transfer; diff --git a/girnode.h b/girnode.h index 0ef95df72..b8161375d 100644 --- a/girnode.h +++ b/girnode.h @@ -136,7 +136,7 @@ struct _GIrNodeParam gboolean dipper; gboolean optional; gboolean retval; - gboolean null_ok; + gboolean allow_none; gboolean transfer; gboolean shallow_transfer; diff --git a/girparser.c b/girparser.c index fb5b68bee..9ca5225f4 100644 --- a/girparser.c +++ b/girparser.c @@ -699,7 +699,7 @@ start_parameter (GMarkupParseContext *context, const gchar *retval; const gchar *dipper; const gchar *optional; - const gchar *nullok; + const gchar *allow_none; const gchar *transfer; GIrNodeParam *param; @@ -712,7 +712,7 @@ start_parameter (GMarkupParseContext *context, retval = find_attribute ("retval", attribute_names, attribute_values); dipper = find_attribute ("dipper", attribute_names, attribute_values); optional = find_attribute ("optional", attribute_names, attribute_values); - nullok = find_attribute ("null-ok", attribute_names, attribute_values); + allow_none = find_attribute ("allow-none", attribute_names, attribute_values); transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); if (name == NULL) @@ -756,10 +756,10 @@ start_parameter (GMarkupParseContext *context, else param->optional = FALSE; - if (nullok && strcmp (nullok, "1") == 0) - param->null_ok = TRUE; + if (allow_none && strcmp (allow_none, "1") == 0) + param->allow_none = TRUE; else - param->null_ok = FALSE; + param->allow_none = FALSE; parse_param_transfer (param, transfer); diff --git a/girwriter.c b/girwriter.c index d4d550631..5a9459fd2 100644 --- a/girwriter.c +++ b/girwriter.c @@ -183,9 +183,9 @@ function_generate (GIdlWriter * writer, GIdlNodeFunction * node) g_string_append (markup_s, g_markup_printf_escaped (" transfer=\"full\"")); - if (param->null_ok) + if (param->allow_none) g_string_append (markup_s, - g_markup_printf_escaped (" null-ok=\"1\"")); + g_markup_printf_escaped (" allow-none=\"1\"")); if (strcmp (direction, "in") != 0) g_string_append (markup_s, diff --git a/gtypelib.h b/gtypelib.h index 8bb877779..3db620d97 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -127,7 +127,7 @@ typedef struct guint in : 1; guint out : 1; guint dipper : 1; - guint null_ok : 1; + guint allow_none : 1; guint optional : 1; guint transfer_ownership : 1; guint transfer_container_ownership : 1; From 9a32d9b093e73c967ad57c6e8c25bec512e67938 Mon Sep 17 00:00:00 2001 From: Lucas Rocha Date: Wed, 22 Oct 2008 14:31:58 +0000 Subject: [PATCH 131/692] fix some build warnings. 2008-10-22 Lucas Rocha * girepository/girmodule.c, girepository/gtypelib.c, girepository/girparser.[ch]: fix some build warnings. svn path=/trunk/; revision=783 --- girmodule.c | 2 +- girparser.c | 1 + girparser.h | 3 ++- gtypelib.c | 4 ++-- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/girmodule.c b/girmodule.c index 382d186ee..6ae868fdd 100644 --- a/girmodule.c +++ b/girmodule.c @@ -74,7 +74,7 @@ g_ir_module_build_typelib (GIrModule *module, { GTypelib *typelib; gsize length; - gint i; + guint i; GList *e; Header *header; DirEntry *entry; diff --git a/girparser.c b/girparser.c index 9ca5225f4..b92bc5482 100644 --- a/girparser.c +++ b/girparser.c @@ -23,6 +23,7 @@ #include #include +#include "girparser.h" #include "girmodule.h" #include "girnode.h" #include "gtypelib.h" diff --git a/girparser.h b/girparser.h index 68b3acf5f..08aecb971 100644 --- a/girparser.h +++ b/girparser.h @@ -26,8 +26,9 @@ G_BEGIN_DECLS -GList *g_ir_parse_string (const gchar *buffer, +GList *g_ir_parse_string (const gchar *namespace, const gchar *const *includes, + const gchar *buffer, gssize length, GError **error); GList *g_ir_parse_file (const gchar *filename, diff --git a/gtypelib.c b/gtypelib.c index 1d3598380..be470a4b0 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -54,7 +54,7 @@ validate_interface_blob (ValidateContext *ctx, guint32 offset, GError **error); -DirEntry * +static DirEntry * get_dir_entry_checked (GTypelib *typelib, guint16 index, GError **error) @@ -876,7 +876,7 @@ validate_constant_blob (GTypelib *typelib, guint32 offset, GError **error) { - gint value_size[] = { + guint value_size[] = { 0, /* VOID */ 4, /* BOOLEAN */ 1, /* INT8 */ From bb2b5e1ee33e80fbc5725aa12e8a00f219b4af39 Mon Sep 17 00:00:00 2001 From: Johan Bilien Date: Thu, 23 Oct 2008 09:10:04 +0000 Subject: [PATCH 132/692] =?UTF-8?q?Bug=20557468=20=E2=80=93=20Support=20fo?= =?UTF-8?q?r=20GI=5FTYPELIB=5FPATH?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-10-23 Johan Bilien Bug 557468 – Support for GI_TYPELIB_PATH * girepository/girepository.c: if the GI_TYPELIB_PATH is set, add the provided paths to the global search path. svn path=/trunk/; revision=786 --- girepository.c | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/girepository.c b/girepository.c index b43a451b1..3e909532b 100644 --- a/girepository.c +++ b/girepository.c @@ -84,8 +84,8 @@ init_globals () { g_static_mutex_lock (&globals_lock); - if (default_repository == NULL) - { + if (default_repository == NULL) + { default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL); } @@ -93,14 +93,37 @@ init_globals () { const gchar *const *datadirs; const gchar *const *dir; - - datadirs = g_get_system_data_dirs (); - + const gchar *type_lib_path_env; + + type_lib_path_env = g_getenv ("GI_TYPELIB_PATH"); + search_path = NULL; - for (dir = datadirs; *dir; dir++) { - char *path = g_build_filename (*dir, "girepository", NULL); - search_path = g_slist_prepend (search_path, path); - } + if (type_lib_path_env) + { + gchar **custom_dirs; + gchar **d; + + custom_dirs = g_strsplit (type_lib_path_env, G_SEARCHPATH_SEPARATOR_S, 0); + + d = custom_dirs; + while (*d) + { + search_path = g_slist_prepend (search_path, *d); + d++; + } + + /* ownership of the array content was passed to the list */ + g_free (custom_dirs); + } + + datadirs = g_get_system_data_dirs (); + + for (dir = datadirs; *dir; dir++) + { + char *path = g_build_filename (*dir, "girepository", NULL); + search_path = g_slist_prepend (search_path, path); + } + search_path = g_slist_reverse (search_path); } From 2d0f1b309347e954974af894209b719d022a4b3e Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Thu, 23 Oct 2008 17:42:25 +0000 Subject: [PATCH 133/692] =?UTF-8?q?Bug=20556739=20=E2=80=93=20transfer-own?= =?UTF-8?q?ership=20attribute=20should=20be=20mandatory=20in=20.gir?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-10-23 Tommi Komulainen * girepository/girparser.c (parse_param_transfer): * giscanner/transformer.py (_create_parameter, _create_return): * giscanner/girwriter.py (_write_return, _write_parameter): * tools/generate.c (write_callable_info): always write and require "transfer-ownership" for return-values and parameters * tests/boxed.gir: * tests/invoke/testfns-1.0.gir: * tests/object.gir: * tests/scanner/DrawableAdditions.xml: * tests/scanner/GtkFrob-1.0-expected.tgir: * tests/scanner/annotation-1.0-expected.tgir: * tests/scanner/drawable-1.0-expected.tgir: * tests/scanner/drawable-injected-1.0-expected.gir: * tests/scanner/drawable-injected-1.0-expected.tgir: * tests/scanner/foo-1.0-expected.tgir: Updated svn path=/trunk/; revision=797 --- girparser.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/girparser.c b/girparser.c index b92bc5482..b898db4fb 100644 --- a/girparser.c +++ b/girparser.c @@ -660,30 +660,28 @@ start_function (GMarkupParseContext *context, static void parse_param_transfer (GIrNodeParam *param, const gchar *transfer) { - if (transfer && strcmp (transfer, "none") == 0) + if (transfer == NULL) + { + g_warning ("required attribute 'transfer-ownership' missing"); + } + else if (strcmp (transfer, "none") == 0) { param->transfer = FALSE; param->shallow_transfer = FALSE; } - else if (transfer && strcmp (transfer, "container") == 0) + else if (strcmp (transfer, "container") == 0) { param->transfer = FALSE; param->shallow_transfer = TRUE; } + else if (strcmp (transfer, "full") == 0) + { + param->transfer = TRUE; + param->shallow_transfer = FALSE; + } else { - if (transfer) - { - if (strcmp (transfer, "full") != 0) - g_warning ("Unknown transfer %s", transfer); - else - param->transfer = TRUE; - } - else if (param->in && !param->out) - param->transfer = FALSE; - else - param->transfer = TRUE; - param->shallow_transfer = FALSE; + g_warning ("Unknown transfer-ownership value: %s", transfer); } } From 294bf64206a88f19df6634f281aa3028d772bd3e Mon Sep 17 00:00:00 2001 From: Lucas Rocha Date: Fri, 24 Oct 2008 09:54:34 +0000 Subject: [PATCH 134/692] Bug 557623 - Constructors shouldn't be flagged as methods. 2008-10-24 Lucas Rocha Bug 557623 - Constructors shouldn't be flagged as methods. * girepository/ginfo.c (g_function_info_get_flags): ditto. svn path=/trunk/; revision=805 --- ginfo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ginfo.c b/ginfo.c index b2a7431c9..0ad4759c8 100644 --- a/ginfo.c +++ b/ginfo.c @@ -477,7 +477,8 @@ g_function_info_get_flags (GIFunctionInfo *info) flags = 0; - if (base->container != NULL) + /* Make sure we don't flag Constructors as methods */ + if (base->container != NULL && !blob->constructor) flags = flags | GI_FUNCTION_IS_METHOD; if (blob->constructor) From 8d06e5c8e700666ca238ac29e5166d166a65c0e7 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 24 Oct 2008 11:19:49 +0000 Subject: [PATCH 135/692] Only use SHLIB_SUFFIX on darwin, otherwise use G_MODULE_SUFFIX, we cannot 2008-10-24 Johan Dahlin * girepository/gtypelib.c: Only use SHLIB_SUFFIX on darwin, otherwise use G_MODULE_SUFFIX, we cannot get shext_cmds from libtool 2.2. svn path=/trunk/; revision=806 --- gtypelib.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gtypelib.c b/gtypelib.c index be470a4b0..7ec1a1cbf 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -35,6 +35,11 @@ typedef struct { #define ALIGN_VALUE(this, boundary) \ (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) +#if !defined(__Darwin__) +# undef SHLIB_SUFFIX +# define SHLIB_SUFFIX G_MODULE_SUFFIX +#endif + static void push_context (ValidateContext *ctx, const char *name) { From b97c26b3eeff612248064633becb5cfbc39faf51 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 24 Oct 2008 11:32:31 +0000 Subject: [PATCH 136/692] Export two private methods to avoid an compiler warning svn path=/trunk/; revision=810 --- girmodule.c | 3 --- girmodule.h | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/girmodule.c b/girmodule.c index 6ae868fdd..d7ca37bff 100644 --- a/girmodule.c +++ b/girmodule.c @@ -24,9 +24,6 @@ #include "girmodule.h" #include "girnode.h" -void _g_irnode_init_stats (void); -void _g_irnode_dump_stats (void); - #define ALIGN_VALUE(this, boundary) \ (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) diff --git a/girmodule.h b/girmodule.h index 5b63c36eb..56c7d4681 100644 --- a/girmodule.h +++ b/girmodule.h @@ -46,6 +46,9 @@ void g_ir_module_free (GIrModule *module); GTypelib * g_ir_module_build_typelib (GIrModule *module, GList *modules); +void _g_irnode_init_stats (void); +void _g_irnode_dump_stats (void); + G_END_DECLS #endif /* __G_IR_MODULE_H__ */ From 696aa37e4e4496577675f22d0b1c50d93b7bca4a Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 24 Oct 2008 11:33:33 +0000 Subject: [PATCH 137/692] Be quiet, do not warn about unhandled members. 2008-10-24 Johan Dahlin * girepository/girnode.c (g_ir_node_check_unhandled_members): Be quiet, do not warn about unhandled members. svn path=/trunk/; revision=811 --- girnode.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/girnode.c b/girnode.c index 7b68e0c4d..fad4c28cd 100644 --- a/girnode.c +++ b/girnode.c @@ -1220,6 +1220,7 @@ static void g_ir_node_check_unhandled_members (GList **members, GIrNodeTypeId container_type) { +#if 0 if (*members) { GList *l; @@ -1227,7 +1228,6 @@ g_ir_node_check_unhandled_members (GList **members, for (l = *members; l; l = l->next) { GIrNode *member = (GIrNode *)l->data; - g_printerr ("Unhandled '%s' member '%s' type '%s'\n", g_ir_node_type_to_string (container_type), member->name, @@ -1237,10 +1237,12 @@ g_ir_node_check_unhandled_members (GList **members, g_list_free (*members); *members = NULL; - /* Commented out for now to not break the build. g_error ("Unhandled members. Aborting."); - */ } +#else + g_list_free (*members); + *members = NULL; +#endif } void From 3944a895ce52140e6394db2fca50f8c905ccfd4c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 25 Oct 2008 14:59:25 +0000 Subject: [PATCH 138/692] Bug 557076 - move typelibs to $libdir svn path=/trunk/; revision=813 --- girepository.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/girepository.c b/girepository.c index 3e909532b..2babec5d4 100644 --- a/girepository.c +++ b/girepository.c @@ -31,6 +31,8 @@ #include "girepository.h" #include "gtypelib.h" +#include "config.h" + static GStaticMutex globals_lock = G_STATIC_MUTEX_INIT; static GIRepository *default_repository = NULL; static GSList *search_path = NULL; @@ -91,8 +93,8 @@ init_globals () if (search_path == NULL) { - const gchar *const *datadirs; - const gchar *const *dir; + const char *libdir; + char *typelib_dir; const gchar *type_lib_path_env; type_lib_path_env = g_getenv ("GI_TYPELIB_PATH"); @@ -116,13 +118,11 @@ init_globals () g_free (custom_dirs); } - datadirs = g_get_system_data_dirs (); + libdir = GOBJECT_INTROSPECTION_LIBDIR; - for (dir = datadirs; *dir; dir++) - { - char *path = g_build_filename (*dir, "girepository", NULL); - search_path = g_slist_prepend (search_path, path); - } + typelib_dir = g_build_filename (libdir, "girepository", NULL); + + search_path = g_slist_prepend (search_path, typelib_dir); search_path = g_slist_reverse (search_path); } From 832328d59a73c924f8f58dd51d6dabd83db79083 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 25 Oct 2008 15:20:54 +0000 Subject: [PATCH 139/692] Bug 557786 - support fixed size arrays svn path=/trunk/; revision=814 --- ginfo.c | 20 ++++++++++++++++++++ girepository.h | 1 + girnode.c | 10 +++++++++- girnode.h | 2 ++ girparser.c | 7 ++++++- gtypelib.h | 8 ++++++-- 6 files changed, 44 insertions(+), 4 deletions(-) diff --git a/ginfo.c b/ginfo.c index 0ad4759c8..3de0cf590 100644 --- a/ginfo.c +++ b/ginfo.c @@ -830,6 +830,26 @@ g_type_info_get_array_length (GITypeInfo *info) return -1; } +gint +g_type_info_get_array_fixed_size (GITypeInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; + + if (!(type->reserved == 0 && type->reserved2 == 0)) + { + ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset]; + + if (blob->tag == GI_TYPE_TAG_ARRAY) + { + if (blob->has_size) + return blob->size; + } + } + + return -1; +} + gboolean g_type_info_is_zero_terminated (GITypeInfo *info) { diff --git a/girepository.h b/girepository.h index 1ab326b7a..103a099d9 100644 --- a/girepository.h +++ b/girepository.h @@ -320,6 +320,7 @@ GITypeInfo * g_type_info_get_param_type (GITypeInfo *info, gint n); GIBaseInfo * g_type_info_get_interface (GITypeInfo *info); gint g_type_info_get_array_length (GITypeInfo *info); +gint g_type_info_get_array_fixed_size(GITypeInfo *info); gboolean g_type_info_is_zero_terminated (GITypeInfo *info); gint g_type_info_get_n_error_domains (GITypeInfo *info); diff --git a/girnode.c b/girnode.c index fad4c28cd..632d5c349 100644 --- a/girnode.c +++ b/girnode.c @@ -1114,6 +1114,8 @@ serialize_type (GIrModule *module, if (node->has_length) g_string_append_printf (str, "length=%d", node->length); + else if (node->has_size) + g_string_append_printf (str, "fixed-size=%d", node->size); if (node->zero_terminated) g_string_append_printf (str, "%szero-terminated=1", @@ -1319,8 +1321,14 @@ g_ir_node_build_typelib (GIrNode *node, array->tag = type->tag; array->zero_terminated = type->zero_terminated; array->has_length = type->has_length; + array->has_size = type->has_size; array->reserved2 = 0; - array->length = type->length; + if (array->has_length) + array->length = type->length; + else if (array->has_size) + array->size = type->size; + else + array->length = -1; pos = *offset2 + 4; *offset2 += 8; diff --git a/girnode.h b/girnode.h index b8161375d..58b18c8d1 100644 --- a/girnode.h +++ b/girnode.h @@ -119,6 +119,8 @@ struct _GIrNodeType gboolean zero_terminated; gboolean has_length; gint length; + gboolean has_size; + gint size; GIrNodeType *parameter_type1; GIrNodeType *parameter_type2; diff --git a/girparser.c b/girparser.c index b898db4fb..e355e6189 100644 --- a/girparser.c +++ b/girparser.c @@ -1514,6 +1514,7 @@ start_type (GMarkupParseContext *context, { const char *zero; const char *len; + const char *size; typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE); @@ -1523,10 +1524,14 @@ start_type (GMarkupParseContext *context, zero = find_attribute ("zero-terminated", attribute_names, attribute_values); len = find_attribute ("length", attribute_names, attribute_values); - + size = find_attribute ("fixed-size", attribute_names, attribute_values); + typenode->zero_terminated = !(zero && strcmp (zero, "1") != 0); typenode->has_length = len != NULL; typenode->length = typenode->has_length ? atoi (len) : -1; + + typenode->has_size = size != NULL; + typenode->size = typenode->has_size ? atoi (size) : -1; } else { diff --git a/gtypelib.h b/gtypelib.h index 3db620d97..458d429d1 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -206,9 +206,13 @@ typedef struct guint16 zero_terminated :1; guint16 has_length :1; - guint16 reserved2 :6; + guint16 has_size :1; + guint16 reserved2 :5; - guint16 length; + union { + guint16 length; + guint16 size; + }; SimpleTypeBlob type; } ArrayTypeBlob; From 310f119141e5f532eb1f8164df54e9329b3ea5c1 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 25 Oct 2008 15:48:50 +0000 Subject: [PATCH 140/692] =?UTF-8?q?Bug=20557791=20=E2=80=93=20g=5Fireposit?= =?UTF-8?q?ory=5Frequire()=20could=20return=20a=20GTypelib=20*?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit svn path=/trunk/; revision=816 --- girepository.c | 17 +++++++++-------- girepository.h | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/girepository.c b/girepository.c index 2babec5d4..dc9473a8b 100644 --- a/girepository.c +++ b/girepository.c @@ -1029,9 +1029,9 @@ find_namespace_latest (const gchar *namespace, * version @version of namespace may be specified. If @version is * not specified, the latest will be used. * - * Returns: %TRUE if successful, %NULL otherwise + * Returns: a pointer to the #GTypelib if successful, %NULL otherwise */ -gboolean +GTypelib * g_irepository_require (GIRepository *repository, const gchar *namespace, const gchar *version, @@ -1039,7 +1039,7 @@ g_irepository_require (GIRepository *repository, GError **error) { GMappedFile *mfile; - gboolean ret = FALSE; + GTypelib *ret = NULL; Header *header; GTypelib *typelib = NULL; const gchar *typelib_namespace, *typelib_version; @@ -1053,9 +1053,10 @@ g_irepository_require (GIRepository *repository, repository = get_repository (repository); - if (get_registered_status (repository, namespace, version, allow_lazy, - &is_lazy, &version_conflict)) - return TRUE; + typelib = get_registered_status (repository, namespace, version, allow_lazy, + &is_lazy, &version_conflict); + if (typelib) + return typelib; if (version_conflict != NULL) { @@ -1063,7 +1064,7 @@ g_irepository_require (GIRepository *repository, G_IREPOSITORY_ERROR_NAMESPACE_VERSION_CONFLICT, "Requiring namespace '%s' version '%s', but '%s' is already loaded", namespace, version, version_conflict); - return FALSE; + return NULL; } if (version != NULL) @@ -1121,7 +1122,7 @@ g_irepository_require (GIRepository *repository, g_typelib_free (typelib); goto out; } - ret = TRUE; + ret = typelib; out: g_free (tmp_version); g_free (path); diff --git a/girepository.h b/girepository.h index 103a099d9..c40b6b749 100644 --- a/girepository.h +++ b/girepository.h @@ -87,7 +87,7 @@ gboolean g_irepository_is_registered (GIRepository *repository, GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, const gchar *namespace, const gchar *name); -gboolean g_irepository_require (GIRepository *repository, +GTypelib * g_irepository_require (GIRepository *repository, const gchar *namespace, const gchar *version, GIRepositoryLoadFlags flags, From 119c5034a1381048309c31729da8660dfba50a17 Mon Sep 17 00:00:00 2001 From: Johan Bilien Date: Mon, 27 Oct 2008 15:03:18 +0000 Subject: [PATCH 141/692] =?UTF-8?q?Bug=20558068=20=E2=80=93=20when=20invok?= =?UTF-8?q?ing=20a=20method,=20offset=20the=20in=20arguments=20by=20one,?= =?UTF-8?q?=20not?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-10-27 Johan Bilien Bug 558068 – when invoking a method, offset the in arguments by one, not the out * tests/invoke/invoke.c, tests/invoke/testfns.c, tests/invoke/testfns-1.0.gir: Add testing of method and constructor. * girepository/ginvoke.c: do not offset the index of given out arguments by one for methods, "this" is provided as in argument only. svn path=/trunk/; revision=820 --- ginvoke.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ginvoke.c b/ginvoke.c index 2626a956d..204c54785 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -254,7 +254,7 @@ g_function_info_invoke (GIFunctionInfo *info, goto out; } - args[i+offset] = (gpointer)&out_args[out_pos+offset]; + args[i+offset] = (gpointer)&out_args[out_pos]; out_pos++; break; case GI_DIRECTION_INOUT: From 65b8727e572c13d8318a532a23732af59bbc5747 Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Sat, 1 Nov 2008 18:21:55 +0000 Subject: [PATCH 142/692] =?UTF-8?q?Bug=20557898=20=E2=80=93=20Fails=20to?= =?UTF-8?q?=20build=20on=20OSX=2010.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-11-01 Tommi Komulainen * configure.ac: Check for $shrext_cmds that should be implicitly available if you're using libtool >= 2.0. If undefined, call libtool --config explicitly to get its value. * girepository/gtypelib.c: Remove special case for (non-)Darwin systems as unneeded. svn path=/trunk/; revision=859 --- gtypelib.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/gtypelib.c b/gtypelib.c index 7ec1a1cbf..be470a4b0 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -35,11 +35,6 @@ typedef struct { #define ALIGN_VALUE(this, boundary) \ (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) -#if !defined(__Darwin__) -# undef SHLIB_SUFFIX -# define SHLIB_SUFFIX G_MODULE_SUFFIX -#endif - static void push_context (ValidateContext *ctx, const char *name) { From b918bb5e8c9717fddf221278c2a150a91c691d92 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 5 Nov 2008 22:09:44 +0000 Subject: [PATCH 143/692] Don't use nested scope local variable for error svn path=/trunk/; revision=864 --- ginvoke.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ginvoke.c b/ginvoke.c index 204c54785..af21473b2 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -163,7 +163,8 @@ g_function_info_invoke (GIFunctionInfo *info, gint n_args, n_invoke_args, in_pos, out_pos, i; gpointer *args; gboolean success = FALSE; - GError *local_error; + GError *local_error = NULL; + gpointer error_address = &local_error; symbol = g_function_info_get_symbol (info); @@ -288,11 +289,9 @@ g_function_info_invoke (GIFunctionInfo *info, g_base_info_unref ((GIBaseInfo *)ainfo); } - local_error = NULL; if (throws) { - gpointer address = &local_error; - args[n_invoke_args - 1] = &address; + args[n_invoke_args - 1] = &error_address; atypes[n_invoke_args - 1] = &ffi_type_pointer; } From 8c88777cfb1d0b138d762b10721c2dbb08de0709 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Mon, 10 Nov 2008 23:58:49 +0000 Subject: [PATCH 144/692] =?UTF-8?q?Bug=20560248=20=E2=80=93=20"disguised?= =?UTF-8?q?=20structures"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Certain types like GIConv and GdkAtom are pointers internally but don't look like pointers when referenced. They have the form. typedef struct _X *X; Parse these as structures/records but mark them in the gir with a 'disguised' attribute so that we know that they need special handling. In the typelib treat them like any other structure. svn path=/trunk/; revision=872 --- girnode.h | 1 + girparser.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/girnode.h b/girnode.h index 58b18c8d1..a0dd9ee07 100644 --- a/girnode.h +++ b/girnode.h @@ -278,6 +278,7 @@ struct _GIrNodeStruct GIrNode node; gboolean deprecated; + gboolean disguised; gchar *gtype_name; gchar *gtype_init; diff --git a/girparser.c b/girparser.c index e355e6189..50085c4cd 100644 --- a/girparser.c +++ b/girparser.c @@ -75,6 +75,7 @@ struct _ParseContext gboolean prefix_aliases; GList *dependencies; GHashTable *aliases; + GHashTable *disguised_structures; const char *namespace; GIrModule *current_module; @@ -94,6 +95,10 @@ start_alias (GMarkupParseContext *context, ParseContext *ctx, GError **error); +static const gchar *find_attribute (const gchar *name, + const gchar **attribute_names, + const gchar **attribute_values); + static void firstpass_start_element_handler (GMarkupParseContext *context, const gchar *element_name, @@ -109,6 +114,30 @@ firstpass_start_element_handler (GMarkupParseContext *context, start_alias (context, element_name, attribute_names, attribute_values, ctx, error); } + else if (strcmp (element_name, "record") == 0) + { + const gchar *name; + const gchar *disguised; + + name = find_attribute ("name", attribute_names, attribute_values); + disguised = find_attribute ("disguised", attribute_names, attribute_values); + + if (disguised && strcmp (disguised, "1") == 0) + { + char *key; + + if (ctx->prefix_aliases) + { + key = g_strdup_printf ("%s.%s", ctx->namespace, name); + } + else + { + key = g_strdup (name); + } + + g_hash_table_replace (ctx->disguised_structures, key, GINT_TO_POINTER (1)); + } + } } static void @@ -1549,6 +1578,13 @@ start_type (GMarkupParseContext *context, typenode = parse_type (ctx, name); + /* A 'disguised' structure is one where the c:type is a typedef that + * doesn't look like a pointer, but is internally. + */ + if (typenode->tag == GI_TYPE_TAG_INTERFACE && + g_hash_table_lookup (ctx->disguised_structures, typenode->interface) != NULL) + is_pointer = TRUE; + if (is_pointer) typenode->is_pointer = is_pointer; } @@ -1936,12 +1972,14 @@ start_struct (GMarkupParseContext *context, { const gchar *name; const gchar *deprecated; + const gchar *disguised; const gchar *gtype_name; const gchar *gtype_init; GIrNodeStruct *struct_; name = find_attribute ("name", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + disguised = find_attribute ("disguised", attribute_names, attribute_values); gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values); gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values); @@ -1969,6 +2007,9 @@ start_struct (GMarkupParseContext *context, else struct_->deprecated = FALSE; + if (disguised && strcmp (disguised, "1") == 0) + struct_->disguised = TRUE; + struct_->gtype_name = g_strdup (gtype_name); struct_->gtype_init = g_strdup (gtype_init); @@ -2102,6 +2143,7 @@ parse_include (GMarkupParseContext *context, sub_ctx.prefix_aliases = TRUE; sub_ctx.namespace = name; sub_ctx.aliases = ctx->aliases; + sub_ctx.disguised_structures = ctx->disguised_structures; sub_ctx.type_depth = 0; context = g_markup_parse_context_new (&firstpass_parser, 0, &sub_ctx, NULL); @@ -2862,6 +2904,7 @@ g_ir_parse_string (const gchar *namespace, ctx.prefix_aliases = FALSE; ctx.namespace = namespace; ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + ctx.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); ctx.type_depth = 0; ctx.dependencies = NULL; ctx.current_module = NULL; @@ -2886,6 +2929,7 @@ g_ir_parse_string (const gchar *namespace, out: g_hash_table_destroy (ctx.aliases); + g_hash_table_destroy (ctx.disguised_structures); g_markup_parse_context_free (context); From d041deae59a543516a44659acd5dfaaff7c06732 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Tue, 11 Nov 2008 00:04:45 +0000 Subject: [PATCH 145/692] Split g_ir_ffi_get_ffi_type() out from ginvoke.c Extract a function to convert GITypeTag to ffi_type from the internals of ginvoke.c. This will be useful in figure out structure alignment. Also fix handling of gsize and time_t to be portable. (Add a check to configure.ac to figure out the width of time_t.) svn path=/trunk/; revision=873 --- Makefile.am | 4 ++- ginvoke.c | 74 ++------------------------------------ girffi.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++ girffi.h | 33 +++++++++++++++++ 4 files changed, 139 insertions(+), 72 deletions(-) create mode 100644 girffi.c create mode 100644 girffi.h diff --git a/Makefile.am b/Makefile.am index be2d0d9cf..005672dc3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,7 +13,9 @@ libgirepository_la_SOURCES = \ gtypelib.h \ gtypelib.c \ ginfo.c \ - ginvoke.c + ginvoke.c \ + girffi.c \ + girffi.h libgirepository_la_CPPFLAGS = $(GIREPO_CFLAGS) libgirepository_la_LIBADD = $(GIREPO_LIBS) libgirepository_la_LDFLAGS = -no-undefined diff --git a/ginvoke.c b/ginvoke.c index af21473b2..89419e569 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -24,6 +24,7 @@ #include #include "girepository.h" +#include "girffi.h" #include "gtypelib.h" #include "config.h" @@ -41,79 +42,10 @@ g_invoke_error_quark (void) static ffi_type * get_ffi_type (GITypeInfo *info) { - ffi_type *rettype; - if (g_type_info_is_pointer (info)) - rettype = &ffi_type_pointer; + return &ffi_type_pointer; else - switch (g_type_info_get_tag (info)) - { - case GI_TYPE_TAG_VOID: - rettype = &ffi_type_void; - break; - case GI_TYPE_TAG_BOOLEAN: - rettype = &ffi_type_uint; - break; - case GI_TYPE_TAG_INT8: - rettype = &ffi_type_sint8; - break; - case GI_TYPE_TAG_UINT8: - rettype = &ffi_type_uint8; - break; - case GI_TYPE_TAG_INT16: - rettype = &ffi_type_sint16; - break; - case GI_TYPE_TAG_UINT16: - rettype = &ffi_type_uint16; - break; - case GI_TYPE_TAG_INT32: - rettype = &ffi_type_sint32; - break; - case GI_TYPE_TAG_UINT32: - rettype = &ffi_type_uint32; - break; - case GI_TYPE_TAG_INT64: - rettype = &ffi_type_sint64; - break; - case GI_TYPE_TAG_UINT64: - rettype = &ffi_type_uint64; - break; - case GI_TYPE_TAG_INT: - rettype = &ffi_type_sint; - break; - case GI_TYPE_TAG_UINT: - rettype = &ffi_type_uint; - break; - case GI_TYPE_TAG_SSIZE: /* FIXME */ - case GI_TYPE_TAG_LONG: - rettype = &ffi_type_slong; - break; - case GI_TYPE_TAG_SIZE: /* FIXME */ - case GI_TYPE_TAG_TIME_T: /* May not be portable */ - case GI_TYPE_TAG_ULONG: - rettype = &ffi_type_ulong; - break; - case GI_TYPE_TAG_FLOAT: - rettype = &ffi_type_float; - break; - case GI_TYPE_TAG_DOUBLE: - rettype = &ffi_type_double; - break; - case GI_TYPE_TAG_UTF8: - case GI_TYPE_TAG_FILENAME: - 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: - case GI_TYPE_TAG_ERROR: - rettype = &ffi_type_pointer; - break; - default: - g_assert_not_reached (); - } - - return rettype; + return g_ir_ffi_get_ffi_type (g_type_info_get_tag (info)); } /** diff --git a/girffi.c b/girffi.c new file mode 100644 index 000000000..db5e87e84 --- /dev/null +++ b/girffi.c @@ -0,0 +1,100 @@ +/* GObject introspection: Helper functions for ffi integration + * + * Copyright (C) 2008 Red Hat, Inc + * Copyright (C) 2005 Matthias Clasen + * + * 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 "girffi.h" + +ffi_type * +g_ir_ffi_get_ffi_type (GITypeTag tag) +{ + switch (tag) + { + case GI_TYPE_TAG_VOID: + return &ffi_type_void; + case GI_TYPE_TAG_BOOLEAN: + return &ffi_type_uint; + case GI_TYPE_TAG_INT8: + return &ffi_type_sint8; + case GI_TYPE_TAG_UINT8: + return &ffi_type_uint8; + case GI_TYPE_TAG_INT16: + return &ffi_type_sint16; + case GI_TYPE_TAG_UINT16: + return &ffi_type_uint16; + case GI_TYPE_TAG_INT32: + return &ffi_type_sint32; + case GI_TYPE_TAG_UINT32: + return &ffi_type_uint32; + case GI_TYPE_TAG_INT64: + return &ffi_type_sint64; + case GI_TYPE_TAG_UINT64: + return &ffi_type_uint64; + case GI_TYPE_TAG_INT: + return &ffi_type_sint; + case GI_TYPE_TAG_UINT: + return &ffi_type_uint; + case GI_TYPE_TAG_SSIZE: +#if GLIB_SIZEOF_SIZE_T == 4 + return &ffi_type_sint32; +#elif GLIB_SIZEOF_SIZE_T == 8 + return &ffi_type_sint64; +#else +# error "Unexpected size for size_t: not 4 or 8" +#endif + case GI_TYPE_TAG_LONG: + return &ffi_type_slong; + case GI_TYPE_TAG_SIZE: + case GI_TYPE_TAG_GTYPE: +#if GLIB_SIZEOF_SIZE_T == 4 + return &ffi_type_uint32; +#elif GLIB_SIZEOF_SIZE_T == 8 + return &ffi_type_uint64; +#else +# error "Unexpected size for size_t: not 4 or 8" +#endif + case GI_TYPE_TAG_TIME_T: +#if SIZEOF_TIME_T == 4 + return &ffi_type_sint32; +#elif SIZEOF_TIME_T == 8 + return &ffi_type_sint64; +#else +# error "Unexpected time for time_t: not 4 or 8" +#endif + case GI_TYPE_TAG_ULONG: + return &ffi_type_ulong; + case GI_TYPE_TAG_FLOAT: + return &ffi_type_float; + case GI_TYPE_TAG_DOUBLE: + return &ffi_type_double; + case GI_TYPE_TAG_UTF8: + case GI_TYPE_TAG_FILENAME: + 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: + case GI_TYPE_TAG_ERROR: + return &ffi_type_pointer; + } + + g_assert_not_reached (); + + return NULL; +} diff --git a/girffi.h b/girffi.h new file mode 100644 index 000000000..842a2334c --- /dev/null +++ b/girffi.h @@ -0,0 +1,33 @@ +/* GObject introspection: Helper functions for ffi integration + * + * Copyright (C) 2008 Red Hat, Inc + * + * 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 __GIRFFI_H__ +#define __GIRFFI_H__ + +#include "girepository.h" +#include + +G_BEGIN_DECLS + +ffi_type *g_ir_ffi_get_ffi_type (GITypeTag tag); + +G_END_DECLS + +#endif /* __GIRFFI_H__ */ From 6d9212674a314eb3886498c18c7dd49bdcf27f26 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Tue, 11 Nov 2008 00:48:17 +0000 Subject: [PATCH 146/692] Bug 560250 - Fully parse included modules For some things, like computing structure offsets to put into the typelib we need more than just the aliases from included modules. Do a completel parse of included modules and store in module->included_modules. Also add g_ir_find_node() to find node information from within the active set of modules and their includes. svn path=/trunk/; revision=874 --- girmodule.c | 4 +++ girmodule.h | 1 + girnode.c | 86 ++++++++++++++++++++++++++++++++++++++++++++ girnode.h | 8 +++++ girparser.c | 100 ++++++++++++++++++++++++++++++++++++++++------------ 5 files changed, 177 insertions(+), 22 deletions(-) diff --git a/girmodule.c b/girmodule.c index d7ca37bff..91cc02d8a 100644 --- a/girmodule.c +++ b/girmodule.c @@ -62,6 +62,10 @@ g_ir_module_free (GIrModule *module) g_list_free (module->entries); /* Don't free dependencies, we inherit that from the parser */ + /* FIXME: we leak the included modules themelves; they may be shared + * between multiple modules, so we would need refcounting */ + g_list_free (module->include_modules); + g_free (module); } diff --git a/girmodule.h b/girmodule.h index 56c7d4681..5008c4e97 100644 --- a/girmodule.h +++ b/girmodule.h @@ -36,6 +36,7 @@ struct _GIrModule gchar *shared_library; GList *dependencies; GList *entries; + GList *include_modules; }; GIrModule *g_ir_module_new (const gchar *name, diff --git a/girnode.c b/girnode.c index 632d5c349..b7f0cb275 100644 --- a/girnode.c +++ b/girnode.c @@ -1070,6 +1070,92 @@ find_entry (GIrModule *module, return idx; } +static GIrNode * +find_name_in_module (GIrModule *module, + const gchar *name) +{ + GList *l; + + for (l = module->entries; l; l = l->next) + { + GIrNode *node = (GIrNode *)l->data; + + if (strcmp (node->name, name) == 0) + return node; + } + + return NULL; +} + +gboolean +g_ir_find_node (GIrModule *module, + GList *modules, + const char *name, + GIrNode **node_out, + GIrModule **module_out) +{ + char **names = g_strsplit (name, ".", 0); + gint n_names = g_strv_length (names); + GIrNode *node = NULL; + GList *l; + + if (n_names == 0) + { + g_warning ("Name can't be empty"); + goto out; + } + + if (n_names > 2) + { + g_warning ("Too many name parts in '%s'", name); + goto out; + } + + if (n_names == 1) + { + *module_out = module; + node = find_name_in_module (module, names[0]); + } + else if (strcmp (names[0], module->name) == 0) + { + *module_out = module; + node = find_name_in_module (module, names[1]); + } + else + { + for (l = module->include_modules; l; l = l->next) + { + GIrModule *m = l->data; + + if (strcmp (names[0], m->name) == 0) + { + *module_out = m; + node = find_name_in_module (m, names[1]); + goto out; + } + } + + for (l = modules; l; l = l->next) + { + GIrModule *m = l->data; + + if (strcmp (names[0], m->name) == 0) + { + *module_out = m; + node = find_name_in_module (m, names[1]); + goto out; + } + } + } + + out: + g_strfreev (names); + + *node_out = node; + + return node != NULL; +} + static void serialize_type (GIrModule *module, GList *modules, diff --git a/girnode.h b/girnode.h index a0dd9ee07..bc24a11c6 100644 --- a/girnode.h +++ b/girnode.h @@ -23,6 +23,8 @@ #include +#include "girmodule.h" + G_BEGIN_DECLS typedef struct _GIrNode GIrNode; @@ -340,6 +342,12 @@ guint32 write_string (const gchar *str, const gchar * g_ir_node_param_direction_string (GIrNodeParam * node); const gchar * g_ir_node_type_to_string (GIrNodeTypeId type); +gboolean g_ir_find_node (GIrModule *module, + GList *modules, + const char *name, + GIrNode **node_out, + GIrModule **module_out); + G_END_DECLS #endif /* __G_IR_NODE_H__ */ diff --git a/girparser.c b/girparser.c index 50085c4cd..9221bb5d6 100644 --- a/girparser.c +++ b/girparser.c @@ -72,6 +72,7 @@ struct _ParseContext const char * const*includes; GList *modules; + GList *include_modules; gboolean prefix_aliases; GList *dependencies; GHashTable *aliases; @@ -87,6 +88,34 @@ struct _ParseContext int type_depth; }; +static void start_element_handler (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error); +static void end_element_handler (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error); +static void text_handler (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error); +static void cleanup (GMarkupParseContext *context, + GError *error, + gpointer user_data); + +static GMarkupParser parser = +{ + start_element_handler, + end_element_handler, + text_handler, + NULL, + cleanup +}; + static gboolean start_alias (GMarkupParseContext *context, const gchar *element_name, @@ -2116,7 +2145,31 @@ parse_include (GMarkupParseContext *context, gchar *buffer; gsize length; char *girpath; - + gboolean success = FALSE; + GList *l; + + for (l = ctx->include_modules; l; l = l->next) + { + GIrModule *m = l->data; + + if (strcmp (m->name, name) == 0) + { + if (strcmp (m->version, version) == 0) + { + return TRUE; + } + else + { + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Module '%s' imported with conflicting versions '%s' and '%s'", + name, m->version, version); + return FALSE; + } + } + } + girpath = locate_gir (name, version, ctx->includes); if (girpath == NULL) @@ -2147,21 +2200,32 @@ parse_include (GMarkupParseContext *context, sub_ctx.type_depth = 0; context = g_markup_parse_context_new (&firstpass_parser, 0, &sub_ctx, NULL); - + if (!g_markup_parse_context_parse (context, buffer, length, error)) - { - g_free (buffer); - return FALSE; - } - + goto out; + if (!g_markup_parse_context_end_parse (context, error)) - { - g_free (buffer); - return FALSE; - } - + goto out; + g_markup_parse_context_free (context); - return TRUE; + + context = g_markup_parse_context_new (&parser, 0, &sub_ctx, NULL); + if (!g_markup_parse_context_parse (context, buffer, length, error)) + goto out; + + if (!g_markup_parse_context_end_parse (context, error)) + goto out; + + success = TRUE; + + out: + ctx->include_modules = g_list_concat (ctx->include_modules, + sub_ctx.modules); + + g_markup_parse_context_free (context); + g_free (buffer); + + return success; } extern GLogLevelFlags logged_levels; @@ -2358,6 +2422,7 @@ start_element_handler (GMarkupParseContext *context, ctx->current_module = g_ir_module_new (name, version, shared_library); ctx->modules = g_list_append (ctx->modules, ctx->current_module); ctx->current_module->dependencies = ctx->dependencies; + ctx->current_module->include_modules = g_list_copy (ctx->include_modules); state_switch (ctx, STATE_NAMESPACE); goto out; @@ -2819,15 +2884,6 @@ cleanup (GMarkupParseContext *context, ctx->current_module = NULL; } -static GMarkupParser parser = -{ - start_element_handler, - end_element_handler, - text_handler, - NULL, - cleanup -}; - static GList * post_filter_varargs_functions (GList *list) { From 31a7f413d6d1ae039c02834e61b9fb6a5f790223 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Tue, 11 Nov 2008 05:10:36 +0000 Subject: [PATCH 147/692] Bug 560252 - Compute field offsets before writing typelib girnode.h: Store the total size and alignment for GIrNodeStruct/Boxed/Union. giroffset.c: New file implementing computation of structure field offsets. girnode.c: Compute structure field offsets before writing types into the typelib. docs/typelib-format.txt: Document that a field offset of 0xFFFF means "unknown". Also fix description of the discriminator_offset field for unions. svn path=/trunk/; revision=876 --- Makefile.am | 1 + girnode.c | 7 +- girnode.h | 16 ++ giroffsets.c | 413 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 436 insertions(+), 1 deletion(-) create mode 100644 giroffsets.c diff --git a/Makefile.am b/Makefile.am index 005672dc3..c3694fd11 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,6 +25,7 @@ libgirepository_parser_la_SOURCES = \ girmodule.h \ girnode.c \ girnode.h \ + giroffsets.c \ girparser.c \ girparser.h libgirepository_parser_la_CFLAGS = $(GIREPO_CFLAGS) diff --git a/girnode.c b/girnode.c index b7f0cb275..87b418c8f 100644 --- a/girnode.c +++ b/girnode.c @@ -1354,6 +1354,8 @@ g_ir_node_build_typelib (GIrNode *node, node->name ? " " : "", g_ir_node_type_to_string (node->type)); + g_ir_node_compute_offsets (node, module, modules); + switch (node->type) { case G_IR_NODE_TYPE: @@ -1525,7 +1527,10 @@ g_ir_node_build_typelib (GIrNode *node, blob->writable = field->writable; blob->reserved = 0; blob->bits = 0; - blob->struct_offset = field->offset; + if (field->offset >= 0) + blob->struct_offset = field->offset; + else + blob->struct_offset = 0xFFFF; /* mark as unknown */ g_ir_node_build_typelib ((GIrNode *)field->type, module, modules, strings, types, diff --git a/girnode.h b/girnode.h index bc24a11c6..971df6b9c 100644 --- a/girnode.h +++ b/girnode.h @@ -271,6 +271,9 @@ struct _GIrNodeBoxed gchar *gtype_name; gchar *gtype_init; + + gint alignment; + gint size; GList *members; }; @@ -284,6 +287,9 @@ struct _GIrNodeStruct gchar *gtype_name; gchar *gtype_init; + + gint alignment; + gint size; GList *members; }; @@ -300,6 +306,9 @@ struct _GIrNodeUnion gchar *gtype_name; gchar *gtype_init; + gint alignment; + gint size; + gint discriminator_offset; GIrNodeType *discriminator_type; }; @@ -348,6 +357,13 @@ gboolean g_ir_find_node (GIrModule *module, GIrNode **node_out, GIrModule **module_out); +/* In giroffsets.c */ + +void g_ir_node_compute_offsets (GIrNode *node, + GIrModule *module, + GList *modules); + + G_END_DECLS #endif /* __G_IR_NODE_H__ */ diff --git a/giroffsets.c b/giroffsets.c new file mode 100644 index 000000000..8489dc43a --- /dev/null +++ b/giroffsets.c @@ -0,0 +1,413 @@ +/* GObject introspection: Compute structure offsets + * + * Copyright (C) 2008 Red Hat, Inc. + * + * 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 "girffi.h" +#include "girnode.h" + +/* The C standard specifies that an enumeration can be any char or any signed + * or unsigned integer type capable of resresenting all the values of the + * enumeration. We use test enumerations to figure out what choices the + * compiler makes. + */ + +typedef enum { + ENUM_1 = 1 /* compiler could use int8, uint8, int16, uint16, int32, uint32 */ +} Enum1; + +typedef enum { + ENUM_2 = 128 /* compiler could use uint8, int16, uint16, int32, uint32 */ +} Enum2; + +typedef enum { + ENUM_3 = 257 /* compiler could use int16, uint16, int32, uint32 */ +} Enum3; + +typedef enum { + ENUM_4 = G_MAXSHORT + 1 /* compiler could use uint16, int32, uint32 */ +} Enum4; + +typedef enum { + ENUM_5 = G_MAXUSHORT + 1 /* compiler could use int32, uint32 */ +} Enum5; + +typedef enum { + ENUM_6 = ((guint)G_MAXINT) + 1 /* compiler could use uint32 */ +} Enum6; + +/* GIrNodeValue has guint32 values, so if it matters to the ABI whether + * constant values are signed, we are in trouble. And we don't handle + * enums with > 32 bit values. */ + +#if 0 +typedef enum { + ENUM_7 = -1 /* compiler could use int8, int16, int32 */ +} Enum7; + +/* etc... */ +#endif + +static gboolean +get_enum_size_alignment (GIrNodeEnum *enum_node, + gint *size, + gint *alignment) +{ + GList *l; + guint32 max_value = 0; + int width; + ffi_type *type_ffi; + + for (l = enum_node->values; l; l = l->next) + { + GIrNodeValue *value = l->data; + if (value->value > max_value) + max_value = value->value; + } + + if (max_value < 128) + width = sizeof (Enum1); + else if (max_value < 256) + width = sizeof (Enum2); + else if (max_value < G_MAXSHORT) + width = sizeof (Enum3); + else if (max_value < G_MAXUSHORT) + width = sizeof (Enum4); + else if (max_value < G_MAXINT) + width = sizeof (Enum5); + else + width = sizeof (Enum6); + + if (width == 1) + type_ffi = &ffi_type_sint8; + else if (width == 2) + type_ffi = &ffi_type_sint16; + else if (width == 4) + type_ffi = &ffi_type_sint32; + else if (width == 8) + type_ffi = &ffi_type_sint64; + else + g_error ("Unexpected enum width %d", width); + + *size = type_ffi->size; + *alignment = type_ffi->alignment; + + return TRUE; +} + +static gboolean +get_interface_size_alignment (GIrNodeType *type, + GIrModule *module, + GList *modules, + gint *size, + gint *alignment) +{ + GIrNode *iface; + GIrModule *iface_module; + + if (!g_ir_find_node (module, modules, type->interface, &iface, &iface_module)) + { + g_warning ("Type for type name '%s' not found", type->interface); + *size = -1; + *alignment = -1; + return FALSE; + } + + g_ir_node_compute_offsets (iface, iface_module, + iface_module == module ? modules : NULL); + + switch (iface->type) + { + case G_IR_NODE_BOXED: + { + GIrNodeBoxed *boxed = (GIrNodeBoxed *)iface; + *size = boxed->size; + *alignment = boxed->alignment; + break; + } + case G_IR_NODE_STRUCT: + { + GIrNodeStruct *struct_ = (GIrNodeStruct *)iface; + *size = struct_->size; + *alignment = struct_->alignment; + break; + } + case G_IR_NODE_UNION: + { + GIrNodeUnion *union_ = (GIrNodeUnion *)iface; + *size = union_->size; + *alignment = union_->alignment; + break; + } + case G_IR_NODE_ENUM: + case G_IR_NODE_FLAGS: + { + return get_enum_size_alignment ((GIrNodeEnum *)iface, + size, alignment); + } + case G_IR_NODE_CALLBACK: + { + *size = ffi_type_pointer.size; + *alignment = ffi_type_pointer.alignment; + break; + } + default: + { + g_warning ("Unexpected non-pointer field of type %s in structure", + g_ir_node_type_to_string (iface->type)); + *size = -1; + *alignment = -1; + break; + } + } + + return *alignment != -1; +} + +static gboolean +get_field_size_alignment (GIrNodeField *field, + GIrModule *module, + GList *modules, + gint *size, + gint *alignment) +{ + GIrNodeType *type = field->type; + ffi_type *type_ffi; + + if (type->is_pointer) + { + type_ffi = &ffi_type_pointer; + } + else + { + if (type->tag == GI_TYPE_TAG_INTERFACE) + { + return get_interface_size_alignment (type, + module, modules, + size, alignment); + } + else + { + type_ffi = g_ir_ffi_get_ffi_type (type->tag); + + if (type_ffi == &ffi_type_void) + { + g_warning ("field '%s' has void type", ((GIrNode *)field)->name); + *size = -1; + *alignment = -1; + return FALSE; + } + else if (type_ffi == &ffi_type_pointer) + { + g_warning ("non-pointer field '%s' has unhandled type %s", + ((GIrNode *)field)->name, + g_type_tag_to_string (type->tag)); + *size = -1; + *alignment = -1; + return FALSE; + } + } + } + + g_assert (type_ffi); + *size = type_ffi->size; + *alignment = type_ffi->alignment; + + return TRUE; +} + +#define ALIGN(n, align) (((n) + (align) - 1) & ~((align) - 1)) + +static gboolean +compute_struct_field_offsets (GList *members, + GIrModule *module, + GList *modules, + gint *size_out, + gint *alignment_out) +{ + int size = 0; + int alignment = 1; + GList *l; + gboolean have_error = FALSE; + + for (l = members; l; l = l->next) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_FIELD) + { + GIrNodeField *field = (GIrNodeField *)member; + + if (!have_error) + { + int member_size; + int member_alignment; + + if (get_field_size_alignment (field, + module, modules, + &member_size, &member_alignment)) + { + size = ALIGN (size, member_alignment); + alignment = MAX (alignment, member_alignment); + field->offset = size; + size += member_size; + } + else + have_error = TRUE; + } + + if (have_error) + field->offset = -1; + } + else if (member->type == G_IR_NODE_CALLBACK) + { + size = ffi_type_pointer.size; + alignment = ffi_type_pointer.alignment; + } + } + + /* Structs are tail-padded out to a multiple of their alignment */ + size = ALIGN (size, alignment); + + if (!have_error) + { + *size_out = size; + *alignment_out = alignment; + } + else + { + *size_out = -1; + *alignment_out = -1; + } + + return !have_error; +} + +static gboolean +compute_union_field_offsets (GList *members, + GIrModule *module, + GList *modules, + gint *size_out, + gint *alignment_out) +{ + int size = 0; + int alignment = 1; + GList *l; + gboolean have_error = FALSE; + + for (l = members; l; l = l->next) + { + GIrNode *member = (GIrNode *)l->data; + + if (member->type == G_IR_NODE_FIELD) + { + GIrNodeField *field = (GIrNodeField *)member; + + if (!have_error) + { + int member_size; + int member_alignment; + + if (get_field_size_alignment (field, + module, modules, + &member_size, &member_alignment)) + { + size = MAX (size, member_size); + alignment = MAX (alignment, member_alignment); + } + else + have_error = TRUE; + } + } + } + + /* Unions are tail-padded out to a multiple of their alignment */ + size = ALIGN (size, alignment); + + if (!have_error) + { + *size_out = size; + *alignment_out = alignment; + } + else + { + *size_out = -1; + *alignment_out = -1; + } + + return !have_error; +} + +/** + * g_ir_node_compute_offsets: + * @node: a #GIrNode + * @module: Current module being processed + * @moudles: all currently loaded modules + * + * If a node is a a structure or union, makes sure that the field + * offsets have been computed, and also computes the overall size and + * alignment for the type. + */ +void +g_ir_node_compute_offsets (GIrNode *node, + GIrModule *module, + GList *modules) +{ + switch (node->type) + { + case G_IR_NODE_BOXED: + { + GIrNodeBoxed *boxed = (GIrNodeBoxed *)node; + + if (boxed->alignment != 0) /* Already done */ + return; + + compute_struct_field_offsets (boxed->members, + module, modules, + &boxed->size, &boxed->alignment); + break; + } + case G_IR_NODE_STRUCT: + { + GIrNodeStruct *struct_ = (GIrNodeStruct *)node; + + if (struct_->alignment != 0) + return; + + compute_struct_field_offsets (struct_->members, + module, modules, + &struct_->size, &struct_->alignment); + break; + } + case G_IR_NODE_UNION: + { + GIrNodeUnion *union_ = (GIrNodeUnion *)node; + + if (union_->alignment != 0) + return; + + compute_union_field_offsets (union_->members, + module, modules, + &union_->size, &union_->alignment); + break; + } + default: + /* Nothing to do */ + return; + } +} From d6809624381f6dcd592b90ea4f387de7e59361d5 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Tue, 11 Nov 2008 05:10:47 +0000 Subject: [PATCH 148/692] Remove field offsets from g-ir-generate output and test inputs Field offsets are a) architecture dependent so they shouldn't be part of the architecture-independent gir format which is installed in datadir. b) Are architecture-dependent so they shouldn't be in test expected output. Remove field offsets from girs. (Virtual function and discriminator offsets are not removed, as they aren't fully hooked up to the field-offset computation machinery yet.) svn path=/trunk/; revision=877 --- girparser.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/girparser.c b/girparser.c index 9221bb5d6..60937d957 100644 --- a/girparser.c +++ b/girparser.c @@ -892,7 +892,6 @@ start_field (GMarkupParseContext *context, writable = find_attribute ("writable", attribute_names, attribute_values); bits = find_attribute ("bits", attribute_names, attribute_values); branch = find_attribute ("branch", attribute_names, attribute_values); - offset = find_attribute ("offset", attribute_names, attribute_values); if (name == NULL) { @@ -914,11 +913,6 @@ start_field (GMarkupParseContext *context, else field->bits = 0; - if (offset) - field->offset = atoi (offset); - else - field->offset = 0; - switch (ctx->current_node->type) { case G_IR_NODE_OBJECT: From 01fda94550791f75f17d43b8207e54ccb845869a Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Tue, 11 Nov 2008 05:11:05 +0000 Subject: [PATCH 149/692] girepository/girparser.c: Remove an unused variable. svn path=/trunk/; revision=879 --- girparser.c | 1 - 1 file changed, 1 deletion(-) diff --git a/girparser.c b/girparser.c index 60937d957..af9bf341b 100644 --- a/girparser.c +++ b/girparser.c @@ -869,7 +869,6 @@ start_field (GMarkupParseContext *context, const gchar *writable; const gchar *bits; const gchar *branch; - const gchar *offset; GIrNodeField *field; switch (ctx->state) From 9d4aa3bba31c35c0e5db968a1ba9f5bc3b8d7ea0 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Tue, 11 Nov 2008 13:45:13 +0000 Subject: [PATCH 150/692] Fail gracefully with an informative error message when recursion is 2008-11-11 Owen Taylor * girepository/giroffsets.c: Fail gracefully with an informative error message when recursion is encountered when computing a structure size. svn path=/trunk/; revision=882 --- giroffsets.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/giroffsets.c b/giroffsets.c index 8489dc43a..f78e47924 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -176,7 +176,7 @@ get_interface_size_alignment (GIrNodeType *type, } } - return *alignment != -1; + return *alignment > 0; } static gboolean @@ -245,6 +245,8 @@ compute_struct_field_offsets (GList *members, GList *l; gboolean have_error = FALSE; + *alignment_out = -2; /* mark to detect recursion */ + for (l = members; l; l = l->next) { GIrNode *member = (GIrNode *)l->data; @@ -310,6 +312,8 @@ compute_union_field_offsets (GList *members, GList *l; gboolean have_error = FALSE; + *alignment_out = -2; /* mark to detect recursion */ + for (l = members; l; l = l->next) { GIrNode *member = (GIrNode *)l->data; @@ -353,6 +357,26 @@ compute_union_field_offsets (GList *members, return !have_error; } +static gboolean +check_needs_computation (GIrNode *node, + GIrModule *module, + gint alignment) +{ + /* + * 0: Not yet computed + * >0: Previously succeeded + * -1: Previously failed + * -2: In progress + */ + if (alignment == -2) + { + g_warning ("Recursion encountered when computing the size of %s.%s", + module->name, node->name); + } + + return alignment == 0; +} + /** * g_ir_node_compute_offsets: * @node: a #GIrNode @@ -366,7 +390,7 @@ compute_union_field_offsets (GList *members, void g_ir_node_compute_offsets (GIrNode *node, GIrModule *module, - GList *modules) + GList *modules) { switch (node->type) { @@ -374,7 +398,7 @@ g_ir_node_compute_offsets (GIrNode *node, { GIrNodeBoxed *boxed = (GIrNodeBoxed *)node; - if (boxed->alignment != 0) /* Already done */ + if (!check_needs_computation (node, module, boxed->alignment)) return; compute_struct_field_offsets (boxed->members, @@ -386,7 +410,7 @@ g_ir_node_compute_offsets (GIrNode *node, { GIrNodeStruct *struct_ = (GIrNodeStruct *)node; - if (struct_->alignment != 0) + if (!check_needs_computation (node, module, struct_->alignment)) return; compute_struct_field_offsets (struct_->members, @@ -398,7 +422,7 @@ g_ir_node_compute_offsets (GIrNode *node, { GIrNodeUnion *union_ = (GIrNodeUnion *)node; - if (union_->alignment != 0) + if (!check_needs_computation (node, module, union_->alignment)) return; compute_union_field_offsets (union_->members, From ac8db19d3fa559ea748581e6a6c957e8537ad679 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Tue, 11 Nov 2008 15:25:51 +0000 Subject: [PATCH 151/692] Include fully-qualified names in all error messages. 2008-11-11 Owen Taylor * girepository/giroffsets.c: Include fully-qualified names in all error messages. svn path=/trunk/; revision=884 --- giroffsets.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/giroffsets.c b/giroffsets.c index f78e47924..66d18555c 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -111,18 +111,21 @@ get_enum_size_alignment (GIrNodeEnum *enum_node, } static gboolean -get_interface_size_alignment (GIrNodeType *type, - GIrModule *module, - GList *modules, - gint *size, - gint *alignment) +get_interface_size_alignment (GIrNodeField *field, + GIrNode *parent_node, + GIrModule *module, + GList *modules, + gint *size, + gint *alignment) { + GIrNodeType *type = field->type; GIrNode *iface; GIrModule *iface_module; if (!g_ir_find_node (module, modules, type->interface, &iface, &iface_module)) { - g_warning ("Type for type name '%s' not found", type->interface); + g_warning ("Can't resolve type '%s' for field %s.%s.%s", + type->interface, module->name, parent_node->name, ((GIrNode *)field)->name); *size = -1; *alignment = -1; return FALSE; @@ -168,7 +171,8 @@ get_interface_size_alignment (GIrNodeType *type, } default: { - g_warning ("Unexpected non-pointer field of type %s in structure", + g_warning ("Field %s.%s.%s has is not a pointer and is of type %s", + module->name, parent_node->name, ((GIrNode *)field)->name, g_ir_node_type_to_string (iface->type)); *size = -1; *alignment = -1; @@ -181,6 +185,7 @@ get_interface_size_alignment (GIrNodeType *type, static gboolean get_field_size_alignment (GIrNodeField *field, + GIrNode *parent_node, GIrModule *module, GList *modules, gint *size, @@ -197,7 +202,7 @@ get_field_size_alignment (GIrNodeField *field, { if (type->tag == GI_TYPE_TAG_INTERFACE) { - return get_interface_size_alignment (type, + return get_interface_size_alignment (field, parent_node, module, modules, size, alignment); } @@ -207,15 +212,16 @@ get_field_size_alignment (GIrNodeField *field, if (type_ffi == &ffi_type_void) { - g_warning ("field '%s' has void type", ((GIrNode *)field)->name); + g_warning ("Field %s.%s.%s has void type", + module->name, parent_node->name, ((GIrNode *)field)->name); *size = -1; *alignment = -1; return FALSE; } else if (type_ffi == &ffi_type_pointer) { - g_warning ("non-pointer field '%s' has unhandled type %s", - ((GIrNode *)field)->name, + g_warning ("Field %s.%s.%s has is not a pointer and is of type %s", + module->name, parent_node->name, ((GIrNode *)field)->name, g_type_tag_to_string (type->tag)); *size = -1; *alignment = -1; @@ -234,7 +240,8 @@ get_field_size_alignment (GIrNodeField *field, #define ALIGN(n, align) (((n) + (align) - 1) & ~((align) - 1)) static gboolean -compute_struct_field_offsets (GList *members, +compute_struct_field_offsets (GIrNode *node, + GList *members, GIrModule *module, GList *modules, gint *size_out, @@ -260,7 +267,7 @@ compute_struct_field_offsets (GList *members, int member_size; int member_alignment; - if (get_field_size_alignment (field, + if (get_field_size_alignment (field, node, module, modules, &member_size, &member_alignment)) { @@ -301,7 +308,8 @@ compute_struct_field_offsets (GList *members, } static gboolean -compute_union_field_offsets (GList *members, +compute_union_field_offsets (GIrNode *node, + GList *members, GIrModule *module, GList *modules, gint *size_out, @@ -327,7 +335,7 @@ compute_union_field_offsets (GList *members, int member_size; int member_alignment; - if (get_field_size_alignment (field, + if (get_field_size_alignment (field, node, module, modules, &member_size, &member_alignment)) { @@ -401,7 +409,7 @@ g_ir_node_compute_offsets (GIrNode *node, if (!check_needs_computation (node, module, boxed->alignment)) return; - compute_struct_field_offsets (boxed->members, + compute_struct_field_offsets (node, boxed->members, module, modules, &boxed->size, &boxed->alignment); break; @@ -413,7 +421,7 @@ g_ir_node_compute_offsets (GIrNode *node, if (!check_needs_computation (node, module, struct_->alignment)) return; - compute_struct_field_offsets (struct_->members, + compute_struct_field_offsets (node, struct_->members, module, modules, &struct_->size, &struct_->alignment); break; @@ -425,7 +433,7 @@ g_ir_node_compute_offsets (GIrNode *node, if (!check_needs_computation (node, module, union_->alignment)) return; - compute_union_field_offsets (union_->members, + compute_union_field_offsets (node, union_->members, module, modules, &union_->size, &union_->alignment); break; From ecc78cf338486cd3274881812e989051b239e552 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Tue, 11 Nov 2008 15:25:59 +0000 Subject: [PATCH 152/692] Search provided include dirs before the default directories. 2008-11-11 Owen Taylor * girepository/girparser.c: Search provided include dirs before the default directories. svn path=/trunk/; revision=885 --- girparser.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/girparser.c b/girparser.c index af9bf341b..74d7275ce 100644 --- a/girparser.c +++ b/girparser.c @@ -198,14 +198,6 @@ locate_gir (const char *name, const char *version, const char * const* extra_pat girname = g_strdup_printf ("%s-%s.gir", name, version); - for (dir = datadirs; *dir; dir++) - { - path = g_build_filename (*dir, "gir", girname, NULL); - if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) - return path; - g_free (path); - path = NULL; - } if (extra_paths != NULL) { for (dir = extra_paths; *dir; dir++) @@ -217,6 +209,14 @@ locate_gir (const char *name, const char *version, const char * const* extra_pat path = NULL; } } + for (dir = datadirs; *dir; dir++) + { + path = g_build_filename (*dir, "gir", girname, NULL); + if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) + return path; + g_free (path); + path = NULL; + } g_free (girname); return path; } From 7c221ce28b46282e1c0bea5d949edc7a5d0d70dc Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Tue, 11 Nov 2008 21:10:12 +0000 Subject: [PATCH 153/692] Compute field offsets and overall size for object structures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-11-11 Owen Taylor Compute field offsets and overall size for object structures Bug 560326 – Fails to build Gtk-2.0.typelib with "Unexpected non-pointer field of type object in structure" Do basic computation of field offsets for objects and interfaces; this doesn't attempt to address all of the "mess" for virtual functions described in Bug 560281. svn path=/trunk/; revision=888 --- girnode.h | 3 +++ giroffsets.c | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/girnode.h b/girnode.h index 971df6b9c..9829a9333 100644 --- a/girnode.h +++ b/girnode.h @@ -228,6 +228,9 @@ struct _GIrNodeInterface GList *interfaces; GList *prerequisites; + gint alignment; + gint size; + GList *members; }; diff --git a/giroffsets.c b/giroffsets.c index 66d18555c..1844dd1b5 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -150,6 +150,14 @@ get_interface_size_alignment (GIrNodeField *field, *alignment = struct_->alignment; break; } + case G_IR_NODE_OBJECT: + case G_IR_NODE_INTERFACE: + { + GIrNodeInterface *interface = (GIrNodeInterface *)iface; + *size = interface->size; + *alignment = interface->alignment; + break; + } case G_IR_NODE_UNION: { GIrNodeUnion *union_ = (GIrNodeUnion *)iface; @@ -426,6 +434,19 @@ g_ir_node_compute_offsets (GIrNode *node, &struct_->size, &struct_->alignment); break; } + case G_IR_NODE_OBJECT: + case G_IR_NODE_INTERFACE: + { + GIrNodeInterface *iface = (GIrNodeInterface *)node; + + if (!check_needs_computation (node, module, iface->alignment)) + return; + + compute_struct_field_offsets (node, iface->members, + module, modules, + &iface->size, &iface->alignment); + break; + } case G_IR_NODE_UNION: { GIrNodeUnion *union_ = (GIrNodeUnion *)node; From 744f3a3004a7c4db32de9c21cf315f82f257b0e7 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Tue, 11 Nov 2008 22:02:37 +0000 Subject: [PATCH 154/692] =?UTF-8?q?Bug=20560404=20=E2=80=93=20Prefix=20typ?= =?UTF-8?q?es=20when=20resolving=20aliases=20in=20included=20modules?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * girepository/girparser.c: When resolving aliases in an included module, prefix types before looking them up. svn path=/trunk/; revision=889 --- girparser.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/girparser.c b/girparser.c index 74d7275ce..850833f37 100644 --- a/girparser.c +++ b/girparser.c @@ -478,19 +478,39 @@ resolve_aliases (ParseContext *ctx, const gchar *type) gpointer orig; gpointer value; GSList *seen_values = NULL; + const char *lookup; + char *prefixed; - seen_values = g_slist_prepend (seen_values, (char*)type); - while (g_hash_table_lookup_extended (ctx->aliases, type, &orig, &value)) + /* If we are in an included module, then we need to qualify the + * names of types before resolving them, since they will have + * been stored in the aliases qualified. + */ + if (ctx->prefix_aliases && strchr (type, '.') == NULL) { - g_debug ("Resolved: %s => %s", type, (char*)value); - type = value; - if (g_slist_find_custom (seen_values, type, + prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type); + lookup = prefixed; + } + else + lookup = type; + + seen_values = g_slist_prepend (seen_values, (char*)lookup); + while (g_hash_table_lookup_extended (ctx->aliases, lookup, &orig, &value)) + { + g_debug ("Resolved: %s => %s\n", lookup, (char*)value); + lookup = value; + if (g_slist_find_custom (seen_values, lookup, (GCompareFunc)strcmp) != NULL) break; - seen_values = g_slist_prepend (seen_values, (gchar*)type); + seen_values = g_slist_prepend (seen_values, (gchar*)lookup); } g_slist_free (seen_values); - return type; + + if (lookup == prefixed) + lookup = type; + + g_free (prefixed); + + return lookup; } static GIrNodeType * From 7bada628b9af036255f7ee0aebb32029c8352bae Mon Sep 17 00:00:00 2001 From: Johan Bilien Date: Wed, 12 Nov 2008 12:12:04 +0000 Subject: [PATCH 155/692] =?UTF-8?q?Bug=20560474=20=E2=80=93=20g-ir-compile?= =?UTF-8?q?r=20crashes=20when=20compiling=20the=20glib=20gir?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-11-12 Johan Bilien Bug 560474 – g-ir-compiler crashes when compiling the glib gir * girepository/girparser.c: avoid freeing an uninitialized pointer svn path=/trunk/; revision=891 --- girparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index 850833f37..38daaa70b 100644 --- a/girparser.c +++ b/girparser.c @@ -479,7 +479,7 @@ resolve_aliases (ParseContext *ctx, const gchar *type) gpointer value; GSList *seen_values = NULL; const char *lookup; - char *prefixed; + char *prefixed = NULL; /* If we are in an included module, then we need to qualify the * names of types before resolving them, since they will have From bc1f9c5bbbafb245b0d8a855aaf66e5bb3ba9379 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Wed, 12 Nov 2008 12:40:34 +0000 Subject: [PATCH 156/692] Add a g_irepository_get_search_path, so we can access the search paths 2008-11-12 Johan Dahlin * girepository/girepository.c (g_irepository_get_search_path): * girepository/girepository.h: Add a g_irepository_get_search_path, so we can access the search paths from runtime. svn path=/trunk/; revision=893 --- girepository.c | 15 +++++++++++++++ girepository.h | 1 + 2 files changed, 16 insertions(+) diff --git a/girepository.c b/girepository.c index dc9473a8b..392118d9c 100644 --- a/girepository.c +++ b/girepository.c @@ -137,6 +137,21 @@ g_irepository_prepend_search_path (const char *directory) search_path = g_slist_prepend (search_path, g_strdup (directory)); } +/** + * g_irepository_get_search_path: + * + * Returns the search path the GIRepository will use when looking for typelibs. + * The string is internal to GIRespository and should not be freed, nor should + * the elements. + * + * Return value: (element-type utf8) (transfer none): list of strings + */ +GSList * +g_irepository_get_search_path (void) +{ + return search_path; +} + static char * build_typelib_key (const char *name, const char *source) { diff --git a/girepository.h b/girepository.h index c40b6b749..225c1f89d 100644 --- a/girepository.h +++ b/girepository.h @@ -77,6 +77,7 @@ typedef enum GType g_irepository_get_type (void) G_GNUC_CONST; GIRepository *g_irepository_get_default (void); void g_irepository_prepend_search_path (const char *directory); +GSList * g_irepository_get_search_path (void); const char * g_irepository_load_typelib (GIRepository *repository, GTypelib *typelib, GIRepositoryLoadFlags flags, From afe696cafd391f46066c983feaa819966c1d8403 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Wed, 12 Nov 2008 12:59:01 +0000 Subject: [PATCH 157/692] Change the element type from utf8 to filename Special case filename 2008-11-12 Johan Dahlin * girepository/girepository.c: Change the element type from utf8 to filename * girepository/girnode.c (g_ir_node_build_typelib): Special case filename equally to utf8 here. svn path=/trunk/; revision=895 --- girepository.c | 2 +- girnode.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/girepository.c b/girepository.c index 392118d9c..0a4d4ebdd 100644 --- a/girepository.c +++ b/girepository.c @@ -144,7 +144,7 @@ g_irepository_prepend_search_path (const char *directory) * The string is internal to GIRespository and should not be freed, nor should * the elements. * - * Return value: (element-type utf8) (transfer none): list of strings + * Return value: (element-type filename) (transfer none): list of strings */ GSList * g_irepository_get_search_path (void) diff --git a/girnode.c b/girnode.c index 87b418c8f..92998ed36 100644 --- a/girnode.c +++ b/girnode.c @@ -1366,7 +1366,8 @@ g_ir_node_build_typelib (GIrNode *node, *offset += 4; if (type->tag < GI_TYPE_TAG_ARRAY || - type->tag == GI_TYPE_TAG_UTF8) + type->tag == GI_TYPE_TAG_UTF8 || + type->tag == GI_TYPE_TAG_FILENAME) { blob->reserved = 0; blob->reserved2 = 0; From 092901f3abcff5a58ff65c369a4db91ef473f155 Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Wed, 12 Nov 2008 14:42:13 +0000 Subject: [PATCH 158/692] Fix minor memory leak. 2008-11-12 Tommi Komulainen * girepository/girepository.c (find_namespace_latest): Fix minor memory leak. svn path=/trunk/; revision=899 --- girepository.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/girepository.c b/girepository.c index 0a4d4ebdd..0ff7bddf0 100644 --- a/girepository.c +++ b/girepository.c @@ -1015,12 +1015,13 @@ find_namespace_latest (const gchar *namespace, candidates = g_slist_sort (candidates, (GCompareFunc) compare_candidate_reverse); elected = (struct NamespaceVersionCandidadate *) candidates->data; - /* Remove the elected one so we don't try to free it */ + /* Remove the elected one so we don't try to free its contents */ candidates = g_slist_delete_link (candidates, candidates); result = elected->mfile; *path_ret = elected->path; *version_ret = elected->version; + g_free (elected); /* just free the container */ g_slist_foreach (candidates, (GFunc) free_candidate, NULL); g_slist_free (candidates); } From 0faf142d0aa568d2fad714f638f713ae715cd7d0 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Wed, 12 Nov 2008 17:16:42 +0000 Subject: [PATCH 159/692] Add a GirParser object to hold the state of a compilation Add a toplevel GirParser object to hold state that is global across a compilation. Currently just holds the include path, but will eventually also keep a cached list of parsed modules. svn path=/trunk/; revision=901 --- girparser.c | 100 +++++++++++++++++++++++++++++++++++++++++----------- girparser.h | 21 ++++++----- 2 files changed, 92 insertions(+), 29 deletions(-) diff --git a/girparser.c b/girparser.c index 38daaa70b..e41d69661 100644 --- a/girparser.c +++ b/girparser.c @@ -28,6 +28,12 @@ #include "girnode.h" #include "gtypelib.h" +struct _GIrParser +{ + gchar **includes; + GList *include_modules; /* All previously parsed include modules */ +}; + typedef enum { STATE_START, @@ -66,11 +72,11 @@ typedef enum typedef struct _ParseContext ParseContext; struct _ParseContext { + GIrParser *parser; + ParseState state; ParseState prev_state; - const char * const*includes; - GList *modules; GList *include_modules; gboolean prefix_aliases; @@ -107,7 +113,7 @@ static void cleanup (GMarkupParseContext *context, GError *error, gpointer user_data); -static GMarkupParser parser = +static GMarkupParser markup_parser = { start_element_handler, end_element_handler, @@ -128,6 +134,34 @@ static const gchar *find_attribute (const gchar *name, const gchar **attribute_names, const gchar **attribute_values); + +GIrParser * +g_ir_parser_new (void) +{ + GIrParser *parser = g_slice_new0 (GIrParser); + + return parser; +} + +void +g_ir_parser_free (GIrParser *parser) +{ + if (parser->includes) + g_strfreev (parser->includes); + + g_slice_free (GIrParser, parser); +} + +void +g_ir_parser_set_includes (GIrParser *parser, + const gchar *const *includes) +{ + if (parser->includes) + g_strfreev (parser->includes); + + parser->includes = g_strdupv ((char **)includes); +} + static void firstpass_start_element_handler (GMarkupParseContext *context, const gchar *element_name, @@ -187,7 +221,9 @@ static GMarkupParser firstpass_parser = }; static char * -locate_gir (const char *name, const char *version, const char * const* extra_paths) +locate_gir (GIrParser *parser, + const char *name, + const char *version) { const gchar *const *datadirs; const gchar *const *dir; @@ -198,9 +234,9 @@ locate_gir (const char *name, const char *version, const char * const* extra_pat girname = g_strdup_printf ("%s-%s.gir", name, version); - if (extra_paths != NULL) + if (parser->includes != NULL) { - for (dir = extra_paths; *dir; dir++) + for (dir = (const gchar *const *)parser->includes; *dir; dir++) { path = g_build_filename (*dir, girname, NULL); if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) @@ -2183,7 +2219,7 @@ parse_include (GMarkupParseContext *context, } } - girpath = locate_gir (name, version, ctx->includes); + girpath = locate_gir (ctx->parser, name, version); if (girpath == NULL) { @@ -2204,8 +2240,8 @@ parse_include (GMarkupParseContext *context, } g_free (girpath); + sub_ctx.parser = ctx->parser; sub_ctx.state = STATE_START; - sub_ctx.includes = ctx->includes; sub_ctx.prefix_aliases = TRUE; sub_ctx.namespace = name; sub_ctx.aliases = ctx->aliases; @@ -2222,7 +2258,7 @@ parse_include (GMarkupParseContext *context, g_markup_parse_context_free (context); - context = g_markup_parse_context_new (&parser, 0, &sub_ctx, NULL); + context = g_markup_parse_context_new (&markup_parser, 0, &sub_ctx, NULL); if (!g_markup_parse_context_parse (context, buffer, length, error)) goto out; @@ -2958,18 +2994,29 @@ post_filter (GIrModule *module) } } -GList * -g_ir_parse_string (const gchar *namespace, - const gchar *const *includes, - const gchar *buffer, - gssize length, - GError **error) +/** + * g_ir_parser_parse_string: + * @parser: a #GIrParser + * @error: return location for a #GError, or %NULL + * + * Parse a string that holds a complete GIR XML file, and return a list of a + * a #GirModule for each <namespace/> element within the file. + * + * @returns: a newly allocated list of #GIrModule. The modules themselves + * are owned by the #GIrParser and will be freed along with the parser. + */ +GList * +g_ir_parser_parse_string (GIrParser *parser, + const gchar *namespace, + const gchar *buffer, + gssize length, + GError **error) { ParseContext ctx = { 0 }; GMarkupParseContext *context; + ctx.parser = parser; ctx.state = STATE_START; - ctx.includes = includes; ctx.prefix_aliases = FALSE; ctx.namespace = namespace; ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); @@ -2988,7 +3035,7 @@ g_ir_parse_string (const gchar *namespace, g_markup_parse_context_free (context); - context = g_markup_parse_context_new (&parser, 0, &ctx, NULL); + context = g_markup_parse_context_new (&markup_parser, 0, &ctx, NULL); if (!g_markup_parse_context_parse (context, buffer, length, error)) goto out; @@ -3005,10 +3052,21 @@ g_ir_parse_string (const gchar *namespace, return ctx.modules; } +/** + * g_ir_parser_parse_file: + * @parser: a #GIrParser + * @error: return location for a #GError, or %NULL + * + * Parse GIR XML file, and return a list of a a #GirModule for each + * <namespace/> element within the file. + * + * @returns: a newly allocated list of #GIrModule. The modules themselves + * are owned by the #GIrParser and will be freed along with the parser. + */ GList * -g_ir_parse_file (const gchar *filename, - const gchar *const *includes, - GError **error) +g_ir_parser_parse_file (GIrParser *parser, + const gchar *filename, + GError **error) { gchar *buffer; gsize length; @@ -3038,7 +3096,7 @@ g_ir_parse_file (const gchar *filename, if (!g_file_get_contents (filename, &buffer, &length, error)) return NULL; - modules = g_ir_parse_string (namespace, includes, buffer, length, error); + modules = g_ir_parser_parse_string (parser, namespace, buffer, length, error); for (iter = modules; iter; iter = iter->next) { diff --git a/girparser.h b/girparser.h index 08aecb971..ac0d216b2 100644 --- a/girparser.h +++ b/girparser.h @@ -25,16 +25,21 @@ G_BEGIN_DECLS +typedef struct _GIrParser GIrParser; -GList *g_ir_parse_string (const gchar *namespace, - const gchar *const *includes, - const gchar *buffer, - gssize length, - GError **error); -GList *g_ir_parse_file (const gchar *filename, - const gchar *const *includes, - GError **error); +GIrParser *g_ir_parser_new (void); +void g_ir_parser_free (GIrParser *parser); +void g_ir_parser_set_includes (GIrParser *parser, + const gchar *const *includes); +GList *g_ir_parser_parse_string (GIrParser *parser, + const gchar *namespace, + const gchar *buffer, + gssize length, + GError **error); +GList *g_ir_parser_parse_file (GIrParser *parser, + const gchar *filename, + GError **error); G_END_DECLS From 102e08428bb99103d6405c86e960ad8de2e9d6b4 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Wed, 12 Nov 2008 17:16:49 +0000 Subject: [PATCH 160/692] Only allow one element per (#560419) The logic in girparser.c didn't work very well if there were multiple nodes within a single (context->namespace was always the overall filename and not the the name specified in the element for one thing; this would cause aliases to be mis-prefixed in include modules.) Also check that the "name" in the node matches the filename. svn path=/trunk/; revision=902 --- girparser.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index e41d69661..6601fcca2 100644 --- a/girparser.c +++ b/girparser.c @@ -2457,7 +2457,16 @@ start_element_handler (GMarkupParseContext *context, if (strcmp (element_name, "namespace") == 0 && ctx->state == STATE_REPOSITORY) { const gchar *name, *version, *shared_library; - + + if (ctx->current_module != NULL) + { + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Only one element is currently allowed per "); + goto out; + } + name = find_attribute ("name", attribute_names, attribute_values); version = find_attribute ("version", attribute_names, attribute_values); shared_library = find_attribute ("shared-library", attribute_names, attribute_values); @@ -2468,6 +2477,13 @@ start_element_handler (GMarkupParseContext *context, MISSING_ATTRIBUTE (context, error, element_name, "version"); else { + if (strcmp (name, ctx->namespace) != 0) + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + " name element '%s' doesn't match file name '%s'", + name, ctx->namespace); + ctx->current_module = g_ir_module_new (name, version, shared_library); ctx->modules = g_list_append (ctx->modules, ctx->current_module); ctx->current_module->dependencies = ctx->dependencies; @@ -3073,6 +3089,7 @@ g_ir_parser_parse_file (GIrParser *parser, GList *modules; GList *iter; const char *slash; + char *dash; char *namespace; if (!g_str_has_suffix (filename, ".gir")) @@ -3093,6 +3110,11 @@ g_ir_parser_parse_file (GIrParser *parser, namespace = g_strdup (slash+1); namespace[strlen(namespace)-4] = '\0'; + /* Remove version */ + dash = strstr (namespace, "-"); + if (dash != NULL) + *dash = '\0'; + if (!g_file_get_contents (filename, &buffer, &length, error)) return NULL; From b1c6e640491b87b30af15a20891a5f20e2f11d6d Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Wed, 12 Nov 2008 17:17:01 +0000 Subject: [PATCH 161/692] Keep aliases and disguised_structures local to each module (#560419) When parsing, keep keep a separate hash tables of aliases and 'disguised' flags for each module, and store that on the module. After parsing an include merge the aliases/disguised flags to the including module. Remove 'prefix_aliases' flag and always prefix aliases/disguised structure types when parsing; this simplifies the code considerably. svn path=/trunk/; revision=904 --- girmodule.c | 44 ++++++++++++++++- girmodule.h | 12 +++++ girparser.c | 138 ++++++++++++++++++++++++++-------------------------- 3 files changed, 123 insertions(+), 71 deletions(-) diff --git a/girmodule.c b/girmodule.c index 91cc02d8a..1b7c3048c 100644 --- a/girmodule.c +++ b/girmodule.c @@ -46,6 +46,9 @@ g_ir_module_new (const gchar *name, module->dependencies = NULL; module->entries = NULL; + module->include_modules = NULL; + module->aliases = NULL; + return module; } @@ -62,13 +65,50 @@ g_ir_module_free (GIrModule *module) g_list_free (module->entries); /* Don't free dependencies, we inherit that from the parser */ - /* FIXME: we leak the included modules themelves; they may be shared - * between multiple modules, so we would need refcounting */ g_list_free (module->include_modules); + g_hash_table_destroy (module->aliases); + g_hash_table_destroy (module->disguised_structures); + g_free (module); } +static void +add_alias_foreach (gpointer key, + gpointer value, + gpointer data) +{ + GIrModule *module = data; + + g_hash_table_replace (module->aliases, g_strdup (key), g_strdup (value)); +} + +static void +add_disguised_structure_foreach (gpointer key, + gpointer value, + gpointer data) +{ + GIrModule *module = data; + + g_hash_table_replace (module->disguised_structures, g_strdup (key), value); +} + +void +g_ir_module_add_include_module (GIrModule *module, + GIrModule *include_module) +{ + module->include_modules = g_list_prepend (module->include_modules, + include_module); + + g_hash_table_foreach (include_module->aliases, + add_alias_foreach, + module); + + g_hash_table_foreach (include_module->disguised_structures, + add_disguised_structure_foreach, + module); +} + GTypelib * g_ir_module_build_typelib (GIrModule *module, GList *modules) diff --git a/girmodule.h b/girmodule.h index 5008c4e97..c658e179b 100644 --- a/girmodule.h +++ b/girmodule.h @@ -36,7 +36,16 @@ struct _GIrModule gchar *shared_library; GList *dependencies; GList *entries; + + /* All modules that are included directly or indirectly */ GList *include_modules; + + /* Aliases defined in the module or in included modules */ + GHashTable *aliases; + + /* Structures with the 'disguised' flag (typedef struct _X *X) + * in the module or in included modules */ + GHashTable *disguised_structures; }; GIrModule *g_ir_module_new (const gchar *name, @@ -44,6 +53,9 @@ GIrModule *g_ir_module_new (const gchar *name, const gchar *module_filename); void g_ir_module_free (GIrModule *module); +void g_ir_module_add_include_module (GIrModule *module, + GIrModule *include_module); + GTypelib * g_ir_module_build_typelib (GIrModule *module, GList *modules); diff --git a/girparser.c b/girparser.c index 6601fcca2..fcd9dadea 100644 --- a/girparser.c +++ b/girparser.c @@ -79,7 +79,6 @@ struct _ParseContext GList *modules; GList *include_modules; - gboolean prefix_aliases; GList *dependencies; GHashTable *aliases; GHashTable *disguised_structures; @@ -189,15 +188,7 @@ firstpass_start_element_handler (GMarkupParseContext *context, { char *key; - if (ctx->prefix_aliases) - { - key = g_strdup_printf ("%s.%s", ctx->namespace, name); - } - else - { - key = g_strdup (name); - } - + key = g_strdup_printf ("%s.%s", ctx->namespace, name); g_hash_table_replace (ctx->disguised_structures, key, GINT_TO_POINTER (1)); } } @@ -514,23 +505,22 @@ resolve_aliases (ParseContext *ctx, const gchar *type) gpointer orig; gpointer value; GSList *seen_values = NULL; - const char *lookup; - char *prefixed = NULL; + const gchar *lookup; + gchar *prefixed; - /* If we are in an included module, then we need to qualify the - * names of types before resolving them, since they will have - * been stored in the aliases qualified. - */ - if (ctx->prefix_aliases && strchr (type, '.') == NULL) + if (strchr (type, '.') == NULL) { prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type); lookup = prefixed; } else - lookup = type; + { + lookup = type; + prefixed = NULL; + } seen_values = g_slist_prepend (seen_values, (char*)lookup); - while (g_hash_table_lookup_extended (ctx->aliases, lookup, &orig, &value)) + while (g_hash_table_lookup_extended (ctx->current_module->aliases, lookup, &orig, &value)) { g_debug ("Resolved: %s => %s\n", lookup, (char*)value); lookup = value; @@ -543,12 +533,38 @@ resolve_aliases (ParseContext *ctx, const gchar *type) if (lookup == prefixed) lookup = type; - + g_free (prefixed); return lookup; } +static gboolean +is_disguised_structure (ParseContext *ctx, const gchar *type) +{ + const gchar *lookup; + gchar *prefixed; + gboolean result; + + if (strchr (type, '.') == NULL) + { + prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type); + lookup = prefixed; + } + else + { + lookup = type; + prefixed = NULL; + } + + result = g_hash_table_lookup (ctx->current_module->disguised_structures, + lookup) != NULL; + + g_free (prefixed); + + return result; +} + static GIrNodeType * parse_type (ParseContext *ctx, const gchar *type) { @@ -1062,25 +1078,18 @@ start_alias (GMarkupParseContext *context, } value = g_strdup (target); - if (ctx->prefix_aliases) + key = g_strdup_printf ("%s.%s", ctx->namespace, name); + if (!strchr (target, '.')) { - key = g_strdup_printf ("%s.%s", ctx->namespace, name); - if (!strchr (target, '.')) + const BasicTypeInfo *basic = parse_basic (target); + if (!basic) { - const BasicTypeInfo *basic = parse_basic (target); - if (!basic) - { - g_free (value); - /* For non-basic types, re-qualify the interface */ - value = g_strdup_printf ("%s.%s", ctx->namespace, target); - } + g_free (value); + /* For non-basic types, re-qualify the interface */ + value = g_strdup_printf ("%s.%s", ctx->namespace, target); } } - else - { - key = g_strdup (name); - } - g_hash_table_insert (ctx->aliases, key, value); + g_hash_table_replace (ctx->aliases, key, value); return TRUE; } @@ -1660,7 +1669,7 @@ start_type (GMarkupParseContext *context, * doesn't look like a pointer, but is internally. */ if (typenode->tag == GI_TYPE_TAG_INTERFACE && - g_hash_table_lookup (ctx->disguised_structures, typenode->interface) != NULL) + is_disguised_structure (ctx, typenode->interface)) is_pointer = TRUE; if (is_pointer) @@ -2190,11 +2199,11 @@ parse_include (GMarkupParseContext *context, const char *version, GError **error) { - ParseContext sub_ctx = { 0 }; gchar *buffer; gsize length; char *girpath; gboolean success = FALSE; + GList *modules; GList *l; for (l = ctx->include_modules; l; l = l->next) @@ -2240,38 +2249,12 @@ parse_include (GMarkupParseContext *context, } g_free (girpath); - sub_ctx.parser = ctx->parser; - sub_ctx.state = STATE_START; - sub_ctx.prefix_aliases = TRUE; - sub_ctx.namespace = name; - sub_ctx.aliases = ctx->aliases; - sub_ctx.disguised_structures = ctx->disguised_structures; - sub_ctx.type_depth = 0; + modules = g_ir_parser_parse_string (ctx->parser, name, buffer, length, error); + success = error != NULL; - context = g_markup_parse_context_new (&firstpass_parser, 0, &sub_ctx, NULL); - - if (!g_markup_parse_context_parse (context, buffer, length, error)) - goto out; - - if (!g_markup_parse_context_end_parse (context, error)) - goto out; - - g_markup_parse_context_free (context); - - context = g_markup_parse_context_new (&markup_parser, 0, &sub_ctx, NULL); - if (!g_markup_parse_context_parse (context, buffer, length, error)) - goto out; - - if (!g_markup_parse_context_end_parse (context, error)) - goto out; - - success = TRUE; - - out: ctx->include_modules = g_list_concat (ctx->include_modules, - sub_ctx.modules); + modules); - g_markup_parse_context_free (context); g_free (buffer); return success; @@ -2477,6 +2460,8 @@ start_element_handler (GMarkupParseContext *context, MISSING_ATTRIBUTE (context, error, element_name, "version"); else { + GList *l; + if (strcmp (name, ctx->namespace) != 0) g_set_error (error, G_MARKUP_ERROR, @@ -2485,6 +2470,15 @@ start_element_handler (GMarkupParseContext *context, name, ctx->namespace); ctx->current_module = g_ir_module_new (name, version, shared_library); + + ctx->current_module->aliases = ctx->aliases; + ctx->aliases = NULL; + ctx->current_module->disguised_structures = ctx->disguised_structures; + ctx->disguised_structures = NULL; + + for (l = ctx->include_modules; l; l = l->next) + g_ir_module_add_include_module (ctx->current_module, l->data); + ctx->modules = g_list_append (ctx->modules, ctx->current_module); ctx->current_module->dependencies = ctx->dependencies; ctx->current_module->include_modules = g_list_copy (ctx->include_modules); @@ -3033,7 +3027,6 @@ g_ir_parser_parse_string (GIrParser *parser, ctx.parser = parser; ctx.state = STATE_START; - ctx.prefix_aliases = FALSE; ctx.namespace = namespace; ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); ctx.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); @@ -3060,8 +3053,15 @@ g_ir_parser_parse_string (GIrParser *parser, out: - g_hash_table_destroy (ctx.aliases); - g_hash_table_destroy (ctx.disguised_structures); + if (ctx.modules == NULL) + { + /* If we have a module, then ownership is transferred to the module */ + + if (ctx.aliases != NULL) + g_hash_table_destroy (ctx.aliases); + if (ctx.disguised_structures != NULL) + g_hash_table_destroy (ctx.disguised_structures); + } g_markup_parse_context_free (context); From 9a36a189396b98283fa24b3c0712b7d8a34b89d5 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Wed, 12 Nov 2008 17:17:08 +0000 Subject: [PATCH 162/692] Fix management of ParseContext.includes_modules (#560419) Fix some trivial bugs in managing the list of include modules. (Add to module's list twice, not initialized to NULL, not freed.) svn path=/trunk/; revision=905 --- girparser.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/girparser.c b/girparser.c index fcd9dadea..198d78baa 100644 --- a/girparser.c +++ b/girparser.c @@ -2479,9 +2479,11 @@ start_element_handler (GMarkupParseContext *context, for (l = ctx->include_modules; l; l = l->next) g_ir_module_add_include_module (ctx->current_module, l->data); + g_list_free (ctx->include_modules); + ctx->include_modules = NULL; + ctx->modules = g_list_append (ctx->modules, ctx->current_module); ctx->current_module->dependencies = ctx->dependencies; - ctx->current_module->include_modules = g_list_copy (ctx->include_modules); state_switch (ctx, STATE_NAMESPACE); goto out; @@ -3028,6 +3030,7 @@ g_ir_parser_parse_string (GIrParser *parser, ctx.parser = parser; ctx.state = STATE_START; ctx.namespace = namespace; + ctx.include_modules = NULL; ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); ctx.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); ctx.type_depth = 0; @@ -3055,12 +3058,14 @@ g_ir_parser_parse_string (GIrParser *parser, if (ctx.modules == NULL) { - /* If we have a module, then ownership is transferred to the module */ - + /* An error occurred before we created a module, so we haven't + * transferred ownership of these hash tables to the module. + */ if (ctx.aliases != NULL) g_hash_table_destroy (ctx.aliases); if (ctx.disguised_structures != NULL) g_hash_table_destroy (ctx.disguised_structures); + g_list_free (ctx.include_modules); } g_markup_parse_context_free (context); From 7fa1ffa6e7d3861372773861197429d15ab9f603 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Wed, 12 Nov 2008 17:17:15 +0000 Subject: [PATCH 163/692] =?UTF-8?q?Bug=20560419=20=E2=80=93=20Cache=20incl?= =?UTF-8?q?udes=20when=20parsing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep track of all modules parsed within a GIrParser, and when a module is referenced a second time, use the existing parsed copy instead of reparsing. svn path=/trunk/; revision=906 --- girparser.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/girparser.c b/girparser.c index 198d78baa..65ba28290 100644 --- a/girparser.c +++ b/girparser.c @@ -31,7 +31,7 @@ struct _GIrParser { gchar **includes; - GList *include_modules; /* All previously parsed include modules */ + GList *parsed_modules; /* All previously parsed modules */ }; typedef enum @@ -145,9 +145,14 @@ g_ir_parser_new (void) void g_ir_parser_free (GIrParser *parser) { + GList *l; + if (parser->includes) g_strfreev (parser->includes); + for (l = parser->parsed_modules; l; l = l->next) + g_ir_module_free (l->data); + g_slice_free (GIrParser, parser); } @@ -2206,7 +2211,7 @@ parse_include (GMarkupParseContext *context, GList *modules; GList *l; - for (l = ctx->include_modules; l; l = l->next) + for (l = ctx->parser->parsed_modules; l; l = l->next) { GIrModule *m = l->data; @@ -2214,6 +2219,8 @@ parse_include (GMarkupParseContext *context, { if (strcmp (m->version, version) == 0) { + ctx->include_modules = g_list_prepend (ctx->include_modules, m); + return TRUE; } else @@ -3054,6 +3061,9 @@ g_ir_parser_parse_string (GIrParser *parser, if (!g_markup_parse_context_end_parse (context, error)) goto out; + parser->parsed_modules = g_list_concat (g_list_copy (ctx.modules), + parser->parsed_modules); + out: if (ctx.modules == NULL) From 1ffeeab3d43c5765d72aeb4aa01a93e2fca98bae Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 13 Nov 2008 19:57:09 +0000 Subject: [PATCH 164/692] g_irepository_dump implementation svn path=/trunk/; revision=911 --- Makefile.am | 6 ++++-- girepository.c | 25 +++++++++++++++++++++++++ girepository.h | 4 ++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index c3694fd11..b58288e8b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,9 +13,11 @@ libgirepository_la_SOURCES = \ gtypelib.h \ gtypelib.c \ ginfo.c \ - ginvoke.c \ girffi.c \ - girffi.h + girffi.h \ + gdump.c \ + ginvoke.c + libgirepository_la_CPPFLAGS = $(GIREPO_CFLAGS) libgirepository_la_LIBADD = $(GIREPO_LIBS) libgirepository_la_LDFLAGS = -no-undefined diff --git a/girepository.c b/girepository.c index 0ff7bddf0..e65910de4 100644 --- a/girepository.c +++ b/girepository.c @@ -1145,6 +1145,31 @@ g_irepository_require (GIRepository *repository, return ret; } +static gboolean +g_irepository_introspect_cb (const char *option_name, + const char *value, + gpointer data, + GError **error) +{ + return g_irepository_dump (value, error); +} + +static const GOptionEntry introspection_args[] = { + { "introspect-dump", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK, + g_irepository_introspect_cb, "Dump introspection information", + "infile.txt,outfile.xml" }, + { NULL } +}; + +GOptionGroup * +g_irepository_get_option_group (void) +{ + GOptionGroup *group; + group = g_option_group_new ("girepository", "Introspection Options", "Show Introspection Options", NULL, NULL); + + g_option_group_add_entries (group, introspection_args); + return group; +} GQuark g_irepository_error_quark (void) diff --git a/girepository.h b/girepository.h index 225c1f89d..46082e037 100644 --- a/girepository.h +++ b/girepository.h @@ -110,6 +110,10 @@ const gchar * g_irepository_get_shared_library (GIRepository *repository, const gchar * g_irepository_get_version (GIRepository *repository, const gchar *namespace); +GOptionGroup * g_irepository_get_option_group (void); + +gboolean g_irepository_dump (const char *arg, GError **error); + /* Typelib */ GTypelib * g_typelib_new_from_memory (guchar *memory, From a610d8cbb4fb9b631d2fa915732c98cd3db89d63 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 13 Nov 2008 20:13:39 +0000 Subject: [PATCH 165/692] Add new files from last commit svn path=/trunk/; revision=913 --- gdump.c | 386 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 386 insertions(+) create mode 100644 gdump.c diff --git a/gdump.c b/gdump.c new file mode 100644 index 000000000..90ca27c51 --- /dev/null +++ b/gdump.c @@ -0,0 +1,386 @@ +/* GObject introspection: Dump introspection data + * + * Copyright (C) 2008 Colin Walters + * + * 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 + +#include "girepository.h" +#include "config.h" + +#include + +static void +escaped_printf (GOutputStream *out, const char *fmt, ...) +{ + char *str; + va_list args; + gsize written; + GError *error = NULL; + + va_start (args, fmt); + + str = g_markup_vprintf_escaped (fmt, args); + if (!g_output_stream_write_all (out, str, strlen (str), &written, NULL, &error)) + { + g_critical ("failed to write to iochannel: %s", error->message); + g_clear_error (&error); + } + g_free (str); + + va_end (args); +} + +static void +goutput_write (GOutputStream *out, const char *str) +{ + gsize written; + GError *error = NULL; + if (!g_output_stream_write_all (out, str, strlen (str), &written, NULL, &error)) + { + g_critical ("failed to write to iochannel: %s", error->message); + g_clear_error (&error); + } +} + +typedef GType (*GetTypeFunc)(void); + +static GType +invoke_get_type (GModule *self, const char *symbol, GError **error) +{ + GetTypeFunc sym; + + if (!g_module_symbol (self, symbol, (void**)&sym)) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Failed to find symbol '%s'", symbol); + return G_TYPE_INVALID; + } + + return sym (); +} + +static void +dump_properties (GType type, GOutputStream *out) +{ + guint i; + guint n_properties; + GParamSpec **props; + + if (G_TYPE_FUNDAMENTAL (type) == G_TYPE_OBJECT) + { + GObjectClass *klass; + klass = g_type_class_ref (type); + props = g_object_class_list_properties (klass, &n_properties); + } + else + { + void *klass; + klass = g_type_default_interface_ref (type); + props = g_object_interface_list_properties (klass, &n_properties); + } + + for (i = 0; i < n_properties; i++) + { + GParamSpec *prop; + + prop = props[i]; + if (prop->owner_type != type) + continue; + + escaped_printf (out, " \n", + prop->name, g_type_name (prop->value_type), prop->flags); + } + g_free (props); +} + +static void +dump_signals (GType type, GOutputStream *out) +{ + guint i; + guint n_sigs; + guint *sig_ids; + + sig_ids = g_signal_list_ids (type, &n_sigs); + for (i = 0; i < n_sigs; i++) + { + guint sigid; + GSignalQuery query; + guint j; + + sigid = sig_ids[i]; + g_signal_query (sigid, &query); + + escaped_printf (out, " \n", + query.signal_name, g_type_name (query.return_type)); + + for (j = 0; j < query.n_params; j++) + { + escaped_printf (out, " \n", + g_type_name (query.param_types[j])); + } + goutput_write (out, " \n"); + } +} + +static void +dump_object_type (GType type, const char *symbol, GOutputStream *out) +{ + guint n_interfaces; + guint i; + GType *interfaces; + + escaped_printf (out, " \n"); + + interfaces = g_type_interfaces (type, &n_interfaces); + for (i = 0; i < n_interfaces; i++) + { + GType itype = interfaces[i]; + escaped_printf (out, " \n", + g_type_name (itype)); + } + dump_properties (type, out); + dump_signals (type, out); + goutput_write (out, " \n"); +} + +static void +dump_interface_type (GType type, const char *symbol, GOutputStream *out) +{ + guint n_interfaces; + guint i; + GType *interfaces; + + escaped_printf (out, " \n", + g_type_name (type), symbol); + + interfaces = g_type_interface_prerequisites (type, &n_interfaces); + for (i = 0; i < n_interfaces; i++) + { + GType itype = interfaces[i]; + escaped_printf (out, " %s\n", + g_type_name (itype)); + } + dump_properties (type, out); + dump_signals (type, out); + goutput_write (out, " \n"); +} + +static void +dump_boxed_type (GType type, const char *symbol, GOutputStream *out) +{ + escaped_printf (out, " \n", + g_type_name (type), symbol); +} + +static void +dump_flags_type (GType type, const char *symbol, GOutputStream *out) +{ + guint i; + GFlagsClass *klass; + + klass = g_type_class_ref (type); + escaped_printf (out, " \n", + g_type_name (type), symbol); + + for (i = 0; i < klass->n_values; i++) + { + GFlagsValue *value = &(klass->values[i]); + + escaped_printf (out, " \n", + value->value_name, value->value_nick, value->value); + } + goutput_write (out, " \n"); +} + +static void +dump_enum_type (GType type, const char *symbol, GOutputStream *out) +{ + guint i; + GEnumClass *klass; + + klass = g_type_class_ref (type); + escaped_printf (out, " \n", + g_type_name (type), symbol); + + for (i = 0; i < klass->n_values; i++) + { + GEnumValue *value = &(klass->values[i]); + + escaped_printf (out, " \n", + value->value_name, value->value_nick, value->value); + } + goutput_write (out, " "); +} + +static void +dump_type (GType type, const char *symbol, GOutputStream *out) +{ + g_printerr ("processing %s\n", g_type_name (type)); + switch (g_type_fundamental (type)) + { + case G_TYPE_OBJECT: + dump_object_type (type, symbol, out); + break; + case G_TYPE_INTERFACE: + dump_interface_type (type, symbol, out); + break; + case G_TYPE_BOXED: + dump_boxed_type (type, symbol, out); + break; + case G_TYPE_FLAGS: + dump_flags_type (type, symbol, out); + break; + case G_TYPE_ENUM: + dump_enum_type (type, symbol, out); + break; + case G_TYPE_POINTER: + /* GValue, etc. Just skip them. */ + break; + default: + g_warning ("unhandled gtype %s", g_type_name (type)); + } +} + +/** + * g_irepository_dump: + * @arg: Comma-separated pair of input and output filenames + * @error: a %GError + * + * Argument specified is a comma-separated pair of filenames; i.e. of + * the form "input.txt,output.xml". The input file should be a + * UTF-8 Unix-line-ending text file, with each line containing the name + * of a GType _get_type function. + * + * The output file should already exist, but be empty. This function will + * overwrite its contents. + * + * Returns: %TRUE on success, %FALSE on error + */ +gboolean +g_irepository_dump (const char *arg, GError **error) +{ + GHashTable *output_types; + char **args; + GFile *input_file; + GFile *output_file; + GFileInputStream *input; + GFileOutputStream *output; + GDataInputStream *in; + GModule *self; + gboolean caught_error = FALSE; + + self = g_module_open (NULL, 0); + if (!self) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "failed to open self: %s", + g_module_error ()); + return FALSE; + } + + args = g_strsplit (arg, ",", 2); + + input_file = g_file_new_for_path (args[0]); + output_file = g_file_new_for_path (args[1]); + + input = g_file_read (input_file, NULL, error); + if (input == NULL) + return FALSE; + + output = g_file_replace (output_file, NULL, FALSE, 0, NULL, error); + if (output == NULL) + { + g_input_stream_close (G_INPUT_STREAM (input), NULL, NULL); + return FALSE; + } + + goutput_write (G_OUTPUT_STREAM (output), "\n"); + goutput_write (G_OUTPUT_STREAM (output), "\n"); + + output_types = g_hash_table_new (NULL, NULL); + + in = g_data_input_stream_new (G_INPUT_STREAM (input)); + g_object_unref (input); + + while (TRUE) + { + gsize len; + char *line = g_data_input_stream_read_line (in, &len, NULL, NULL); + GType type; + + if (line == NULL || *line == '\0') + { + g_free (line); + break; + } + + g_strchomp (line); + type = invoke_get_type (self, line, error); + + if (type == G_TYPE_INVALID) + { + caught_error = TRUE; + g_free (line); + break; + } + + if (g_hash_table_lookup (output_types, (gpointer) type)) + goto next; + g_hash_table_insert (output_types, (gpointer) type, (gpointer) type); + + dump_type (type, line, G_OUTPUT_STREAM (output)); + + next: + g_free (line); + } + + g_hash_table_destroy (output_types); + + goutput_write (G_OUTPUT_STREAM (output), "\n"); + + { + GError **ioerror; + /* Avoid overwriting an earlier set error */ + if (caught_error) + ioerror = NULL; + else + ioerror = error; + if (!g_input_stream_close (G_INPUT_STREAM (in), NULL, ioerror)) + return FALSE; + if (!g_output_stream_close (G_OUTPUT_STREAM (output), NULL, ioerror)) + return FALSE; + } + + return !caught_error; +} From fd1fe6c0b6ede3ae59710dbfab24a24b90414ac6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 13 Nov 2008 20:21:05 +0000 Subject: [PATCH 166/692] Remove processing msg svn path=/trunk/; revision=915 --- gdump.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gdump.c b/gdump.c index 90ca27c51..b26b0e854 100644 --- a/gdump.c +++ b/gdump.c @@ -244,7 +244,6 @@ dump_enum_type (GType type, const char *symbol, GOutputStream *out) static void dump_type (GType type, const char *symbol, GOutputStream *out) { - g_printerr ("processing %s\n", g_type_name (type)); switch (g_type_fundamental (type)) { case G_TYPE_OBJECT: From 3b0bf76d2129655603aded659fc057341badf66f Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Thu, 13 Nov 2008 21:38:42 +0000 Subject: [PATCH 167/692] girepository/girffi.c: Fix "Unexpected time for time_t" message. svn path=/trunk/; revision=919 --- girffi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girffi.c b/girffi.c index db5e87e84..d6eefb273 100644 --- a/girffi.c +++ b/girffi.c @@ -75,7 +75,7 @@ g_ir_ffi_get_ffi_type (GITypeTag tag) #elif SIZEOF_TIME_T == 8 return &ffi_type_sint64; #else -# error "Unexpected time for time_t: not 4 or 8" +# error "Unexpected size for time_t: not 4 or 8" #endif case GI_TYPE_TAG_ULONG: return &ffi_type_ulong; From 02020aeb2059070ad82559945a769f0031901dc3 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 13 Nov 2008 22:56:15 +0000 Subject: [PATCH 168/692] Bug 557788 - Return types for constructors in generated typelib bogus svn path=/trunk/; revision=920 --- girnode.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/girnode.c b/girnode.c index 92998ed36..8851df066 100644 --- a/girnode.c +++ b/girnode.c @@ -1216,7 +1216,11 @@ serialize_type (GIrModule *module, iface = find_entry_node (module, modules, node->interface, NULL); if (iface) - name = iface->name; + { + if (iface->type == G_IR_NODE_XREF) + g_string_append_printf (str, "%s.", ((GIrNodeXRef *)iface)->namespace); + name = iface->name; + } else { g_warning ("Interface for type reference %s not found", node->interface); From 5a1f29d1c966184ab76a1feca20f964958d960cd Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 16 Nov 2008 20:58:35 +0000 Subject: [PATCH 169/692] Bug 560241 - Out-arguments should not be marked as being pointers in all cases svn path=/trunk/; revision=928 --- girparser.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/girparser.c b/girparser.c index 65ba28290..ecc2e10f0 100644 --- a/girparser.c +++ b/girparser.c @@ -1656,18 +1656,26 @@ start_type (GMarkupParseContext *context, } else { - gboolean is_pointer; + int pointer_depth; name = find_attribute ("name", attribute_names, attribute_values); if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); + pointer_depth = 0; ctype = find_attribute ("c:type", attribute_names, attribute_values); - if (ctype != NULL && strchr (ctype, '*')) - is_pointer = TRUE; - else - is_pointer = FALSE; - + if (ctype != NULL) + { + const char *cp = ctype + strlen(ctype) - 1; + while (cp > ctype && *cp-- == '*') + pointer_depth++; + } + + if (ctx->current_typed->type == G_IR_NODE_PARAM && + ((GIrNodeParam *)ctx->current_typed)->out && + pointer_depth > 0) + pointer_depth--; + typenode = parse_type (ctx, name); /* A 'disguised' structure is one where the c:type is a typedef that @@ -1675,10 +1683,10 @@ start_type (GMarkupParseContext *context, */ if (typenode->tag == GI_TYPE_TAG_INTERFACE && is_disguised_structure (ctx, typenode->interface)) - is_pointer = TRUE; + pointer_depth++; - if (is_pointer) - typenode->is_pointer = is_pointer; + if (pointer_depth > 0) + typenode->is_pointer = TRUE; } ctx->type_parameters = g_list_append (ctx->type_parameters, typenode); From c7ae662dbe605018052351532c040d9e448dfd96 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Sun, 16 Nov 2008 21:14:19 +0000 Subject: [PATCH 170/692] =?UTF-8?q?Bug=20552371=20=E2=80=93=20implement=20?= =?UTF-8?q?struct=20field=20get/set?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add convenience functions g_field_info_set_field() and g_field_info_get_field() to set and get fields based on the offsets in GIFieldInfo. svn path=/trunk/; revision=929 --- Makefile.am | 1 + gfield.c | 308 +++++++++++++++++++++++++++++++++++++++++++++++++ girepository.h | 6 + 3 files changed, 315 insertions(+) create mode 100644 gfield.c diff --git a/Makefile.am b/Makefile.am index b58288e8b..f98dda293 100644 --- a/Makefile.am +++ b/Makefile.am @@ -12,6 +12,7 @@ libgirepository_la_SOURCES = \ girepository.c \ gtypelib.h \ gtypelib.c \ + gfield.c \ ginfo.c \ girffi.c \ girffi.h \ diff --git a/gfield.c b/gfield.c new file mode 100644 index 000000000..79a5a0d5a --- /dev/null +++ b/gfield.c @@ -0,0 +1,308 @@ +#include "girepository.h" + +/** + * g_field_info_get_field: + * @field_info: a #GIFieldInfo + * @mem: pointer to a block of memory representing a C structure or union + * @value: a #GArgument into which to store the value retrieved + * + * Reads a field identified by a #GFieldInfo from a C structure or + * union. This only handles fields of simple C types. It will fail + * for a field of a composite type like a nested structure or union + * even if that is actually readable. + * + * Returns: %TRUE if reading the field succeeded, otherwise %FALSE + */ +gboolean +g_field_info_get_field (GIFieldInfo *field_info, + gpointer mem, + GArgument *value) +{ + int offset; + GITypeInfo *type_info; + gboolean result = FALSE; + + if (!g_field_info_get_flags (field_info) & GI_FIELD_IS_READABLE) + return FALSE; + + offset = g_field_info_get_offset (field_info); + type_info = g_field_info_get_type (field_info); + + if (g_type_info_is_pointer (type_info)) + { + value->v_pointer = G_STRUCT_MEMBER(gpointer, mem, offset); + result = TRUE; + } + else + { + switch (g_type_info_get_tag (type_info)) + { + case GI_TYPE_TAG_VOID: + g_warning("Field %s: should not be have void type", + g_base_info_get_name ((GIBaseInfo *)field_info)); + break; + case GI_TYPE_TAG_BOOLEAN: + value->v_boolean = G_STRUCT_MEMBER(gboolean, mem, offset) != FALSE; + result = TRUE; + break; + case GI_TYPE_TAG_INT8: + case GI_TYPE_TAG_UINT8: + value->v_uint8 = G_STRUCT_MEMBER(guint8, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT16: + case GI_TYPE_TAG_UINT16: + value->v_uint16 = G_STRUCT_MEMBER(guint16, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT32: + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_INT: + case GI_TYPE_TAG_UINT: + value->v_uint32 = G_STRUCT_MEMBER(guint32, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + value->v_uint64 = G_STRUCT_MEMBER(guint64, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_LONG: + case GI_TYPE_TAG_ULONG: + value->v_ulong = G_STRUCT_MEMBER(gulong, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_SSIZE: + case GI_TYPE_TAG_SIZE: + case GI_TYPE_TAG_GTYPE: + value->v_size = G_STRUCT_MEMBER(gsize, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_FLOAT: + value->v_float = G_STRUCT_MEMBER(gfloat, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_DOUBLE: + value->v_double = G_STRUCT_MEMBER(gdouble, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_TIME_T: + value->v_long = G_STRUCT_MEMBER(time_t, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_UTF8: + case GI_TYPE_TAG_FILENAME: + case GI_TYPE_TAG_ARRAY: + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: + case GI_TYPE_TAG_GHASH: + g_warning("Field %s: type %s should have is_pointer set", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_type_tag_to_string (g_type_info_get_tag (type_info))); + break; + case GI_TYPE_TAG_ERROR: + /* Needs to be handled by the language binding directly */ + break; + case GI_TYPE_TAG_INTERFACE: + { + GIBaseInfo *interface = g_type_info_get_interface (type_info); + switch (g_base_info_get_type (interface)) + { + case GI_INFO_TYPE_STRUCT: + case GI_INFO_TYPE_UNION: + case GI_INFO_TYPE_BOXED: + /* Needs to be handled by the language binding directly */ + break; + case GI_INFO_TYPE_OBJECT: + break; + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + /* Not yet implemented */ + break; + case GI_INFO_TYPE_VFUNC: + case GI_INFO_TYPE_CALLBACK: + g_warning("Field%s: Interface type %d should have is_pointer set", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_base_info_get_type (interface)); + break; + case GI_INFO_TYPE_INVALID: + case GI_INFO_TYPE_INTERFACE: + case GI_INFO_TYPE_FUNCTION: + case GI_INFO_TYPE_CONSTANT: + case GI_INFO_TYPE_ERROR_DOMAIN: + case GI_INFO_TYPE_VALUE: + case GI_INFO_TYPE_SIGNAL: + case GI_INFO_TYPE_PROPERTY: + case GI_INFO_TYPE_FIELD: + case GI_INFO_TYPE_ARG: + case GI_INFO_TYPE_TYPE: + case GI_INFO_TYPE_UNRESOLVED: + g_warning("Field %s: Interface type %d not expected", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_base_info_get_type (interface)); + break; + } + + g_base_info_unref ((GIBaseInfo *)interface); + break; + } + break; + } + } + + g_base_info_unref ((GIBaseInfo *)field_info); + + return result; +} + +/** + * g_field_info_set_field: + * @field_info: a #GIFieldInfo + * @mem: pointer to a block of memory representing a C structure or union + * @value: a #GArgument holding the value to store + * + * Writes a field identified by a #GFieldInfo to a C structure or + * union. This only handles fields of simple C types. It will fail + * for a field of a composite type like a nested structure or union + * even if that is actually writable. Note also that that it will refuse + * to write fields where memory management would by required. A field + * with a type such as 'char *' must be set with a setter function. + * + * Returns: %TRUE if reading the field succeeded, otherwise %FALSE + */ +gboolean +g_field_info_set_field (GIFieldInfo *field_info, + gpointer mem, + const GArgument *value) +{ + int offset; + GITypeInfo *type_info; + gboolean result = FALSE; + + if (!g_field_info_get_flags (field_info) & GI_FIELD_IS_WRITABLE) + return FALSE; + + offset = g_field_info_get_offset (field_info); + type_info = g_field_info_get_type (field_info); + + if (!g_type_info_is_pointer (type_info)) + { + switch (g_type_info_get_tag (type_info)) + { + case GI_TYPE_TAG_VOID: + g_warning("Field %s: should not be have void type", + g_base_info_get_name ((GIBaseInfo *)field_info)); + break; + case GI_TYPE_TAG_BOOLEAN: + G_STRUCT_MEMBER(gboolean, mem, offset) = value->v_boolean != FALSE; + result = TRUE; + break; + case GI_TYPE_TAG_INT8: + case GI_TYPE_TAG_UINT8: + G_STRUCT_MEMBER(guint8, mem, offset) = value->v_uint8; + result = TRUE; + break; + case GI_TYPE_TAG_INT16: + case GI_TYPE_TAG_UINT16: + G_STRUCT_MEMBER(guint16, mem, offset) = value->v_uint16; + result = TRUE; + break; + case GI_TYPE_TAG_INT32: + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_INT: + case GI_TYPE_TAG_UINT: + G_STRUCT_MEMBER(guint32, mem, offset) = value->v_uint32; + result = TRUE; + break; + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + G_STRUCT_MEMBER(guint64, mem, offset) = value->v_uint64; + result = TRUE; + break; + case GI_TYPE_TAG_LONG: + case GI_TYPE_TAG_ULONG: + G_STRUCT_MEMBER(gulong, mem, offset)= value->v_ulong; + result = TRUE; + break; + case GI_TYPE_TAG_SSIZE: + case GI_TYPE_TAG_SIZE: + case GI_TYPE_TAG_GTYPE: + G_STRUCT_MEMBER(gsize, mem, offset) = value->v_size; + result = TRUE; + break; + case GI_TYPE_TAG_FLOAT: + G_STRUCT_MEMBER(gfloat, mem, offset) = value->v_float; + result = TRUE; + break; + case GI_TYPE_TAG_DOUBLE: + G_STRUCT_MEMBER(gdouble, mem, offset)= value->v_double; + result = TRUE; + break; + case GI_TYPE_TAG_TIME_T: + G_STRUCT_MEMBER(time_t, mem, offset) = value->v_long; + result = TRUE; + break; + case GI_TYPE_TAG_UTF8: + case GI_TYPE_TAG_FILENAME: + case GI_TYPE_TAG_ARRAY: + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: + case GI_TYPE_TAG_GHASH: + g_warning("Field %s: type %s should have is_pointer set", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_type_tag_to_string (g_type_info_get_tag (type_info))); + break; + case GI_TYPE_TAG_ERROR: + /* Needs to be handled by the language binding directly */ + break; + case GI_TYPE_TAG_INTERFACE: + { + GIBaseInfo *interface = g_type_info_get_interface (type_info); + switch (g_base_info_get_type (interface)) + { + case GI_INFO_TYPE_STRUCT: + case GI_INFO_TYPE_UNION: + case GI_INFO_TYPE_BOXED: + /* Needs to be handled by the language binding directly */ + break; + case GI_INFO_TYPE_OBJECT: + break; + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + /* Not yet implemented */ + break; + case GI_INFO_TYPE_VFUNC: + case GI_INFO_TYPE_CALLBACK: + g_warning("Field%s: Interface type %d should have is_pointer set", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_base_info_get_type (interface)); + break; + case GI_INFO_TYPE_INVALID: + case GI_INFO_TYPE_INTERFACE: + case GI_INFO_TYPE_FUNCTION: + case GI_INFO_TYPE_CONSTANT: + case GI_INFO_TYPE_ERROR_DOMAIN: + case GI_INFO_TYPE_VALUE: + case GI_INFO_TYPE_SIGNAL: + case GI_INFO_TYPE_PROPERTY: + case GI_INFO_TYPE_FIELD: + case GI_INFO_TYPE_ARG: + case GI_INFO_TYPE_TYPE: + case GI_INFO_TYPE_UNRESOLVED: + g_warning("Field %s: Interface type %d not expected", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_base_info_get_type (interface)); + break; + } + + g_base_info_unref ((GIBaseInfo *)interface); + break; + } + break; + } + } + + g_base_info_unref ((GIBaseInfo *)field_info); + + return result; +} diff --git a/girepository.h b/girepository.h index 46082e037..fc5768c5f 100644 --- a/girepository.h +++ b/girepository.h @@ -356,6 +356,12 @@ gint g_field_info_get_size (GIFieldInfo *info); gint g_field_info_get_offset (GIFieldInfo *info); GITypeInfo * g_field_info_get_type (GIFieldInfo *info); +gboolean g_field_info_get_field (GIFieldInfo *field_info, + gpointer mem, + GArgument *value); +gboolean g_field_info_set_field (GIFieldInfo *field_info, + gpointer mem, + const GArgument *value); /* GIUnionInfo */ gint g_union_info_get_n_fields (GIUnionInfo *info); From 6cb96533b9972e04399427e26389ea13a5556bc1 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Sun, 16 Nov 2008 21:15:54 +0000 Subject: [PATCH 171/692] =?UTF-8?q?Bug=20560825=20=E2=80=93=20Add=20size?= =?UTF-8?q?=20and=20alignment=20to=20typelib?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Include the size and alignment of structures and unions in the typelib, and add getter methods to retrieve them from GIStructInfo/GIUnionInfo. * docs/typelib-format.txt girepository/gtypelib.h girepository/girnode.c girepository/girmodule.c girepository/gtypelib.c: Add size and alignment to StructBlob and UnionBlob. * girepository/ginfo.c girepository/girepository.h: Add g_[struct|union]_get[size|alignment](). * test/offsets/gen-gitestoffsets: Test overall structure size and alignment. svn path=/trunk/; revision=930 --- ginfo.c | 35 +++++++++++++++++++++++++++++++++++ girepository.h | 4 ++++ girmodule.c | 4 ++-- girnode.c | 27 +++++++++++++++++---------- gtypelib.c | 8 ++++---- gtypelib.h | 10 ++++++++-- 6 files changed, 70 insertions(+), 18 deletions(-) diff --git a/ginfo.c b/ginfo.c index 3de0cf590..a3813d641 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1112,6 +1112,24 @@ g_struct_info_find_method (GIStructInfo *info, return find_method (base, offset, blob->n_methods, name); } +gsize +g_struct_info_get_size (GIStructInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset]; + + return blob->size; +} + +gsize +g_struct_info_get_alignment (GIStructInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset]; + + return blob->alignment; +} + gint g_enum_info_get_n_values (GIEnumInfo *info) { @@ -1887,3 +1905,20 @@ g_union_info_find_method (GIUnionInfo *info, return find_method (base, offset, blob->n_functions, name); } +gsize +g_union_info_get_size (GIUnionInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; + + return blob->size; +} + +gsize +g_union_info_get_alignment (GIUnionInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; + + return blob->alignment; +} diff --git a/girepository.h b/girepository.h index fc5768c5f..a671cb5c8 100644 --- a/girepository.h +++ b/girepository.h @@ -377,6 +377,8 @@ GIConstantInfo * g_union_info_get_discriminator (GIUnionInfo *info, gint n); GIFunctionInfo * g_union_info_find_method (GIUnionInfo *info, const gchar *name); +gsize g_union_info_get_size (GIUnionInfo *info); +gsize g_union_info_get_alignment (GIUnionInfo *info); /* GIStructInfo */ @@ -388,6 +390,8 @@ GIFunctionInfo * g_struct_info_get_method (GIStructInfo *info, gint n); GIFunctionInfo * g_struct_info_find_method (GIStructInfo *info, const gchar *name); +gsize g_struct_info_get_size (GIStructInfo *info); +gsize g_struct_info_get_alignment (GIStructInfo *info); /* GIRegisteredTypeInfo */ diff --git a/girmodule.c b/girmodule.c index 1b7c3048c..1b26f3de4 100644 --- a/girmodule.c +++ b/girmodule.c @@ -222,10 +222,10 @@ g_ir_module_build_typelib (GIrModule *module, header->annotation_blob_size = 12; header->signature_blob_size = 8; header->enum_blob_size = 20; - header->struct_blob_size = 20; + header->struct_blob_size = 24; header->object_blob_size = 32; header->interface_blob_size = 28; - header->union_blob_size = 28; + header->union_blob_size = 32; /* fill in directory and content */ entry = (DirEntry *)&data[header->directory]; diff --git a/girnode.c b/girnode.c index 8851df066..9f809d4be 100644 --- a/girnode.c +++ b/girnode.c @@ -469,7 +469,7 @@ g_ir_node_get_size (GIrNode *node) { GIrNodeStruct *struct_ = (GIrNodeStruct *)node; - size = 20; + size = 24; for (l = struct_->members; l; l = l->next) size += g_ir_node_get_size ((GIrNode *)l->data); } @@ -479,7 +479,7 @@ g_ir_node_get_size (GIrNode *node) { GIrNodeBoxed *boxed = (GIrNodeBoxed *)node; - size = 20; + size = 24; for (l = boxed->members; l; l = l->next) size += g_ir_node_get_size ((GIrNode *)l->data); } @@ -517,7 +517,7 @@ g_ir_node_get_size (GIrNode *node) { GIrNodeUnion *union_ = (GIrNodeUnion *)node; - size = 28; + size = 32; for (l = union_->members; l; l = l->next) size += g_ir_node_get_size ((GIrNode *)l->data); for (l = union_->discriminators; l; l = l->next) @@ -707,7 +707,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeStruct *struct_ = (GIrNodeStruct *)node; - size = 20; + size = 24; size += ALIGN_VALUE (strlen (node->name) + 1, 4); if (struct_->gtype_name) size += ALIGN_VALUE (strlen (struct_->gtype_name) + 1, 4); @@ -722,7 +722,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeBoxed *boxed = (GIrNodeBoxed *)node; - size = 20; + size = 24; size += ALIGN_VALUE (strlen (node->name) + 1, 4); if (boxed->gtype_name) { @@ -814,7 +814,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeUnion *union_ = (GIrNodeUnion *)node; - size = 28; + size = 32; size += ALIGN_VALUE (strlen (node->name) + 1, 4); if (union_->gtype_name) size += ALIGN_VALUE (strlen (union_->gtype_name) + 1, 4); @@ -1789,6 +1789,9 @@ g_ir_node_build_typelib (GIrNode *node, blob->deprecated = struct_->deprecated; blob->reserved = 0; blob->name = write_string (node->name, strings, data, offset2); + blob->alignment = struct_->alignment; + blob->size = struct_->size; + if (struct_->gtype_name) { blob->unregistered = FALSE; @@ -1805,7 +1808,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->n_fields = 0; blob->n_methods = 0; - *offset += 20; + *offset += 24; members = g_list_copy (struct_->members); @@ -1836,11 +1839,13 @@ g_ir_node_build_typelib (GIrNode *node, 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->alignment = boxed->alignment; + blob->size = boxed->size; blob->n_fields = 0; blob->n_methods = 0; - *offset += 20; + *offset += 24; members = g_list_copy (boxed->members); @@ -1868,6 +1873,8 @@ g_ir_node_build_typelib (GIrNode *node, blob->deprecated = union_->deprecated; blob->reserved = 0; blob->name = write_string (node->name, strings, data, offset2); + blob->alignment = union_->alignment; + blob->size = union_->size; if (union_->gtype_name) { blob->unregistered = FALSE; @@ -1888,7 +1895,7 @@ g_ir_node_build_typelib (GIrNode *node, if (union_->discriminator_type) { - *offset += 24; + *offset += 28; blob->discriminated = TRUE; g_ir_node_build_typelib ((GIrNode *)union_->discriminator_type, module, modules, strings, types, @@ -1896,7 +1903,7 @@ g_ir_node_build_typelib (GIrNode *node, } else { - *offset += 28; + *offset += 32; blob->discriminated = FALSE; blob->discriminator_type.offset = 0; } diff --git a/gtypelib.c b/gtypelib.c index be470a4b0..8472195fe 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -168,7 +168,7 @@ g_typelib_check_sanity (void) CHECK_SIZE (ValueBlob, 12); CHECK_SIZE (FieldBlob, 12); CHECK_SIZE (RegisteredTypeBlob, 16); - CHECK_SIZE (StructBlob, 20); + CHECK_SIZE (StructBlob, 24); CHECK_SIZE (EnumBlob, 20); CHECK_SIZE (PropertyBlob, 12); CHECK_SIZE (SignalBlob, 12); @@ -177,7 +177,7 @@ g_typelib_check_sanity (void) CHECK_SIZE (InterfaceBlob, 28); CHECK_SIZE (ConstantBlob, 20); CHECK_SIZE (AnnotationBlob, 12); - CHECK_SIZE (UnionBlob, 28); + CHECK_SIZE (UnionBlob, 32); #undef CHECK_SIZE g_assert (size_check_ok); @@ -320,10 +320,10 @@ validate_header (ValidateContext *ctx, header->annotation_blob_size != 12 || header->signature_blob_size != 8 || header->enum_blob_size != 20 || - header->struct_blob_size != 20 || + header->struct_blob_size != 24 || header->object_blob_size != 32 || header->interface_blob_size != 28 || - header->union_blob_size != 28) + header->union_blob_size != 32) { g_set_error (error, G_TYPELIB_ERROR, diff --git a/gtypelib.h b/gtypelib.h index 458d429d1..1b2b8934a 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -295,13 +295,16 @@ typedef struct guint16 deprecated : 1; guint16 unregistered : 1; - guint16 reserved :14; + guint16 alignment : 6; + guint16 reserved : 8; guint32 name; guint32 gtype_name; guint32 gtype_init; + guint32 size; + guint16 n_fields; guint16 n_methods; @@ -318,12 +321,15 @@ typedef struct guint16 deprecated : 1; guint16 unregistered : 1; guint16 discriminated : 1; - guint16 reserved :13; + guint16 alignment : 6; + guint16 reserved : 7; guint32 name; guint32 gtype_name; guint32 gtype_init; + guint32 size; + guint16 n_fields; guint16 n_functions; From c10269cf2d96547ee29f81a046d6131776b94672 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Sun, 16 Nov 2008 21:20:26 +0000 Subject: [PATCH 172/692] Respect is_pointer in serialize_type() Add a '*' to the serialization for the cases where we set is_pointer in the type blob we write out depending on node->is_pointer. Don't add the '*' in the cases where is_pointer is set or not set in a fixed fashion. http://bugzilla.gnome.org/show_bug.cgi?id=561087 svn path=/trunk/; revision=931 --- girnode.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/girnode.c b/girnode.c index 9f809d4be..9c5cf5b6a 100644 --- a/girnode.c +++ b/girnode.c @@ -1191,7 +1191,8 @@ serialize_type (GIrModule *module, if (node->tag < GI_TYPE_TAG_ARRAY) { - g_string_append_printf (str, "%s", basic[node->tag]); + g_string_append_printf (str, "%s%s", basic[node->tag], + node->is_pointer ? "*" : ""); } else if (node->tag == GI_TYPE_TAG_ARRAY) { @@ -1227,7 +1228,8 @@ serialize_type (GIrModule *module, name = node->interface; } - g_string_append_printf (str, "%s", name); + g_string_append_printf (str, "%s%s", name, + node->is_pointer ? "*" : ""); } else if (node->tag == GI_TYPE_TAG_GLIST) { From 7916f49e55802fbf4d1673c1f0135d9e65cd7043 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 17 Nov 2008 00:27:37 +0000 Subject: [PATCH 173/692] Bug 559706 - interface prequisites svn path=/trunk/; revision=932 --- gdump.c | 7 ++++++- girparser.c | 51 ++++++++++++++++++++++----------------------------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/gdump.c b/gdump.c index b26b0e854..a58e620e0 100644 --- a/gdump.c +++ b/gdump.c @@ -186,7 +186,12 @@ dump_interface_type (GType type, const char *symbol, GOutputStream *out) for (i = 0; i < n_interfaces; i++) { GType itype = interfaces[i]; - escaped_printf (out, " %s\n", + if (itype == G_TYPE_OBJECT) + { + /* This is implicit */ + continue; + } + escaped_printf (out, " \n", g_type_name (itype)); } dump_properties (type, out); diff --git a/girparser.c b/girparser.c index ecc2e10f0..43f340299 100644 --- a/girparser.c +++ b/girparser.c @@ -54,7 +54,7 @@ typedef enum STATE_INTERFACE_PROPERTY, /* 15 */ STATE_INTERFACE_FIELD, STATE_IMPLEMENTS, - STATE_REQUIRES, + STATE_PREREQUISITE, STATE_BOXED, STATE_BOXED_FIELD, /* 20 */ STATE_STRUCT, @@ -2338,25 +2338,6 @@ start_element_handler (GMarkupParseContext *context, attribute_names, attribute_values, ctx, error)) goto out; - else if (strcmp (element_name, "class") == 0 && - ctx->state == STATE_REQUIRES) - { - const gchar *name; - - name = find_attribute ("name", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { - GIrNodeInterface *iface; - - iface = (GIrNodeInterface *)ctx->current_node; - iface ->prerequisites = g_list_append (iface->prerequisites, g_strdup (name)); - } - - goto out; - } break; case 'd': @@ -2522,7 +2503,26 @@ start_element_handler (GMarkupParseContext *context, attribute_names, attribute_values, ctx, error)) goto out; + else if (strcmp (element_name, "prerequisite") == 0 && + ctx->state == STATE_INTERFACE) + { + const gchar *name; + name = find_attribute ("name", attribute_names, attribute_values); + + state_switch (ctx, STATE_PREREQUISITE); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeInterface *iface; + + iface = (GIrNodeInterface *)ctx->current_node; + iface ->prerequisites = g_list_append (iface->prerequisites, g_strdup (name)); + } + goto out; + } break; case 'r': @@ -2549,13 +2549,6 @@ start_element_handler (GMarkupParseContext *context, attribute_names, attribute_values, ctx, error)) goto out; - else if (strcmp (element_name, "requires") == 0 && - ctx->state == STATE_INTERFACE) - { - state_switch (ctx, STATE_REQUIRES); - - goto out; - } else if (start_struct (context, element_name, attribute_names, attribute_values, ctx, error)) @@ -2893,8 +2886,8 @@ end_element_handler (GMarkupParseContext *context, if (require_end_element (context, ctx, "implements", element_name, error)) state_switch (ctx, STATE_CLASS); break; - case STATE_REQUIRES: - if (require_end_element (context, ctx, "requires", element_name, error)) + case STATE_PREREQUISITE: + if (require_end_element (context, ctx, "prerequisite", element_name, error)) state_switch (ctx, STATE_INTERFACE); break; case STATE_NAMESPACE_CONSTANT: From 44b1fde2db164b7418cc3500bb188fef97f46abd Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 17 Nov 2008 00:27:44 +0000 Subject: [PATCH 174/692] Add test for interface prereq svn path=/trunk/; revision=935 --- girparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index 43f340299..48e311923 100644 --- a/girparser.c +++ b/girparser.c @@ -2519,7 +2519,7 @@ start_element_handler (GMarkupParseContext *context, GIrNodeInterface *iface; iface = (GIrNodeInterface *)ctx->current_node; - iface ->prerequisites = g_list_append (iface->prerequisites, g_strdup (name)); + iface->prerequisites = g_list_append (iface->prerequisites, g_strdup (name)); } goto out; } From 6c74aba6b68f44e1d35406c8c13cbb2ed047a0d2 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 17 Nov 2008 00:27:46 +0000 Subject: [PATCH 175/692] Bug 559706 - Interface prerequisites svn path=/trunk/; revision=936 --- gdump.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gdump.c b/gdump.c index a58e620e0..9c0c083d4 100644 --- a/gdump.c +++ b/gdump.c @@ -188,7 +188,11 @@ dump_interface_type (GType type, const char *symbol, GOutputStream *out) GType itype = interfaces[i]; if (itype == G_TYPE_OBJECT) { - /* This is implicit */ + /* Treat this as implicit for now; in theory GInterfaces are + * supported on things like GstMiniObject, but right now + * the introspection system only supports GObject. + * http://bugzilla.gnome.org/show_bug.cgi?id=559706 + */ continue; } escaped_printf (out, " \n", From b87284dac2c81fd2e53ba17980dcbffcfab73e89 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 17 Nov 2008 00:39:46 +0000 Subject: [PATCH 176/692] g_irepository_get_default is (transfer none) svn path=/trunk/; revision=937 --- girepository.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girepository.c b/girepository.c index e65910de4..8947f2344 100644 --- a/girepository.c +++ b/girepository.c @@ -447,7 +447,7 @@ g_irepository_is_registered (GIRepository *repository, * parameter to mean this default repository, which is usually more * convenient for C. * - * Returns: The global singleton #GIRepository + * Returns: (transfer none): The global singleton #GIRepository */ GIRepository * g_irepository_get_default (void) From e6cf04484d3b5301e4a542906409d48262cf3d66 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 17 Nov 2008 00:49:58 +0000 Subject: [PATCH 177/692] Ensure we always call init_globals svn path=/trunk/; revision=938 --- girepository.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/girepository.c b/girepository.c index 8947f2344..e8a26474a 100644 --- a/girepository.c +++ b/girepository.c @@ -82,7 +82,7 @@ g_irepository_class_init (GIRepositoryClass *class) } static void -init_globals () +init_globals (void) { g_static_mutex_lock (&globals_lock); @@ -179,13 +179,12 @@ get_typelib_dependencies (GTypelib *typelib) static GIRepository * get_repository (GIRepository *repository) { + init_globals (); + if (repository != NULL) return repository; - else - { - init_globals (); - return default_repository; - } + else + return default_repository; } static GTypelib * From 05d5158001a5ae6f4b88e6169889c485d67a4dda Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Tue, 18 Nov 2008 12:29:10 +0000 Subject: [PATCH 178/692] Add "storage type" to the typelib data for enums In order to set and get enum and flag fields in structures, we need to know the integral type that the enumeration is stored as. We are already computing that at compile time in order to compute struct offsets, so the easiest thing to do is to save that in the typelib. * docs/typelib-format.txt girepository/girnode.[ch] girepository/giroffsets.c girepository/gtypelib.h: Add 'storage_type' to the typelib format for EnumBlob and compute and save it at compile time. * girepository/girepository.h girepository/ginfo.c: Add g_enum_info_get_storage_type(). * girepository/gfield.c: Implement reading and writing enum and flags fields based on the storage type. http://bugzilla.gnome.org/show_bug.cgi?id=561296 svn path=/trunk/; revision=944 --- gfield.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++--- ginfo.c | 22 ++++++++++++ girepository.h | 1 + girnode.c | 1 + girnode.h | 1 + giroffsets.c | 63 ++++++++++++++++++++++++++++----- gtypelib.h | 3 +- 7 files changed, 172 insertions(+), 14 deletions(-) diff --git a/gfield.c b/gfield.c index 79a5a0d5a..673e3db7a 100644 --- a/gfield.c +++ b/gfield.c @@ -1,4 +1,7 @@ +#include + #include "girepository.h" +#include "girffi.h" /** * g_field_info_get_field: @@ -117,11 +120,55 @@ g_field_info_get_field (GIFieldInfo *field_info, break; case GI_INFO_TYPE_ENUM: case GI_INFO_TYPE_FLAGS: - /* Not yet implemented */ - break; + { + /* FIXME: there's a mismatch here between the value->v_int we use + * here and the glong result returned from g_value_info_get_value(). + * But to switch this to glong, we'd have to make g_function_info_invoke() + * translate value->v_long to the proper ABI for an enum function + * call parameter, which will usually be int, and then fix up language + * bindings. + */ + GITypeTag storage_type = g_enum_info_get_storage_type ((GIEnumInfo *)interface); + switch (storage_type) + { + case GI_TYPE_TAG_INT8: + case GI_TYPE_TAG_UINT8: + value->v_int = (gint)G_STRUCT_MEMBER(guint8, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT16: + case GI_TYPE_TAG_UINT16: + value->v_int = (gint)G_STRUCT_MEMBER(guint16, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT32: + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_INT: + case GI_TYPE_TAG_UINT: + value->v_int = (gint)G_STRUCT_MEMBER(guint32, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + value->v_int = (gint)G_STRUCT_MEMBER(guint64, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_LONG: + case GI_TYPE_TAG_ULONG: + value->v_int = (gint)G_STRUCT_MEMBER(gulong, mem, offset); + result = TRUE; + break; + default: + g_warning("Field %s: Unexpected enum storage type %s", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_type_tag_to_string (storage_type)); + break; + } + break; + } case GI_INFO_TYPE_VFUNC: case GI_INFO_TYPE_CALLBACK: - g_warning("Field%s: Interface type %d should have is_pointer set", + g_warning("Field %s: Interface type %d should have is_pointer set", g_base_info_get_name ((GIBaseInfo *)field_info), g_base_info_get_type (interface)); break; @@ -269,7 +316,47 @@ g_field_info_set_field (GIFieldInfo *field_info, break; case GI_INFO_TYPE_ENUM: case GI_INFO_TYPE_FLAGS: - /* Not yet implemented */ + { + /* See FIXME above + */ + GITypeTag storage_type = g_enum_info_get_storage_type ((GIEnumInfo *)interface); + switch (storage_type) + { + case GI_TYPE_TAG_INT8: + case GI_TYPE_TAG_UINT8: + G_STRUCT_MEMBER(guint8, mem, offset) = (guint8)value->v_int; + result = TRUE; + break; + case GI_TYPE_TAG_INT16: + case GI_TYPE_TAG_UINT16: + G_STRUCT_MEMBER(guint16, mem, offset) = (guint16)value->v_int; + result = TRUE; + break; + case GI_TYPE_TAG_INT32: + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_INT: + case GI_TYPE_TAG_UINT: + G_STRUCT_MEMBER(guint32, mem, offset) = (guint32)value->v_int; + result = TRUE; + break; + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + G_STRUCT_MEMBER(guint64, mem, offset) = (guint64)value->v_int; + result = TRUE; + break; + case GI_TYPE_TAG_LONG: + case GI_TYPE_TAG_ULONG: + G_STRUCT_MEMBER(gulong, mem, offset) = (gulong)value->v_int; + result = TRUE; + break; + default: + g_warning("Field %s: Unexpected enum storage type %s", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_type_tag_to_string (storage_type)); + break; + } + break; + } break; case GI_INFO_TYPE_VFUNC: case GI_INFO_TYPE_CALLBACK: diff --git a/ginfo.c b/ginfo.c index a3813d641..204583cd4 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1152,6 +1152,28 @@ g_enum_info_get_value (GIEnumInfo *info, return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, base, base->typelib, offset); } +/** + * g_enum_info_get_storage_type: + * @info: GIEnumInfo + * + * Gets the tag of the type used for the enum in the C ABI. This will + * will be a signed or unsigned integral type. + + * Note that in the current implementation the width of the type is + * computed correctly, but the signed or unsigned nature of the type + * may not match the sign of the type used by the C compiler. + * + * Return Value: the storage type for the enumeration + */ +GITypeTag +g_enum_info_get_storage_type (GIEnumInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + EnumBlob *blob = (EnumBlob *)&base->typelib->data[base->offset]; + + return blob->storage_type; +} + /* GIObjectInfo functions */ GIObjectInfo * g_object_info_get_parent (GIObjectInfo *info) diff --git a/girepository.h b/girepository.h index a671cb5c8..abeb85700 100644 --- a/girepository.h +++ b/girepository.h @@ -404,6 +404,7 @@ GType g_registered_type_info_get_g_type (GIRegisteredTypeInf gint g_enum_info_get_n_values (GIEnumInfo *info); GIValueInfo * g_enum_info_get_value (GIEnumInfo *info, gint n); +GITypeTag g_enum_info_get_storage_type (GIEnumInfo *info); /* GIObjectInfo */ diff --git a/girnode.c b/girnode.c index 9c5cf5b6a..8e9d5d1a6 100644 --- a/girnode.c +++ b/girnode.c @@ -1952,6 +1952,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->deprecated = enum_->deprecated; blob->reserved = 0; + blob->storage_type = enum_->storage_type; blob->name = write_string (node->name, strings, data, offset2); if (enum_->gtype_name) { diff --git a/girnode.h b/girnode.h index 9829a9333..674594d8a 100644 --- a/girnode.h +++ b/girnode.h @@ -259,6 +259,7 @@ struct _GIrNodeEnum GIrNode node; gboolean deprecated; + gint storage_type; gchar *gtype_name; gchar *gtype_init; diff --git a/giroffsets.c b/giroffsets.c index 1844dd1b5..46cdbd90c 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -63,15 +63,15 @@ typedef enum { /* etc... */ #endif -static gboolean -get_enum_size_alignment (GIrNodeEnum *enum_node, - gint *size, - gint *alignment) +static void +compute_enum_storage_type (GIrNodeEnum *enum_node) { GList *l; guint32 max_value = 0; int width; - ffi_type *type_ffi; + + if (enum_node->storage_type != GI_TYPE_TAG_VOID) /* already done */ + return; for (l = enum_node->values; l; l = l->next) { @@ -94,15 +94,48 @@ get_enum_size_alignment (GIrNodeEnum *enum_node, width = sizeof (Enum6); if (width == 1) - type_ffi = &ffi_type_sint8; + enum_node->storage_type = GI_TYPE_TAG_UINT8; else if (width == 2) - type_ffi = &ffi_type_sint16; + enum_node->storage_type = GI_TYPE_TAG_UINT16; else if (width == 4) - type_ffi = &ffi_type_sint32; + enum_node->storage_type = GI_TYPE_TAG_UINT32; else if (width == 8) - type_ffi = &ffi_type_sint64; + enum_node->storage_type = GI_TYPE_TAG_UINT64; else g_error ("Unexpected enum width %d", width); +} + +static gboolean +get_enum_size_alignment (GIrNodeEnum *enum_node, + gint *size, + gint *alignment) +{ + ffi_type *type_ffi; + + compute_enum_storage_type (enum_node); + + switch (enum_node->storage_type) + { + case GI_TYPE_TAG_INT8: + case GI_TYPE_TAG_UINT8: + type_ffi = &ffi_type_uint8; + break; + case GI_TYPE_TAG_INT16: + case GI_TYPE_TAG_UINT16: + type_ffi = &ffi_type_uint16; + break; + case GI_TYPE_TAG_INT32: + case GI_TYPE_TAG_UINT32: + type_ffi = &ffi_type_uint32; + break; + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + type_ffi = &ffi_type_uint64; + break; + default: + g_error ("Unexpected enum storage type %s", + g_type_tag_to_string (enum_node->storage_type)); + } *size = type_ffi->size; *alignment = type_ffi->alignment; @@ -459,6 +492,18 @@ g_ir_node_compute_offsets (GIrNode *node, &union_->size, &union_->alignment); break; } + case G_IR_NODE_ENUM: + case G_IR_NODE_FLAGS: + { + GIrNodeEnum *enum_ = (GIrNodeEnum *)node; + + if (enum_->storage_type != GI_TYPE_TAG_VOID) /* already done */ + return; + + compute_enum_storage_type (enum_); + + break; + } default: /* Nothing to do */ return; diff --git a/gtypelib.h b/gtypelib.h index 1b2b8934a..7db15db3a 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -349,7 +349,8 @@ typedef struct guint16 deprecated : 1; guint16 unregistered : 1; - guint16 reserved :14; + guint16 storage_type : 5; + guint16 reserved : 9; guint32 name; From d4d832bf9a73c9d1fdabb1e79df1d44a4ee4d92e Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 18 Nov 2008 18:42:32 +0000 Subject: [PATCH 179/692] Add a comment about keeping hardcoded numbers in g_typelib_check_sanity svn path=/trunk/; revision=945 --- gtypelib.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gtypelib.c b/gtypelib.c index 8472195fe..5cda70579 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -152,6 +152,14 @@ g_typelib_check_sanity (void) n, sizeof (s)); \ size_check_ok = FALSE; \ } + + /* When changing the size of a typelib structure, you are required to update + * the hardcoded size here. Do NOT change these to use sizeof(); these + * should match whatever is defined in the text specification and serve as + * a sanity check on structure modifications. + * + * Everything else in the code however should be using sizeof(). + */ CHECK_SIZE (Header, 108); CHECK_SIZE (DirEntry, 12); From 52072b6bbfd6dff7094615e04e4ce9a701a13ef8 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 18 Nov 2008 18:42:36 +0000 Subject: [PATCH 180/692] Use sizeof() instead of hard-coding struct sizes svn path=/trunk/; revision=946 --- girnode.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/girnode.c b/girnode.c index 8e9d5d1a6..75dd265c8 100644 --- a/girnode.c +++ b/girnode.c @@ -1576,8 +1576,8 @@ g_ir_node_build_typelib (GIrNode *node, signature = *offset2; n = g_list_length (function->parameters); - *offset += 16; - *offset2 += 8 + n * 12; + *offset += sizeof(FunctionBlob); + *offset2 += sizeof(SignatureBlob) + n * sizeof(ArgBlob); blob->blob_type = BLOB_TYPE_FUNCTION; blob->deprecated = function->deprecated; @@ -1628,8 +1628,8 @@ g_ir_node_build_typelib (GIrNode *node, signature = *offset2; n = g_list_length (function->parameters); - *offset += 12; - *offset2 += 8 + n * 12; + *offset += sizeof(CallbackBlob); + *offset2 += sizeof(SignatureBlob) + n * sizeof(ArgBlob); blob->blob_type = BLOB_TYPE_CALLBACK; blob->deprecated = function->deprecated; @@ -1671,8 +1671,8 @@ g_ir_node_build_typelib (GIrNode *node, signature = *offset2; n = g_list_length (signal->parameters); - *offset += 12; - *offset2 += 8 + n * 12; + *offset += sizeof(SignalBlob); + *offset2 += sizeof(SignatureBlob) + n * sizeof(ArgBlob); blob->deprecated = signal->deprecated; blob->run_first = signal->run_first; @@ -1722,8 +1722,8 @@ g_ir_node_build_typelib (GIrNode *node, signature = *offset2; n = g_list_length (vfunc->parameters); - *offset += 16; - *offset2 += 8 + n * 12; + *offset += sizeof(VFuncBlob); + *offset2 += sizeof(SignatureBlob) + n * sizeof(ArgBlob); blob->name = write_string (node->name, strings, data, offset2); blob->must_chain_up = 0; /* FIXME */ From d8cb1e0d2c638b3f847d2582eec8d458cda2875d Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Mon, 24 Nov 2008 16:22:16 +0000 Subject: [PATCH 181/692] Remove a warning, be less verbose on error on fundamental types. 2008-11-24 Johan Dahlin * girepository/gdump.c (dump_type): Remove a warning, be less verbose on error on fundamental types. svn path=/trunk/; revision=963 --- gdump.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gdump.c b/gdump.c index 9c0c083d4..23650becd 100644 --- a/gdump.c +++ b/gdump.c @@ -274,7 +274,11 @@ dump_type (GType type, const char *symbol, GOutputStream *out) /* GValue, etc. Just skip them. */ break; default: - g_warning ("unhandled gtype %s", g_type_name (type)); + /* Other fundamental types such as the once GStreamer and Clutter registers + * are not yet interesting from an introspection perspective and should be + * ignored + */ + break; } } From a573a1c741f2f62078d0e47c039080014a570867 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 25 Nov 2008 21:48:34 +0000 Subject: [PATCH 182/692] Bug 561137 - support multiple repositories This change makes us stop calling g_irepository_get_default inside ginfo.c, which won't work for non-default repositories. Change GIBaseInfo to not only keep track of its source repository, we hold a reference. This makes memmgt much clearer. svn path=/trunk/; revision=970 --- Makefile.am | 1 + ginfo.c | 61 +++++++++++++++++++++++++++++++++----------------- ginfo.h | 42 ++++++++++++++++++++++++++++++++++ girepository.c | 11 +++++++-- 4 files changed, 93 insertions(+), 22 deletions(-) create mode 100644 ginfo.h diff --git a/Makefile.am b/Makefile.am index f98dda293..4554d5710 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,6 +13,7 @@ libgirepository_la_SOURCES = \ gtypelib.h \ gtypelib.c \ gfield.c \ + ginfo.h \ ginfo.c \ girffi.c \ girffi.h \ diff --git a/ginfo.c b/ginfo.c index 204583cd4..0e39bcd07 100644 --- a/ginfo.c +++ b/ginfo.c @@ -24,13 +24,14 @@ #include #include -#include "girepository.h" #include "gtypelib.h" +#include "ginfo.h" struct _GIBaseInfo { gint type; gint ref_count; + GIRepository *repository; GIBaseInfo *container; GTypelib *typelib; @@ -135,13 +136,16 @@ struct _GIUnionInfo /* info creation */ GIBaseInfo * -g_info_new (GIInfoType type, - GIBaseInfo *container, - GTypelib *typelib, - guint32 offset) +g_info_new_full (GIInfoType type, + GIRepository *repository, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset) { GIBaseInfo *info; + g_return_val_if_fail (container != NULL || repository != NULL, NULL); + info = g_new0 (GIBaseInfo, 1); info->ref_count = 1; @@ -153,38 +157,48 @@ g_info_new (GIInfoType type, if (container) info->container = g_base_info_ref (container); + info->repository = g_object_ref (repository); + return info; } +GIBaseInfo * +g_info_new (GIInfoType type, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset) +{ + return g_info_new_full (type, container->repository, container, typelib, offset); +} + static GIBaseInfo * -g_info_from_entry (GTypelib *typelib, +g_info_from_entry (GIRepository *repository, + GTypelib *typelib, guint16 index) { GIBaseInfo *result; DirEntry *entry = g_typelib_get_dir_entry (typelib, index); - + if (entry->local) - result = g_info_new (entry->blob_type, NULL, typelib, entry->offset); - else + result = g_info_new_full (entry->blob_type, repository, NULL, typelib, entry->offset); + else { const gchar *namespace = g_typelib_get_string (typelib, entry->offset); const gchar *name = g_typelib_get_string (typelib, entry->name); - - GIRepository *repository = g_irepository_get_default (); - + 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; unresolved->namespace = namespace; - + return (GIBaseInfo*)unresolved; } return result; @@ -213,6 +227,8 @@ g_base_info_unref (GIBaseInfo *info) if (info->container) g_base_info_unref (info->container); + g_object_unref (info->repository); + g_free (info); } } @@ -804,7 +820,7 @@ g_type_info_get_interface (GITypeInfo *info) InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->typelib->data[base->offset]; if (blob->tag == GI_TYPE_TAG_INTERFACE) - return g_info_from_entry (base->typelib, blob->interface); + return g_info_from_entry (base->repository, base->typelib, blob->interface); } return NULL; @@ -896,7 +912,8 @@ g_type_info_get_error_domain (GITypeInfo *info, ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->typelib->data[base->offset]; if (blob->tag == GI_TYPE_TAG_ERROR) - return (GIErrorDomainInfo *) g_info_from_entry (base->typelib, + return (GIErrorDomainInfo *) g_info_from_entry (base->repository, + base->typelib, blob->domains[n]); } @@ -920,7 +937,8 @@ g_error_domain_info_get_codes (GIErrorDomainInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->typelib->data[base->offset]; - return (GIInterfaceInfo *) g_info_from_entry (base->typelib, blob->error_codes); + return (GIInterfaceInfo *) g_info_from_entry (base->repository, + base->typelib, blob->error_codes); } @@ -1182,7 +1200,8 @@ g_object_info_get_parent (GIObjectInfo *info) ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; if (blob->parent) - return (GIObjectInfo *) g_info_from_entry (base->typelib, blob->parent); + return (GIObjectInfo *) g_info_from_entry (base->repository, + base->typelib, blob->parent); else return NULL; } @@ -1229,7 +1248,8 @@ g_object_info_get_interface (GIObjectInfo *info, GIBaseInfo *base = (GIBaseInfo *)info; ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; - return (GIInterfaceInfo *) g_info_from_entry (base->typelib, blob->interfaces[n]); + return (GIInterfaceInfo *) g_info_from_entry (base->repository, + base->typelib, blob->interfaces[n]); } gint @@ -1437,7 +1457,8 @@ g_interface_info_get_prerequisite (GIInterfaceInfo *info, GIBaseInfo *base = (GIBaseInfo *)info; InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; - return g_info_from_entry (base->typelib, blob->prerequisites[n]); + return g_info_from_entry (base->repository, + base->typelib, blob->prerequisites[n]); } diff --git a/ginfo.h b/ginfo.h new file mode 100644 index 000000000..15138cfbb --- /dev/null +++ b/ginfo.h @@ -0,0 +1,42 @@ +/* GObject introspection: Typelib info functions + * + * Copyright (C) 2008 Red Hat, Inc + * + * 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 __GIRINFO_H__ +#define __GIRINFO_H__ + +#include "girepository.h" + +G_BEGIN_DECLS + +GITypeInfo * +g_type_info_new (GIBaseInfo *container, + GTypelib *typelib, + guint32 offset); + +GIBaseInfo * +g_info_new_full (GIInfoType type, + GIRepository *repository, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset); + +G_END_DECLS + +#endif diff --git a/girepository.c b/girepository.c index e8a26474a..8b37b696f 100644 --- a/girepository.c +++ b/girepository.c @@ -30,6 +30,7 @@ #include #include "girepository.h" #include "gtypelib.h" +#include "ginfo.h" #include "config.h" @@ -333,6 +334,7 @@ register_internal (GIRepository *repository, else key = build_typelib_key (namespace, source); + g_printerr ("loaded: %s\n", key); g_hash_table_insert (repository->priv->typelibs, key, (void *)typelib); } @@ -487,6 +489,7 @@ g_irepository_get_n_infos (GIRepository *repository, typedef struct { + GIRepository *repo; gint index; const gchar *name; const gchar *type; @@ -556,8 +559,9 @@ find_interface (gpointer key, if (index != 0) { entry = g_typelib_get_dir_entry (typelib, index); - iface_data->iface = g_info_new (entry->blob_type, NULL, - typelib, entry->offset); + iface_data->iface = g_info_new_full (entry->blob_type, + iface_data->repo, + NULL, typelib, entry->offset); } } @@ -585,6 +589,7 @@ g_irepository_get_info (GIRepository *repository, repository = get_repository (repository); + data.repo = repository; data.name = NULL; data.type = NULL; data.index = index + 1; @@ -621,6 +626,7 @@ g_irepository_find_by_gtype (GIRepository *repository, repository = get_repository (repository); + data.repo = repository; data.name = NULL; data.type = g_type_name (type); data.index = -1; @@ -657,6 +663,7 @@ g_irepository_find_by_name (GIRepository *repository, repository = get_repository (repository); + data.repo = repository; data.name = name; data.type = NULL; data.index = -1; From e8718f02505378cc6bd40514507494232a551f4a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 25 Nov 2008 21:48:38 +0000 Subject: [PATCH 183/692] Remove debug print svn path=/trunk/; revision=971 --- girepository.c | 1 - 1 file changed, 1 deletion(-) diff --git a/girepository.c b/girepository.c index 8b37b696f..40fba52c6 100644 --- a/girepository.c +++ b/girepository.c @@ -334,7 +334,6 @@ register_internal (GIRepository *repository, else key = build_typelib_key (namespace, source); - g_printerr ("loaded: %s\n", key); g_hash_table_insert (repository->priv->typelibs, key, (void *)typelib); } From 74e22b307cdba38027743c380eeeae72be38a3aa Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 25 Nov 2008 22:29:20 +0000 Subject: [PATCH 184/692] =?UTF-8?q?Bug=20559705=20=E2=80=93=20Missing=20as?= =?UTF-8?q?sociation=20between=20static=20methods=20and=20classes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-11-25 Colin Walters Bug 559705 – Missing association between static methods and classes * docs/typelib-format.txt: * girepository/ginfo.c (g_function_info_get_flags): * girepository/girmodule.c (g_ir_module_build_typelib): * girepository/girnode.c (g_ir_node_get_size), (g_ir_node_build_typelib): * girepository/girparser.c (start_function): * girepository/gtypelib.c (g_typelib_check_sanity), (validate_header), (validate_function_blob): * girepository/gtypelib.h: * giscanner/ast.py: * giscanner/girwriter.py: * giscanner/glibtransformer.py: * tests/scanner/foo-1.0-expected.gir: * tests/scanner/foo-1.0-expected.tgir: * tests/scanner/foo.h: svn path=/trunk/; revision=972 --- ginfo.c | 2 +- girmodule.c | 2 +- girnode.c | 3 ++- girparser.c | 4 +++- gtypelib.c | 6 +++--- gtypelib.h | 7 +++++++ 6 files changed, 17 insertions(+), 7 deletions(-) diff --git a/ginfo.c b/ginfo.c index 0e39bcd07..5df1e3f83 100644 --- a/ginfo.c +++ b/ginfo.c @@ -494,7 +494,7 @@ g_function_info_get_flags (GIFunctionInfo *info) flags = 0; /* Make sure we don't flag Constructors as methods */ - if (base->container != NULL && !blob->constructor) + if (!blob->constructor && !blob->is_static) flags = flags | GI_FUNCTION_IS_METHOD; if (blob->constructor) diff --git a/girmodule.c b/girmodule.c index 1b26f3de4..be41a1ed3 100644 --- a/girmodule.c +++ b/girmodule.c @@ -209,7 +209,7 @@ g_ir_module_build_typelib (GIrModule *module, : 0); header->directory = ALIGN_VALUE (header_size, 4); header->entry_blob_size = 12; - header->function_blob_size = 16; + header->function_blob_size = sizeof (FunctionBlob); header->callback_blob_size = 12; header->signal_blob_size = 12; header->vfunc_blob_size = 16; diff --git a/girnode.c b/girnode.c index 75dd265c8..61e4f0b6c 100644 --- a/girnode.c +++ b/girnode.c @@ -415,7 +415,7 @@ g_ir_node_get_size (GIrNode *node) break; case G_IR_NODE_FUNCTION: - size = 16; + size = sizeof (FunctionBlob); break; case G_IR_NODE_PARAM: @@ -1581,6 +1581,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->blob_type = BLOB_TYPE_FUNCTION; blob->deprecated = function->deprecated; + blob->is_static = !function->is_method; blob->setter = function->is_setter; blob->getter = function->is_getter; blob->constructor = function->is_constructor; diff --git a/girparser.c b/girparser.c index 48e311923..e6d59b4c3 100644 --- a/girparser.c +++ b/girparser.c @@ -674,10 +674,12 @@ start_function (GMarkupParseContext *context, strcmp (element_name, "callback") == 0); break; case STATE_CLASS: + found = strcmp (element_name, "function") == 0; + /* fallthrough */ case STATE_BOXED: case STATE_STRUCT: case STATE_UNION: - found = strcmp (element_name, "constructor") == 0; + found = (found || strcmp (element_name, "constructor") == 0); /* fallthrough */ case STATE_INTERFACE: found = (found || diff --git a/gtypelib.c b/gtypelib.c index 5cda70579..51cbafcd2 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -167,7 +167,7 @@ g_typelib_check_sanity (void) CHECK_SIZE (ArgBlob, 12); CHECK_SIZE (SignatureBlob, 8); CHECK_SIZE (CommonBlob, 8); - CHECK_SIZE (FunctionBlob, 16); + CHECK_SIZE (FunctionBlob, 20); CHECK_SIZE (InterfaceTypeBlob, 4); CHECK_SIZE (ArrayTypeBlob, 8); CHECK_SIZE (ParamTypeBlob, 4); @@ -315,7 +315,7 @@ validate_header (ValidateContext *ctx, } if (header->entry_blob_size != 12 || - header->function_blob_size != 16 || + header->function_blob_size != 20 || header->callback_blob_size != 12 || header->signal_blob_size != 12 || header->vfunc_blob_size != 16 || @@ -731,7 +731,7 @@ validate_function_blob (ValidateContext *ctx, g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, - "Wrong blob type"); + "Wrong blob type %d, expected function", blob->blob_type); return FALSE; } diff --git a/gtypelib.h b/gtypelib.h index 7db15db3a..343f9e1bb 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -172,10 +172,17 @@ typedef struct guint16 wraps_vfunc : 1; guint16 throws : 1; guint16 index :10; + /* Note the bits above need to match CommonBlob + * and are thus exhausted, extend things using + * the reserved block below. */ guint32 name; guint32 symbol; guint32 signature; + + guint16 is_static : 1; + guint16 reserved : 15; + guint16 reserved2 : 16; } FunctionBlob; typedef struct From 9c62e9fc6eab74a01b969f2a90f61af155e0630c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 1 Dec 2008 17:05:37 +0000 Subject: [PATCH 185/692] Fix memory leak; unref type info we created, not field info We expect callers to own the FieldInfo, we should not unref it. However we should unref the type info we accessed. svn path=/trunk/; revision=981 --- gfield.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gfield.c b/gfield.c index 673e3db7a..4515bcf5b 100644 --- a/gfield.c +++ b/gfield.c @@ -197,7 +197,7 @@ g_field_info_get_field (GIFieldInfo *field_info, } } - g_base_info_unref ((GIBaseInfo *)field_info); + g_base_info_unref ((GIBaseInfo *)type_info); return result; } @@ -389,7 +389,7 @@ g_field_info_set_field (GIFieldInfo *field_info, } } - g_base_info_unref ((GIBaseInfo *)field_info); + g_base_info_unref ((GIBaseInfo *)type_info); return result; } From bb9820839a26bca519d46cb52a0a6c7bcd325ac8 Mon Sep 17 00:00:00 2001 From: Johan Bilien Date: Wed, 10 Dec 2008 17:53:09 +0000 Subject: [PATCH 186/692] =?UTF-8?q?Bug=20563998=20=E2=80=93=20Cache=20the?= =?UTF-8?q?=20GIBaseInfo=20for=20GTypes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-12-10 Johan Bilien Bug 563998 – Cache the GIBaseInfo for GTypes * girepository/girepository.c (g_irepository_find_by_gtype): add a cache of GType -> GIBaseInfo. svn path=/trunk/; revision=991 --- girepository.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/girepository.c b/girepository.c index 40fba52c6..56c1e9952 100644 --- a/girepository.c +++ b/girepository.c @@ -42,6 +42,7 @@ struct _GIRepositoryPrivate { GHashTable *typelibs; /* (string) namespace -> GTypelib */ GHashTable *lazy_typelibs; /* (string) namespace-version -> GTypelib */ + GHashTable *info_by_gtype; /* GType -> GIBaseInfo */ }; G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT); @@ -57,6 +58,10 @@ g_irepository_init (GIRepository *repository) (GDestroyNotify) g_typelib_free); repository->priv->lazy_typelibs = g_hash_table_new (g_str_hash, g_str_equal); + repository->priv->info_by_gtype + = g_hash_table_new_full (g_direct_hash, g_direct_equal, + (GDestroyNotify) NULL, + (GDestroyNotify) g_base_info_unref); } static void @@ -66,6 +71,7 @@ g_irepository_finalize (GObject *object) g_hash_table_destroy (repository->priv->typelibs); g_hash_table_destroy (repository->priv->lazy_typelibs); + g_hash_table_destroy (repository->priv->info_by_gtype); (* G_OBJECT_CLASS (g_irepository_parent_class)->finalize) (G_OBJECT (repository)); } @@ -625,6 +631,12 @@ g_irepository_find_by_gtype (GIRepository *repository, repository = get_repository (repository); + data.iface = g_hash_table_lookup (repository->priv->info_by_gtype, + (gpointer)type); + + if (data.iface) + return g_base_info_ref (data.iface); + data.repo = repository; data.name = NULL; data.type = g_type_name (type); @@ -634,6 +646,12 @@ g_irepository_find_by_gtype (GIRepository *repository, g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data); + if (data.iface) + g_hash_table_insert (repository->priv->info_by_gtype, + (gpointer) type, + g_base_info_ref (data.iface)); + + return data.iface; } From b95d92aca0d78f7b35649e5ce51f55863a6d2422 Mon Sep 17 00:00:00 2001 From: Andreas Rottmann Date: Sat, 3 Jan 2009 13:44:42 +0000 Subject: [PATCH 187/692] =?UTF-8?q?Bug=20556489=20=E2=80=93=20callback=20a?= =?UTF-8?q?nnotations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-01-03 Andreas Rottmann Bug 556489 – callback annotations * giscanner/transformer.py * tools/generate.c (write_callable_info): Write out the new scope, closure and destroy attributes. * giscanner/transformer.py (Transformer._type_is_callback): New method, checking if a given type is a callback. (Transformer._augment_callback_params): New method; adds information (closure, destroy) to callback parameters. (Transformer._handle_closure, Transformer._handle_destroy): New methods, auxiliary to _augment_callback_params. (Transformer._create_function): Call _augment_callback_params(). (Transformer._create_parameter): Handle scope option. (Transformer._create_typedef_callback): New method, creates a callback, and registers it in the typedef namespace (Transformer._create_typedef): Use _create_typedef_callback() instead of the plain _create_callback(). * giscanner/ast.py (Parameter): Added callback-related fields. * giscanner/girwriter.py: Write out new Parameter fields. * girepository/girnode.h (GIrNodeParam): Added fields scope, closure and destroy. * girepository/gtypelib.h (ArgBlob): Ditto. * girepository/girparser.c (start_parameter): Handle new fields. * girepository/girmodule.c (g_ir_module_build_typelib): Adjust arg_blob_size, bump major version due to this change. * girepository/girnode.c (g_ir_node_get_full_size_internal) (g_ir_node_build_typelib) * girepository/gtypelib.c (g_typelib_check_sanity): ArgBlob size adjustments. (g_ir_node_build_typelib): Fill in new ArgBlob flags from param. * girepository/girepository.h (GIScope): New enumeration, listing the different possible scopes for callbacks. * girepository/ginfo.c (g_arg_info_get_scope) (g_arg_info_get_closure, g_arg_info_get_destroy): Accessors for callback-related argument indices (callback scope, closure for a callback, destroy notification for a callback). * tests/scanner/: Added testcases for new features. svn path=/trunk/; revision=998 --- ginfo.c | 29 ++++++++++++++++++++++++++++- girepository.h | 11 +++++++++++ girmodule.c | 4 ++-- girnode.c | 9 ++++++--- girnode.h | 4 ++++ girparser.c | 22 +++++++++++++++++++++- gtypelib.c | 6 +++--- gtypelib.h | 6 +++++- 8 files changed, 80 insertions(+), 11 deletions(-) diff --git a/ginfo.c b/ginfo.c index 5df1e3f83..8324c05b0 100644 --- a/ginfo.c +++ b/ginfo.c @@ -741,12 +741,39 @@ g_arg_info_get_ownership_transfer (GIArgInfo *info) return GI_TRANSFER_NOTHING; } +GIScopeType +g_arg_info_get_scope (GIArgInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + + return blob->scope; +} + +gint +g_arg_info_get_closure (GIArgInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + + return blob->closure; +} + +gint +g_arg_info_get_destroy (GIArgInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + + return blob->destroy; +} + GITypeInfo * g_arg_info_get_type (GIArgInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - return g_type_info_new (base, base->typelib, base->offset + 8); + return g_type_info_new (base, base->typelib, base->offset + 12); } /* GITypeInfo functions */ diff --git a/girepository.h b/girepository.h index abeb85700..38697c69f 100644 --- a/girepository.h +++ b/girepository.h @@ -269,12 +269,23 @@ typedef enum { GI_DIRECTION_INOUT } GIDirection; +typedef enum { + GI_SCOPE_TYPE_INVALID, + GI_SCOPE_TYPE_CALL, + GI_SCOPE_TYPE_OBJECT, + GI_SCOPE_TYPE_ASYNC, + GI_SCOPE_TYPE_NOTIFIED +} GIScopeType; + GIDirection g_arg_info_get_direction (GIArgInfo *info); gboolean g_arg_info_is_dipper (GIArgInfo *info); gboolean g_arg_info_is_return_value (GIArgInfo *info); gboolean g_arg_info_is_optional (GIArgInfo *info); gboolean g_arg_info_may_be_null (GIArgInfo *info); GITransfer g_arg_info_get_ownership_transfer (GIArgInfo *info); +GIScopeType g_arg_info_get_scope (GIArgInfo *info); +gint g_arg_info_get_closure (GIArgInfo *info); +gint g_arg_info_get_destroy (GIArgInfo *info); GITypeInfo * g_arg_info_get_type (GIArgInfo *info); diff --git a/girmodule.c b/girmodule.c index be41a1ed3..85103bff1 100644 --- a/girmodule.c +++ b/girmodule.c @@ -190,7 +190,7 @@ g_ir_module_build_typelib (GIrModule *module, /* fill in header */ header = (Header *)data; memcpy (header, G_IR_MAGIC, 16); - header->major_version = 1; + header->major_version = 2; header->minor_version = 0; header->reserved = 0; header->n_entries = n_entries; @@ -213,7 +213,7 @@ g_ir_module_build_typelib (GIrModule *module, header->callback_blob_size = 12; header->signal_blob_size = 12; header->vfunc_blob_size = 16; - header->arg_blob_size = 12; + header->arg_blob_size = 16; header->property_blob_size = 12; header->field_blob_size = 12; header->value_blob_size = 12; diff --git a/girnode.c b/girnode.c index 61e4f0b6c..c4045ef7e 100644 --- a/girnode.c +++ b/girnode.c @@ -582,7 +582,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeParam *param = (GIrNodeParam *)node; - size = 12; + size = 16; if (node->name) size += ALIGN_VALUE (strlen (node->name) + 1, 4); size += g_ir_node_get_full_size_internal (node, (GIrNode *)param->type); @@ -1764,7 +1764,7 @@ g_ir_node_build_typelib (GIrNode *node, ArgBlob *blob = (ArgBlob *)&data[*offset]; GIrNodeParam *param = (GIrNodeParam *)node; - *offset += 8; + *offset += 12; blob->name = write_string (node->name, strings, data, offset2); blob->in = param->in; @@ -1775,8 +1775,11 @@ g_ir_node_build_typelib (GIrNode *node, blob->transfer_ownership = param->transfer; blob->transfer_container_ownership = param->shallow_transfer; blob->return_value = param->retval; + blob->scope = param->scope; blob->reserved = 0; - + blob->closure = param->closure; + blob->destroy = param->destroy; + g_ir_node_build_typelib ((GIrNode *)param->type, module, modules, strings, types, data, offset, offset2); } diff --git a/girnode.h b/girnode.h index 674594d8a..a1b8f0dc0 100644 --- a/girnode.h +++ b/girnode.h @@ -143,6 +143,10 @@ struct _GIrNodeParam gboolean allow_none; gboolean transfer; gboolean shallow_transfer; + GIScopeType scope; + + gint8 closure; + gint8 destroy; GIrNodeType *type; }; diff --git a/girparser.c b/girparser.c index e6d59b4c3..1072ecc5a 100644 --- a/girparser.c +++ b/girparser.c @@ -837,6 +837,9 @@ start_parameter (GMarkupParseContext *context, const gchar *optional; const gchar *allow_none; const gchar *transfer; + const gchar *scope; + const gchar *closure; + const gchar *destroy; GIrNodeParam *param; if (!(strcmp (element_name, "parameter") == 0 && @@ -850,7 +853,10 @@ start_parameter (GMarkupParseContext *context, optional = find_attribute ("optional", attribute_names, attribute_values); allow_none = find_attribute ("allow-none", attribute_names, attribute_values); transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); - + scope = find_attribute ("scope", attribute_names, attribute_values); + closure = find_attribute ("closure", attribute_names, attribute_values); + destroy = find_attribute ("destroy", attribute_names, attribute_values); + if (name == NULL) name = "unknown"; @@ -899,6 +905,20 @@ start_parameter (GMarkupParseContext *context, parse_param_transfer (param, transfer); + if (scope && strcmp (scope, "call") == 0) + param->scope = GI_SCOPE_TYPE_CALL; + else if (scope && strcmp (scope, "object") == 0) + param->scope = GI_SCOPE_TYPE_OBJECT; + else if (scope && strcmp (scope, "async") == 0) + param->scope = GI_SCOPE_TYPE_ASYNC; + else if (scope && strcmp (scope, "notified") == 0) + param->scope = GI_SCOPE_TYPE_NOTIFIED; + else + param->scope = GI_SCOPE_TYPE_INVALID; + + param->closure = closure ? atoi (closure) : -1; + param->destroy = destroy ? atoi (destroy) : -1; + ((GIrNode *)param)->name = g_strdup (name); switch (ctx->current_node->type) diff --git a/gtypelib.c b/gtypelib.c index 51cbafcd2..d7b09f214 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -164,7 +164,7 @@ g_typelib_check_sanity (void) CHECK_SIZE (Header, 108); CHECK_SIZE (DirEntry, 12); CHECK_SIZE (SimpleTypeBlob, 4); - CHECK_SIZE (ArgBlob, 12); + CHECK_SIZE (ArgBlob, 16); CHECK_SIZE (SignatureBlob, 8); CHECK_SIZE (CommonBlob, 8); CHECK_SIZE (FunctionBlob, 20); @@ -286,7 +286,7 @@ validate_header (ValidateContext *ctx, } - if (header->major_version != 1 || header->minor_version != 0) + if (header->major_version != 2 || header->minor_version != 0) { g_set_error (error, G_TYPELIB_ERROR, @@ -319,7 +319,7 @@ validate_header (ValidateContext *ctx, header->callback_blob_size != 12 || header->signal_blob_size != 12 || header->vfunc_blob_size != 16 || - header->arg_blob_size != 12 || + header->arg_blob_size != 16 || header->property_blob_size != 12 || header->field_blob_size != 12 || header->value_blob_size != 12 || diff --git a/gtypelib.h b/gtypelib.h index 343f9e1bb..a68d00800 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -132,7 +132,11 @@ typedef struct guint transfer_ownership : 1; guint transfer_container_ownership : 1; guint return_value : 1; - guint reserved :24; + guint scope : 3; + guint reserved :21; + + gint8 closure; + gint8 destroy; SimpleTypeBlob arg_type; } ArgBlob; From ca638d9ecf711f67cd14afdfa710924367d9f9ae Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 12 Jan 2009 21:31:43 +0000 Subject: [PATCH 188/692] Bug 567087 - generic marshaller Since GObject-Introspection depends on both ffi and GObject, it's a convenient home for jdahlin's generic signal marshaller until such time as GObject can directly depend on ffi. When it gets added to GObject, we can simply point our marshaller at that one. svn path=/trunk/; revision=1022 --- ginvoke.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++ girepository.h | 9 +++ 2 files changed, 180 insertions(+) diff --git a/ginvoke.c b/ginvoke.c index 89419e569..e83a8200a 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -261,3 +261,174 @@ g_function_info_invoke (GIFunctionInfo *info, out: return success; } + +static ffi_type * +value_to_ffi_type (const GValue *gvalue, gpointer *value) +{ + ffi_type *rettype = NULL; + GType type = g_type_fundamental (G_VALUE_TYPE (gvalue)); + g_assert (type != G_TYPE_INVALID); + + switch (type) + { + case G_TYPE_BOOLEAN: + case G_TYPE_CHAR: + case G_TYPE_INT: + rettype = &ffi_type_sint; + *value = (gpointer)&(gvalue->data[0].v_int); + break; + case G_TYPE_UCHAR: + case G_TYPE_UINT: + rettype = &ffi_type_uint; + *value = (gpointer)&(gvalue->data[0].v_uint); + break; + case G_TYPE_STRING: + case G_TYPE_OBJECT: + case G_TYPE_BOXED: + case G_TYPE_POINTER: + rettype = &ffi_type_pointer; + *value = (gpointer)&(gvalue->data[0].v_pointer); + break; + case G_TYPE_FLOAT: + rettype = &ffi_type_float; + *value = (gpointer)&(gvalue->data[0].v_float); + break; + case G_TYPE_DOUBLE: + rettype = &ffi_type_double; + *value = (gpointer)&(gvalue->data[0].v_double); + break; + case G_TYPE_LONG: + rettype = &ffi_type_slong; + *value = (gpointer)&(gvalue->data[0].v_long); + break; + case G_TYPE_ULONG: + rettype = &ffi_type_ulong; + *value = (gpointer)&(gvalue->data[0].v_ulong); + break; + case G_TYPE_INT64: + rettype = &ffi_type_sint64; + *value = (gpointer)&(gvalue->data[0].v_int64); + break; + case G_TYPE_UINT64: + rettype = &ffi_type_uint64; + *value = (gpointer)&(gvalue->data[0].v_uint64); + break; + default: + rettype = &ffi_type_pointer; + *value = NULL; + g_warning ("Unsupported fundamental type: %s", g_type_name (type)); + break; + } + return rettype; +} + +static void +value_from_ffi_type (GValue *gvalue, gpointer *value) +{ + switch (g_type_fundamental (G_VALUE_TYPE (gvalue))) + { + case G_TYPE_INT: + g_value_set_int (gvalue, *(gint*)value); + break; + case G_TYPE_FLOAT: + g_value_set_float (gvalue, *(gfloat*)value); + break; + case G_TYPE_DOUBLE: + g_value_set_double (gvalue, *(gdouble*)value); + break; + case G_TYPE_BOOLEAN: + g_value_set_boolean (gvalue, *(gboolean*)value); + break; + case G_TYPE_STRING: + g_value_set_string (gvalue, *(gchar**)value); + break; + case G_TYPE_CHAR: + g_value_set_char (gvalue, *(gchar*)value); + break; + case G_TYPE_UCHAR: + g_value_set_uchar (gvalue, *(guchar*)value); + break; + case G_TYPE_UINT: + g_value_set_uint (gvalue, *(guint*)value); + break; + case G_TYPE_POINTER: + g_value_set_pointer (gvalue, *(gpointer*)value); + break; + case G_TYPE_LONG: + g_value_set_long (gvalue, *(glong*)value); + break; + case G_TYPE_ULONG: + g_value_set_ulong (gvalue, *(gulong*)value); + break; + case G_TYPE_INT64: + g_value_set_int64 (gvalue, *(gint64*)value); + break; + case G_TYPE_UINT64: + g_value_set_uint64 (gvalue, *(guint64*)value); + break; + case G_TYPE_BOXED: + g_value_set_boxed (gvalue, *(gpointer*)value); + break; + default: + g_warning ("Unsupported fundamental type: %s", + g_type_name (g_type_fundamental (G_VALUE_TYPE (gvalue)))); + } +} + +void +gi_cclosure_marshal_generic (GClosure *closure, + GValue *return_gvalue, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + ffi_type *rtype; + void *rvalue; + int n_args; + ffi_type **atypes; + void **args; + int i; + ffi_cif cif; + GCClosure *cc = (GCClosure*) closure; + + if (return_gvalue && G_VALUE_TYPE (return_gvalue)) + { + rtype = value_to_ffi_type (return_gvalue, &rvalue); + } + else + { + rtype = &ffi_type_void; + } + + rvalue = g_alloca (MAX (rtype->size, sizeof (ffi_arg))); + + n_args = n_param_values + 1; + atypes = g_alloca (sizeof (ffi_type *) * n_args); + args = g_alloca (sizeof (gpointer) * n_args); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + atypes[n_args-1] = value_to_ffi_type (param_values + 0, + &args[n_args-1]); + atypes[0] = &ffi_type_pointer; + args[0] = &closure->data; + } + else + { + atypes[0] = value_to_ffi_type (param_values + 0, &args[0]); + atypes[n_args-1] = &ffi_type_pointer; + args[n_args-1] = &closure->data; + } + + for (i = 1; i < n_args - 1; i++) + atypes[i] = value_to_ffi_type (param_values + i, &args[i]); + + if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, rtype, atypes) != FFI_OK) + return; + + ffi_call (&cif, marshal_data ? marshal_data : cc->callback, rvalue, args); + + if (return_gvalue && G_VALUE_TYPE (return_gvalue)) + value_from_ffi_type (return_gvalue, rvalue); +} diff --git a/girepository.h b/girepository.h index 38697c69f..340c7fa48 100644 --- a/girepository.h +++ b/girepository.h @@ -141,6 +141,15 @@ typedef enum GQuark g_irepository_error_quark (void); +/* Global utility functions */ + +void gi_cclosure_marshal_generic (GClosure *closure, + GValue *return_gvalue, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + /* Types of objects registered in the repository */ typedef enum From 2971e35fe6182643925ab930b2de6479e0715211 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 12 Jan 2009 21:31:45 +0000 Subject: [PATCH 189/692] Bug 567212: Exit after dumping The intended use of g_irepository_get_option_group is that your application more transparently supports --introspection-dump; we should exit so that your app doesn't continue trying to launch. svn path=/trunk/; revision=1023 --- girepository.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/girepository.c b/girepository.c index 56c1e9952..540623ae4 100644 --- a/girepository.c +++ b/girepository.c @@ -1174,7 +1174,8 @@ g_irepository_introspect_cb (const char *option_name, gpointer data, GError **error) { - return g_irepository_dump (value, error); + gboolean ret = g_irepository_dump (value, error); + exit (ret ? 0 : 1); } static const GOptionEntry introspection_args[] = { From 3fff99dfcc2bce9dfd3abd71999ae23c913ecc37 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 12 Jan 2009 21:42:58 +0000 Subject: [PATCH 190/692] Bug 562914: Order GI_TYPELIB_PATH before anything else We want the environment variable to override so that people can easily write scripts that run their programs uninstalled. svn path=/trunk/; revision=1024 --- girepository.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/girepository.c b/girepository.c index 540623ae4..6b34e05b6 100644 --- a/girepository.c +++ b/girepository.c @@ -37,6 +37,7 @@ static GStaticMutex globals_lock = G_STATIC_MUTEX_INIT; static GIRepository *default_repository = NULL; static GSList *search_path = NULL; +static GSList *override_search_path = NULL; struct _GIRepositoryPrivate { @@ -104,9 +105,13 @@ init_globals (void) char *typelib_dir; const gchar *type_lib_path_env; + /* This variable is intended to take precedence over both the default + * search path, as well as anything written into code with g_irepository_prepend_search_path. + */ type_lib_path_env = g_getenv ("GI_TYPELIB_PATH"); search_path = NULL; + override_search_path = NULL; if (type_lib_path_env) { gchar **custom_dirs; @@ -117,7 +122,7 @@ init_globals (void) d = custom_dirs; while (*d) { - search_path = g_slist_prepend (search_path, *d); + override_search_path = g_slist_prepend (override_search_path, *d); d++; } @@ -159,6 +164,21 @@ g_irepository_get_search_path (void) return search_path; } +static +GSList * +build_search_path_with_overrides (void) +{ + GSList *result; + if (override_search_path != NULL) + { + result = g_slist_copy (override_search_path); + g_slist_last (result)->next = g_slist_copy (search_path); + } + else + result = g_slist_copy (search_path); + return result; +} + static char * build_typelib_key (const char *name, const char *source) { @@ -843,6 +863,7 @@ find_namespace_version (const gchar *namespace, const gchar *version, gchar **path_ret) { + GSList *tmp_path; GSList *ldir; GError *error = NULL; GMappedFile *mfile = NULL; @@ -850,7 +871,8 @@ find_namespace_version (const gchar *namespace, fname = g_strdup_printf ("%s-%s.typelib", namespace, version); - for (ldir = search_path; ldir; ldir = ldir->next) + tmp_path = build_search_path_with_overrides (); + for (ldir = tmp_path; ldir; ldir = ldir->next) { char *path = g_build_filename (ldir->data, fname, NULL); @@ -865,6 +887,7 @@ find_namespace_version (const gchar *namespace, break; } g_free (fname); + g_slist_free (tmp_path); return mfile; } @@ -963,6 +986,7 @@ find_namespace_latest (const gchar *namespace, gchar **version_ret, gchar **path_ret) { + GSList *tmp_path; GSList *ldir; GError *error = NULL; char *namespace_dash; @@ -978,7 +1002,8 @@ find_namespace_latest (const gchar *namespace, namespace_typelib = g_strdup_printf ("%s.typelib", namespace); index = 0; - for (ldir = search_path; ldir; ldir = ldir->next) + tmp_path = build_search_path_with_overrides (); + for (ldir = tmp_path; ldir; ldir = ldir->next) { GDir *dir; const char *dirname; @@ -1048,9 +1073,9 @@ find_namespace_latest (const gchar *namespace, g_slist_foreach (candidates, (GFunc) free_candidate, NULL); g_slist_free (candidates); } - g_free (namespace_dash); g_free (namespace_typelib); + g_slist_free (tmp_path); return result; } From 9bf5ee61a42ec93403b6627fba45d15df67851ee Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 15 Jan 2009 22:31:07 +0000 Subject: [PATCH 191/692] =?UTF-8?q?Bug=20567813=20=E2=80=93=20Everything?= =?UTF-8?q?=20should=20be=20versioned?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2009-01-15 Johan Dahlin Bug 567813 – Everything should be versioned * gir/Makefile.am: * girepository/Makefile.am: * girepository/girepository.c (init_globals): * girepository/girparser.c (locate_gir): * giscanner/dumper.py: * giscanner/transformer.py: * gobject-introspection-1.0.pc.in: * tests/everything/Makefile.am: * tests/invoke/Makefile.am: * tests/offsets/Makefile.am: * tests/repository/Makefile.am: * tests/scanner/Makefile.am: * tools/Makefile.am: svn path=/trunk/; revision=1046 --- Makefile.am | 12 ++++++------ girepository.c | 2 +- girparser.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile.am b/Makefile.am index 4554d5710..dc8a6cae6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,14 +1,14 @@ include $(top_srcdir)/gcov.mak -GCOVSOURCES = $(libgirepository_la_SOURCES) +GCOVSOURCES = $(libgirepository_1_0_la_SOURCES) girepodir = $(includedir)/gobject-introspection-1.0/ girepo_HEADERS = girepository.h -lib_LTLIBRARIES = libgirepository.la +lib_LTLIBRARIES = libgirepository-1.0.la noinst_LTLIBRARIES = libgirepository-parser.la -libgirepository_la_SOURCES = \ +libgirepository_1_0_la_SOURCES = \ girepository.c \ gtypelib.h \ gtypelib.c \ @@ -20,9 +20,9 @@ libgirepository_la_SOURCES = \ gdump.c \ ginvoke.c -libgirepository_la_CPPFLAGS = $(GIREPO_CFLAGS) -libgirepository_la_LIBADD = $(GIREPO_LIBS) -libgirepository_la_LDFLAGS = -no-undefined +libgirepository_1_0_la_CPPFLAGS = $(GIREPO_CFLAGS) +libgirepository_1_0_la_LIBADD = $(GIREPO_LIBS) +libgirepository_1_0_la_LDFLAGS = -no-undefined libgirepository_parser_la_SOURCES = \ girmodule.c \ diff --git a/girepository.c b/girepository.c index 6b34e05b6..f35854a7d 100644 --- a/girepository.c +++ b/girepository.c @@ -132,7 +132,7 @@ init_globals (void) libdir = GOBJECT_INTROSPECTION_LIBDIR; - typelib_dir = g_build_filename (libdir, "girepository", NULL); + typelib_dir = g_build_filename (libdir, "girepository-1.0", NULL); search_path = g_slist_prepend (search_path, typelib_dir); diff --git a/girparser.c b/girparser.c index 1072ecc5a..381c334fb 100644 --- a/girparser.c +++ b/girparser.c @@ -243,7 +243,7 @@ locate_gir (GIrParser *parser, } for (dir = datadirs; *dir; dir++) { - path = g_build_filename (*dir, "gir", girname, NULL); + path = g_build_filename (*dir, "gir-1.0", girname, NULL); if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) return path; g_free (path); From 40e6b947905063aca5bd6aff9ba24444c55990af Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 16 Jan 2009 00:42:22 +0000 Subject: [PATCH 192/692] add FT_Int32 add XftFont Report errors when an invalid type is encountered 2009-01-15 Johan Dahlin * gir/freetype2-2.0.gir: add FT_Int32 * gir/xft-2.0.gir: add XftFont * girepository/gdump.c (g_irepository_dump): Report errors when an invalid type is encountered * giscanner/glibtransformer.py: Make the error message a bit nicer. Part of preparating for gir generating inside pango. svn path=/trunk/; revision=1050 --- gdump.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gdump.c b/gdump.c index 23650becd..519672aa7 100644 --- a/gdump.c +++ b/gdump.c @@ -362,7 +362,8 @@ g_irepository_dump (const char *arg, GError **error) if (type == G_TYPE_INVALID) { - caught_error = TRUE; + g_printerr ("Invalid GType: '%s'\n", line); + caught_error = TRUE; g_free (line); break; } From a0a60f2601d5f0cec5e12b8da4ddf00b1a2bc9b2 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Mon, 26 Jan 2009 17:56:48 +0000 Subject: [PATCH 193/692] Only unref the repository if it's actually set. 2009-01-26 Johan Dahlin * girepository/ginfo.c (g_base_info_unref): Only unref the repository if it's actually set. svn path=/trunk/; revision=1068 --- ginfo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ginfo.c b/ginfo.c index 8324c05b0..97aa5342e 100644 --- a/ginfo.c +++ b/ginfo.c @@ -227,7 +227,8 @@ g_base_info_unref (GIBaseInfo *info) if (info->container) g_base_info_unref (info->container); - g_object_unref (info->repository); + if (info->repository) + g_object_unref (info->repository); g_free (info); } From 8ac6225faf25ebb5b7c67f5e93b88d089b6f5347 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Thu, 29 Jan 2009 10:32:25 +0000 Subject: [PATCH 194/692] post_filter_varargs_functions should also filter callbacks. Add tests of * girepository/girparser.c: post_filter_varargs_functions should also filter callbacks. * tests/scanner/foo.h: Add tests of varargs callbacks. svn path=/trunk/; revision=1075 --- girparser.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 11 deletions(-) diff --git a/girparser.c b/girparser.c index 381c334fb..76795366a 100644 --- a/girparser.c +++ b/girparser.c @@ -2976,18 +2976,19 @@ cleanup (GMarkupParseContext *context, } static GList * -post_filter_varargs_functions (GList *list) +post_filter_varargs_functions (GList *list, GList ** varargs_callbacks_out) { GList *iter; - + GList *varargs_callbacks = *varargs_callbacks_out; + iter = list; while (iter) { GList *link = iter; GIrNode *node = iter->data; - + iter = iter->next; - + if (node->type == G_IR_NODE_FUNCTION) { if (((GIrNodeFunction*)node)->is_varargs) @@ -2995,7 +2996,60 @@ post_filter_varargs_functions (GList *list) list = g_list_delete_link (list, link); } } + if (node->type == G_IR_NODE_CALLBACK) + { + if (((GIrNodeFunction*)node)->is_varargs) + { + varargs_callbacks = g_list_append(varargs_callbacks, + node); + list = g_list_delete_link (list, link); + } + } } + iter = list; + while (iter) + { + GList *link = iter; + GIrNode *node = iter->data; + + iter = iter->next; + + if (node->type == G_IR_NODE_FUNCTION) + { + GList *param; + gboolean function_done = FALSE; + + for (param = ((GIrNodeFunction *)node)->parameters; + param; + param = param->next) + { + GIrNodeParam *node = (GIrNodeParam *)param->data; + + if (function_done) + break; + + if (node->type->is_interface) + { + GList *callback; + for (callback = varargs_callbacks; + callback; + callback = callback->next) + { + if (!strcmp(node->type->interface, + ((GIrNode *)varargs_callbacks->data)->name)) + { + list = g_list_delete_link (list, link); + function_done = TRUE; + break; + } + } + } + } + } + } + + *varargs_callbacks_out = varargs_callbacks; + return list; } @@ -3003,37 +3057,44 @@ static void post_filter (GIrModule *module) { GList *iter; - - module->entries = post_filter_varargs_functions (module->entries); + GList *varargs_callbacks = NULL; + + module->entries = post_filter_varargs_functions (module->entries, + &varargs_callbacks); iter = module->entries; while (iter) { GIrNode *node = iter->data; - + iter = iter->next; if (node->type == G_IR_NODE_OBJECT || node->type == G_IR_NODE_INTERFACE) { GIrNodeInterface *iface = (GIrNodeInterface*)node; - iface->members = post_filter_varargs_functions (iface->members); + iface->members = post_filter_varargs_functions (iface->members, + &varargs_callbacks); } else if (node->type == G_IR_NODE_BOXED) { GIrNodeBoxed *boxed = (GIrNodeBoxed*)node; - boxed->members = post_filter_varargs_functions (boxed->members); + boxed->members = post_filter_varargs_functions (boxed->members, + &varargs_callbacks); } else if (node->type == G_IR_NODE_STRUCT) { GIrNodeStruct *iface = (GIrNodeStruct*)node; - iface->members = post_filter_varargs_functions (iface->members); + iface->members = post_filter_varargs_functions (iface->members, + &varargs_callbacks); } else if (node->type == G_IR_NODE_UNION) { GIrNodeUnion *iface = (GIrNodeUnion*)node; - iface->members = post_filter_varargs_functions (iface->members); + iface->members = post_filter_varargs_functions (iface->members, + &varargs_callbacks); } } + g_list_free(varargs_callbacks); } /** From 3353523d11061e5a9e6541937548b261a3de8790 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Thu, 29 Jan 2009 10:43:05 +0000 Subject: [PATCH 195/692] Undo revision 1075 svn path=/trunk/; revision=1077 --- girparser.c | 103 +++++++++++----------------------------------------- 1 file changed, 21 insertions(+), 82 deletions(-) diff --git a/girparser.c b/girparser.c index 76795366a..381c334fb 100644 --- a/girparser.c +++ b/girparser.c @@ -2976,80 +2976,26 @@ cleanup (GMarkupParseContext *context, } static GList * -post_filter_varargs_functions (GList *list, GList ** varargs_callbacks_out) +post_filter_varargs_functions (GList *list) { GList *iter; - GList *varargs_callbacks = *varargs_callbacks_out; - - iter = list; - while (iter) - { - GList *link = iter; - GIrNode *node = iter->data; - - iter = iter->next; - - if (node->type == G_IR_NODE_FUNCTION) - { - if (((GIrNodeFunction*)node)->is_varargs) - { - list = g_list_delete_link (list, link); - } - } - if (node->type == G_IR_NODE_CALLBACK) - { - if (((GIrNodeFunction*)node)->is_varargs) - { - varargs_callbacks = g_list_append(varargs_callbacks, - node); - list = g_list_delete_link (list, link); - } - } - } - iter = list; - while (iter) - { - GList *link = iter; - GIrNode *node = iter->data; - - iter = iter->next; - - if (node->type == G_IR_NODE_FUNCTION) - { - GList *param; - gboolean function_done = FALSE; - - for (param = ((GIrNodeFunction *)node)->parameters; - param; - param = param->next) - { - GIrNodeParam *node = (GIrNodeParam *)param->data; - - if (function_done) - break; - if (node->type->is_interface) - { - GList *callback; - for (callback = varargs_callbacks; - callback; - callback = callback->next) - { - if (!strcmp(node->type->interface, - ((GIrNode *)varargs_callbacks->data)->name)) - { - list = g_list_delete_link (list, link); - function_done = TRUE; - break; - } - } - } + iter = list; + while (iter) + { + GList *link = iter; + GIrNode *node = iter->data; + + iter = iter->next; + + if (node->type == G_IR_NODE_FUNCTION) + { + if (((GIrNodeFunction*)node)->is_varargs) + { + list = g_list_delete_link (list, link); } } } - - *varargs_callbacks_out = varargs_callbacks; - return list; } @@ -3057,44 +3003,37 @@ static void post_filter (GIrModule *module) { GList *iter; - GList *varargs_callbacks = NULL; - - module->entries = post_filter_varargs_functions (module->entries, - &varargs_callbacks); + + module->entries = post_filter_varargs_functions (module->entries); iter = module->entries; while (iter) { GIrNode *node = iter->data; - + iter = iter->next; if (node->type == G_IR_NODE_OBJECT || node->type == G_IR_NODE_INTERFACE) { GIrNodeInterface *iface = (GIrNodeInterface*)node; - iface->members = post_filter_varargs_functions (iface->members, - &varargs_callbacks); + iface->members = post_filter_varargs_functions (iface->members); } else if (node->type == G_IR_NODE_BOXED) { GIrNodeBoxed *boxed = (GIrNodeBoxed*)node; - boxed->members = post_filter_varargs_functions (boxed->members, - &varargs_callbacks); + boxed->members = post_filter_varargs_functions (boxed->members); } else if (node->type == G_IR_NODE_STRUCT) { GIrNodeStruct *iface = (GIrNodeStruct*)node; - iface->members = post_filter_varargs_functions (iface->members, - &varargs_callbacks); + iface->members = post_filter_varargs_functions (iface->members); } else if (node->type == G_IR_NODE_UNION) { GIrNodeUnion *iface = (GIrNodeUnion*)node; - iface->members = post_filter_varargs_functions (iface->members, - &varargs_callbacks); + iface->members = post_filter_varargs_functions (iface->members); } } - g_list_free(varargs_callbacks); } /** From 4e5037e0f3e446eb491f7a3ce989aca7daffb796 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 2 Feb 2009 16:31:02 +0000 Subject: [PATCH 196/692] =?UTF-8?q?Bug=20563469=20=E2=80=93=20Arrays=20not?= =?UTF-8?q?=20treated=20correctly=20in=20struct=20offset=20calculation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Arrays are currently not handled specially, and hence treated as pointers in giroffsets.c:get_field_size_alignment(), which is (obviously) wrong. svn path=/trunk/; revision=1078 --- giroffsets.c | 83 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 26 deletions(-) diff --git a/giroffsets.c b/giroffsets.c index 46cdbd90c..f224e6931 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -144,21 +144,19 @@ get_enum_size_alignment (GIrNodeEnum *enum_node, } static gboolean -get_interface_size_alignment (GIrNodeField *field, - GIrNode *parent_node, - GIrModule *module, - GList *modules, - gint *size, - gint *alignment) +get_interface_size_alignment (GIrNodeType *type, + GIrModule *module, + GList *modules, + gint *size, + gint *alignment, + const char *who) { - GIrNodeType *type = field->type; GIrNode *iface; GIrModule *iface_module; if (!g_ir_find_node (module, modules, type->interface, &iface, &iface_module)) { - g_warning ("Can't resolve type '%s' for field %s.%s.%s", - type->interface, module->name, parent_node->name, ((GIrNode *)field)->name); + g_warning ("Can't resolve type '%s' for %s", type->interface, who); *size = -1; *alignment = -1; return FALSE; @@ -212,8 +210,8 @@ get_interface_size_alignment (GIrNodeField *field, } default: { - g_warning ("Field %s.%s.%s has is not a pointer and is of type %s", - module->name, parent_node->name, ((GIrNode *)field)->name, + g_warning ("%s has is not a pointer and is of type %s", + who, g_ir_node_type_to_string (iface->type)); *size = -1; *alignment = -1; @@ -225,17 +223,34 @@ get_interface_size_alignment (GIrNodeField *field, } static gboolean -get_field_size_alignment (GIrNodeField *field, - GIrNode *parent_node, - GIrModule *module, - GList *modules, - gint *size, - gint *alignment) +get_type_size_alignment (GIrNodeType *type, + GIrModule *module, + GList *modules, + gint *size, + gint *alignment, + const char *who) { - GIrNodeType *type = field->type; ffi_type *type_ffi; - if (type->is_pointer) + if (type->tag == GI_TYPE_TAG_ARRAY) + { + gint elt_size, elt_alignment; + + if (!type->has_size + || !get_type_size_alignment(type->parameter_type1, module, modules, + &elt_size, &elt_alignment, who)) + { + *size = -1; + *alignment = -1; + return FALSE; + } + + *size = type->size * elt_size; + *alignment = elt_alignment; + + return TRUE; + } + else if (type->is_pointer) { type_ffi = &ffi_type_pointer; } @@ -243,9 +258,7 @@ get_field_size_alignment (GIrNodeField *field, { if (type->tag == GI_TYPE_TAG_INTERFACE) { - return get_interface_size_alignment (field, parent_node, - module, modules, - size, alignment); + return get_interface_size_alignment (type, module, modules, size, alignment, who); } else { @@ -253,16 +266,15 @@ get_field_size_alignment (GIrNodeField *field, if (type_ffi == &ffi_type_void) { - g_warning ("Field %s.%s.%s has void type", - module->name, parent_node->name, ((GIrNode *)field)->name); + g_warning ("%s has void type", who); *size = -1; *alignment = -1; return FALSE; } else if (type_ffi == &ffi_type_pointer) { - g_warning ("Field %s.%s.%s has is not a pointer and is of type %s", - module->name, parent_node->name, ((GIrNode *)field)->name, + g_warning ("%s has is not a pointer and is of type %s", + who, g_type_tag_to_string (type->tag)); *size = -1; *alignment = -1; @@ -278,6 +290,25 @@ get_field_size_alignment (GIrNodeField *field, return TRUE; } +static gboolean +get_field_size_alignment (GIrNodeField *field, + GIrNode *parent_node, + GIrModule *module, + GList *modules, + gint *size, + gint *alignment) +{ + gchar *who; + gboolean success; + + who = g_strdup_printf ("field %s.%s.%s", module->name, parent_node->name, ((GIrNode *)field)->name); + + success = get_type_size_alignment (field->type, module, modules, size, alignment, who); + g_free (who); + + return success; +} + #define ALIGN(n, align) (((n) + (align) - 1) & ~((align) - 1)) static gboolean From 306ca05c5e681c6a842e9b6ed35c9f9f77186baf Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 2 Feb 2009 16:31:06 +0000 Subject: [PATCH 197/692] Bug 569408, Bug 568680 - Scanner misses fields (at least in GObject.Object) The scanner misses all fields of the GObject struct -- there are no children of the element for GObject in the GIR. This of course yields wrong field offsets for all derived objects. svn path=/trunk/; revision=1079 --- giroffsets.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/giroffsets.c b/giroffsets.c index f224e6931..cc56d0bc8 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -357,8 +357,9 @@ compute_struct_field_offsets (GIrNode *node, } else if (member->type == G_IR_NODE_CALLBACK) { - size = ffi_type_pointer.size; - alignment = ffi_type_pointer.alignment; + size = ALIGN (size, ffi_type_pointer.alignment); + alignment = MAX (alignment, ffi_type_pointer.alignment); + size += ffi_type_pointer.size; } } From 0ed02eb80bed5972fa9c6ad37beef98160f833d8 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Mon, 2 Feb 2009 20:41:30 +0000 Subject: [PATCH 198/692] handle the special case for GObject, whose glib:get-type is listed as * girepository/ginfo.c (g_registered_type_info_get_g_type): handle the special case for GObject, whose glib:get-type is listed as "intern". svn path=/trunk/; revision=1080 --- ginfo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ginfo.c b/ginfo.c index 97aa5342e..289717d53 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1061,6 +1061,8 @@ g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info) if (type_init == NULL) return G_TYPE_NONE; + else if (!strcmp (type_init, "intern")) + return G_TYPE_OBJECT; get_type_func = NULL; if (!g_typelib_symbol (((GIBaseInfo*)info)->typelib, From 8a0cdd96e954da241e0a6e8dda184147df9b4148 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 4 Feb 2009 00:48:17 +0000 Subject: [PATCH 199/692] Bug 555960 - nested structs and unions Patch from Andreas Rottmann . This change modifies the parser to hold a stack of nodes, instead of a single concept of "current" node. This allows the parser to recurse into nested nodes. svn path=/trunk/; revision=1081 --- girparser.c | 150 +++++++++++++++++++++++++++++----------------------- 1 file changed, 83 insertions(+), 67 deletions(-) diff --git a/girparser.c b/girparser.c index 381c334fb..46c16e5b4 100644 --- a/girparser.c +++ b/girparser.c @@ -85,13 +85,14 @@ struct _ParseContext const char *namespace; GIrModule *current_module; - GIrNode *current_node; + GSList *node_stack; GIrNode *current_typed; gboolean is_varargs; GList *type_stack; GList *type_parameters; int type_depth; }; +#define CURRENT_NODE(ctx) ((GIrNode *)((ctx)->node_stack->data)) static void start_element_handler (GMarkupParseContext *context, const gchar *element_name, @@ -310,6 +311,27 @@ state_switch (ParseContext *ctx, ParseState newstate) ctx->state = newstate; } +static GIrNode * +pop_node (ParseContext *ctx) +{ + g_assert (ctx->node_stack != 0); + + GSList *top = ctx->node_stack; + GIrNode *node = top->data; + + g_debug ("popping node %d %s", node->type, node->name); + ctx->node_stack = top->next; + g_slist_free_1 (top); + return node; +} + +static void +push_node (ParseContext *ctx, GIrNode *node) +{ + g_debug ("pushing node %d %s", node->type, node->name); + ctx->node_stack = g_slist_prepend (ctx->node_stack, node); +} + static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib, gboolean in_gobject); @@ -643,7 +665,7 @@ start_glib_boxed (GMarkupParseContext *context, else boxed->deprecated = FALSE; - ctx->current_node = (GIrNode *)boxed; + push_node (ctx, (GIrNode *)boxed); ctx->current_module->entries = g_list_append (ctx->current_module->entries, boxed); @@ -744,20 +766,20 @@ start_function (GMarkupParseContext *context, else function->throws = FALSE; - if (ctx->current_node == NULL) + if (ctx->node_stack == NULL) { ctx->current_module->entries = g_list_append (ctx->current_module->entries, function); } else - switch (ctx->current_node->type) + switch (CURRENT_NODE (ctx)->type) { case G_IR_NODE_INTERFACE: case G_IR_NODE_OBJECT: { GIrNodeInterface *iface; - iface = (GIrNodeInterface *)ctx->current_node; + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); iface->members = g_list_append (iface->members, function); } break; @@ -765,7 +787,7 @@ start_function (GMarkupParseContext *context, { GIrNodeBoxed *boxed; - boxed = (GIrNodeBoxed *)ctx->current_node; + boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx); boxed->members = g_list_append (boxed->members, function); } break; @@ -773,14 +795,14 @@ start_function (GMarkupParseContext *context, { GIrNodeStruct *struct_; - struct_ = (GIrNodeStruct *)ctx->current_node; + struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx); struct_->members = g_list_append (struct_->members, function); } break; case G_IR_NODE_UNION: { GIrNodeUnion *union_; - union_ = (GIrNodeUnion *)ctx->current_node; + union_ = (GIrNodeUnion *)CURRENT_NODE (ctx); union_->members = g_list_append (union_->members, function); } break; @@ -788,7 +810,7 @@ start_function (GMarkupParseContext *context, g_assert_not_reached (); } - ctx->current_node = (GIrNode *)function; + push_node(ctx, (GIrNode *)function); state_switch (ctx, STATE_FUNCTION); return TRUE; @@ -921,14 +943,14 @@ start_parameter (GMarkupParseContext *context, ((GIrNode *)param)->name = g_strdup (name); - switch (ctx->current_node->type) + switch (CURRENT_NODE (ctx)->type) { case G_IR_NODE_FUNCTION: case G_IR_NODE_CALLBACK: { GIrNodeFunction *func; - func = (GIrNodeFunction *)ctx->current_node; + func = (GIrNodeFunction *)CURRENT_NODE (ctx); func->parameters = g_list_append (func->parameters, param); } break; @@ -936,7 +958,7 @@ start_parameter (GMarkupParseContext *context, { GIrNodeSignal *signal; - signal = (GIrNodeSignal *)ctx->current_node; + signal = (GIrNodeSignal *)CURRENT_NODE (ctx); signal->parameters = g_list_append (signal->parameters, param); } break; @@ -944,7 +966,7 @@ start_parameter (GMarkupParseContext *context, { GIrNodeVFunc *vfunc; - vfunc = (GIrNodeVFunc *)ctx->current_node; + vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx); vfunc->parameters = g_list_append (vfunc->parameters, param); } break; @@ -1011,13 +1033,13 @@ start_field (GMarkupParseContext *context, else field->bits = 0; - switch (ctx->current_node->type) + switch (CURRENT_NODE (ctx)->type) { case G_IR_NODE_OBJECT: { GIrNodeInterface *iface; - iface = (GIrNodeInterface *)ctx->current_node; + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); iface->members = g_list_append (iface->members, field); state_switch (ctx, STATE_CLASS_FIELD); } @@ -1026,7 +1048,7 @@ start_field (GMarkupParseContext *context, { GIrNodeInterface *iface; - iface = (GIrNodeInterface *)ctx->current_node; + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); iface->members = g_list_append (iface->members, field); state_switch (ctx, STATE_INTERFACE_FIELD); } @@ -1035,7 +1057,7 @@ start_field (GMarkupParseContext *context, { GIrNodeBoxed *boxed; - boxed = (GIrNodeBoxed *)ctx->current_node; + boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx); boxed->members = g_list_append (boxed->members, field); state_switch (ctx, STATE_BOXED_FIELD); } @@ -1044,7 +1066,7 @@ start_field (GMarkupParseContext *context, { GIrNodeStruct *struct_; - struct_ = (GIrNodeStruct *)ctx->current_node; + struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx); struct_->members = g_list_append (struct_->members, field); state_switch (ctx, STATE_STRUCT_FIELD); } @@ -1053,7 +1075,7 @@ start_field (GMarkupParseContext *context, { GIrNodeUnion *union_; - union_ = (GIrNodeUnion *)ctx->current_node; + union_ = (GIrNodeUnion *)CURRENT_NODE (ctx); union_->members = g_list_append (union_->members, field); if (branch) { @@ -1160,7 +1182,7 @@ start_enum (GMarkupParseContext *context, else enum_->deprecated = FALSE; - ctx->current_node = (GIrNode *) enum_; + push_node (ctx, (GIrNode *) enum_); ctx->current_module->entries = g_list_append (ctx->current_module->entries, enum_); @@ -1226,7 +1248,7 @@ start_property (GMarkupParseContext *context, else property->construct_only = FALSE; - iface = (GIrNodeInterface *)ctx->current_node; + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); iface->members = g_list_append (iface->members, property); if (ctx->state == STATE_CLASS) @@ -1302,7 +1324,7 @@ start_member (GMarkupParseContext *context, else value_->deprecated = FALSE; - enum_ = (GIrNodeEnum *)ctx->current_node; + enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx); enum_->values = g_list_append (enum_->values, value_); } @@ -1354,7 +1376,7 @@ start_constant (GMarkupParseContext *context, if (ctx->state == STATE_NAMESPACE) { - ctx->current_node = (GIrNode *) constant; + push_node (ctx, (GIrNode *) constant); ctx->current_module->entries = g_list_append (ctx->current_module->entries, constant); } @@ -1362,7 +1384,7 @@ start_constant (GMarkupParseContext *context, { GIrNodeInterface *iface; - iface = (GIrNodeInterface *)ctx->current_node; + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); iface->members = g_list_append (iface->members, constant); } @@ -1430,7 +1452,7 @@ start_errordomain (GMarkupParseContext *context, else domain->deprecated = FALSE; - ctx->current_node = (GIrNode *) domain; + push_node (ctx, (GIrNode *) domain); ctx->current_module->entries = g_list_append (ctx->current_module->entries, domain); @@ -1482,7 +1504,7 @@ start_interface (GMarkupParseContext *context, else iface->deprecated = FALSE; - ctx->current_node = (GIrNode *) iface; + push_node (ctx, (GIrNode *) iface); ctx->current_module->entries = g_list_append (ctx->current_module->entries, iface); @@ -1542,7 +1564,7 @@ start_class (GMarkupParseContext *context, iface->abstract = abstract && strcmp (abstract, "1") == 0; - ctx->current_node = (GIrNode *) iface; + push_node (ctx, (GIrNode *) iface); ctx->current_module->entries = g_list_append (ctx->current_module->entries, iface); @@ -1598,18 +1620,18 @@ start_type (GMarkupParseContext *context, ctx->type_depth = 1; if (is_varargs) { - switch (ctx->current_node->type) + switch (CURRENT_NODE (ctx)->type) { case G_IR_NODE_FUNCTION: case G_IR_NODE_CALLBACK: { - GIrNodeFunction *func = (GIrNodeFunction *)ctx->current_node; + GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx); func->is_varargs = TRUE; } break; case G_IR_NODE_VFUNC: { - GIrNodeVFunc *vfunc = (GIrNodeVFunc *)ctx->current_node; + GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx); vfunc->is_varargs = TRUE; } break; @@ -1770,7 +1792,7 @@ end_type_top (ParseContext *ctx) } break; default: - g_printerr("current node is %d\n", ctx->current_node->type); + g_printerr("current node is %d\n", CURRENT_NODE (ctx)->type); g_assert_not_reached (); } g_list_free (ctx->type_parameters); @@ -1859,24 +1881,24 @@ start_return_value (GMarkupParseContext *context, transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); parse_param_transfer (param, transfer); - switch (ctx->current_node->type) + switch (CURRENT_NODE (ctx)->type) { case G_IR_NODE_FUNCTION: case G_IR_NODE_CALLBACK: { - GIrNodeFunction *func = (GIrNodeFunction *)ctx->current_node; + GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx); func->result = param; } break; case G_IR_NODE_SIGNAL: { - GIrNodeSignal *signal = (GIrNodeSignal *)ctx->current_node; + GIrNodeSignal *signal = (GIrNodeSignal *)CURRENT_NODE (ctx); signal->result = param; } break; case G_IR_NODE_VFUNC: { - GIrNodeVFunc *vfunc = (GIrNodeVFunc *)ctx->current_node; + GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx); vfunc->result = param; } break; @@ -1914,7 +1936,7 @@ start_implements (GMarkupParseContext *context, return FALSE; } - iface = (GIrNodeInterface *)ctx->current_node; + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); iface->interfaces = g_list_append (iface->interfaces, g_strdup (name)); return TRUE; @@ -1990,10 +2012,10 @@ start_glib_signal (GMarkupParseContext *context, else signal->has_class_closure = FALSE; - iface = (GIrNodeInterface *)ctx->current_node; + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); iface->members = g_list_append (iface->members, signal); - ctx->current_node = (GIrNode *)signal; + push_node (ctx, (GIrNode *)signal); state_switch (ctx, STATE_FUNCTION); } @@ -2068,10 +2090,10 @@ start_vfunc (GMarkupParseContext *context, else vfunc->offset = 0; - iface = (GIrNodeInterface *)ctx->current_node; + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); iface->members = g_list_append (iface->members, vfunc); - ctx->current_node = (GIrNode *)vfunc; + push_node (ctx, (GIrNode *)vfunc); state_switch (ctx, STATE_FUNCTION); } @@ -2135,9 +2157,9 @@ start_struct (GMarkupParseContext *context, struct_->gtype_name = g_strdup (gtype_name); struct_->gtype_init = g_strdup (gtype_init); - ctx->current_node = (GIrNode *)struct_; ctx->current_module->entries = g_list_append (ctx->current_module->entries, struct_); + push_node (ctx, (GIrNode *)struct_); state_switch (ctx, STATE_STRUCT); return TRUE; @@ -2183,9 +2205,9 @@ start_union (GMarkupParseContext *context, else union_->deprecated = FALSE; - ctx->current_node = (GIrNode *)union_; ctx->current_module->entries = g_list_append (ctx->current_module->entries, union_); + push_node (ctx, (GIrNode *)union_); state_switch (ctx, STATE_UNION); } @@ -2215,9 +2237,9 @@ start_discriminator (GMarkupParseContext *context, else if (offset == NULL) MISSING_ATTRIBUTE (context, error, element_name, "offset"); { - ((GIrNodeUnion *)ctx->current_node)->discriminator_type + ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type = parse_type (ctx, type); - ((GIrNodeUnion *)ctx->current_node)->discriminator_offset + ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset = atoi (offset); } @@ -2540,7 +2562,7 @@ start_element_handler (GMarkupParseContext *context, { GIrNodeInterface *iface; - iface = (GIrNodeInterface *)ctx->current_node; + iface = (GIrNodeInterface *)CURRENT_NODE(ctx); iface->prerequisites = g_list_append (iface->prerequisites, g_strdup (name)); } goto out; @@ -2742,28 +2764,22 @@ end_element_handler (GMarkupParseContext *context, case STATE_FUNCTION: { - gboolean current_is_toplevel; - GList *last = g_list_last (ctx->current_module->entries); - - current_is_toplevel = ctx->current_node == last->data; - - if (current_is_toplevel) + pop_node (ctx); + if (ctx->node_stack == NULL) { - ctx->current_node = NULL; state_switch (ctx, STATE_NAMESPACE); } else - { - ctx->current_node = g_list_last (ctx->current_module->entries)->data; - if (ctx->current_node->type == G_IR_NODE_INTERFACE) + { + if (CURRENT_NODE (ctx)->type == G_IR_NODE_INTERFACE) state_switch (ctx, STATE_INTERFACE); - else if (ctx->current_node->type == G_IR_NODE_OBJECT) + else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT) state_switch (ctx, STATE_CLASS); - else if (ctx->current_node->type == G_IR_NODE_BOXED) + else if (CURRENT_NODE (ctx)->type == G_IR_NODE_BOXED) state_switch (ctx, STATE_BOXED); - else if (ctx->current_node->type == G_IR_NODE_STRUCT) + else if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT) state_switch (ctx, STATE_STRUCT); - else if (ctx->current_node->type == G_IR_NODE_UNION) + else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION) state_switch (ctx, STATE_UNION); else { @@ -2801,7 +2817,7 @@ end_element_handler (GMarkupParseContext *context, case STATE_CLASS: if (require_end_element (context, ctx, "class", element_name, error)) { - ctx->current_node = NULL; + pop_node (ctx); state_switch (ctx, STATE_NAMESPACE); } break; @@ -2809,7 +2825,7 @@ end_element_handler (GMarkupParseContext *context, case STATE_ERRORDOMAIN: if (require_end_element (context, ctx, "errordomain", element_name, error)) { - ctx->current_node = NULL; + pop_node (ctx); state_switch (ctx, STATE_NAMESPACE); } break; @@ -2835,7 +2851,7 @@ end_element_handler (GMarkupParseContext *context, case STATE_INTERFACE: if (require_end_element (context, ctx, "interface", element_name, error)) { - ctx->current_node = NULL; + pop_node (ctx); state_switch (ctx, STATE_NAMESPACE); } break; @@ -2847,7 +2863,7 @@ end_element_handler (GMarkupParseContext *context, element_name, error, "enumeration", "bitfield", NULL)) { - ctx->current_node = NULL; + pop_node (ctx); state_switch (ctx, STATE_NAMESPACE); } break; @@ -2855,7 +2871,7 @@ end_element_handler (GMarkupParseContext *context, case STATE_BOXED: if (require_end_element (context, ctx, "glib:boxed", element_name, error)) { - ctx->current_node = NULL; + pop_node (ctx); state_switch (ctx, STATE_NAMESPACE); } break; @@ -2881,7 +2897,7 @@ end_element_handler (GMarkupParseContext *context, case STATE_STRUCT: if (require_end_element (context, ctx, "record", element_name, error)) { - ctx->current_node = NULL; + pop_node (ctx); state_switch (ctx, STATE_NAMESPACE); } break; @@ -2898,7 +2914,7 @@ end_element_handler (GMarkupParseContext *context, case STATE_UNION: if (require_end_element (context, ctx, "union", element_name, error)) { - ctx->current_node = NULL; + pop_node (ctx); state_switch (ctx, STATE_NAMESPACE); } break; @@ -2919,7 +2935,7 @@ end_element_handler (GMarkupParseContext *context, break; if (require_end_element (context, ctx, "constant", element_name, error)) { - ctx->current_node = NULL; + pop_node (ctx); switch (ctx->state) { case STATE_NAMESPACE_CONSTANT: From 52d2251c82bae27976de751f2196881edb142a86 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 4 Feb 2009 00:48:24 +0000 Subject: [PATCH 200/692] Bug 555960 - Nested structs and unions (generation portion) Patch from Andreas Rottmann . * tests/scanner/utility.h (UtilityTaggedValue): Make the union member anonymous. (UtilityByte): New union typedef with an unnamed struct in it. * giscanner/transformer.py (Transformer._create_struct): Create unnamed structs for symbols with a None ident. (Transformer._create_union): Likewise. * giscanner/girwriter.py (GIRWriter._write_record): Allow name being None. (GIRWriter._write_union): Likewise. * girepository/girparser.c (start_struct): Allow a NULL name for non-toplevel structs. (start_union): Likewise. * tests/scanner/utility.h (UtilityTaggedValue): New struct typedef, which has a nested union member. * tests/scanner/utility-expected.gir: Adapted. * giscanner/transformer.py (Transformer._create_member): Create struct/union members if appropriate. (Transformer._create_struct, Transformer._create_union): Allow for structs/unions without a C type. * giscanner/glibtransformer.py (GLibTransformer._resolve_field): We don't need to resolve non-typef'd (GLibTransformer._resolve_field): Add cases for non-typedef'd struct/union "fields". * giscanner/girwriter.py (GIRWriter._write_record): Allow for records without a C type. (GIRWriter._write_field): structs and unions may appear in places where fields do. svn path=/trunk/; revision=1082 --- girparser.c | 73 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 16 deletions(-) diff --git a/girparser.c b/girparser.c index 46c16e5b4..3e1f9dfe5 100644 --- a/girparser.c +++ b/girparser.c @@ -2112,7 +2112,10 @@ start_struct (GMarkupParseContext *context, GError **error) { if (strcmp (element_name, "record") == 0 && - ctx->state == STATE_NAMESPACE) + (ctx->state == STATE_NAMESPACE || + ctx->state == STATE_UNION || + ctx->state == STATE_STRUCT || + ctx->state == STATE_CLASS)) { const gchar *name; const gchar *deprecated; @@ -2127,7 +2130,7 @@ start_struct (GMarkupParseContext *context, gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values); gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values); - if (name == NULL) + if (name == NULL && ctx->node_stack == NULL) { MISSING_ATTRIBUTE (context, error, element_name, "name"); return FALSE; @@ -2145,7 +2148,7 @@ start_struct (GMarkupParseContext *context, struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT); - ((GIrNode *)struct_)->name = g_strdup (name); + ((GIrNode *)struct_)->name = g_strdup (name ? name : ""); if (deprecated) struct_->deprecated = TRUE; else @@ -2156,9 +2159,10 @@ start_struct (GMarkupParseContext *context, struct_->gtype_name = g_strdup (gtype_name); struct_->gtype_init = g_strdup (gtype_init); - - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, struct_); + + if (ctx->node_stack == NULL) + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, struct_); push_node (ctx, (GIrNode *)struct_); state_switch (ctx, STATE_STRUCT); @@ -2176,8 +2180,11 @@ start_union (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "union") == 0 && - ctx->state == STATE_NAMESPACE) + if (strcmp (element_name, "union") == 0 && + (ctx->state == STATE_NAMESPACE || + ctx->state == STATE_UNION || + ctx->state == STATE_STRUCT || + ctx->state == STATE_CLASS)) { const gchar *name; const gchar *deprecated; @@ -2189,7 +2196,7 @@ start_union (GMarkupParseContext *context, typename = find_attribute ("glib:type-name", attribute_names, attribute_values); typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); - if (name == NULL) + if (name == NULL && ctx->node_stack == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); else { @@ -2197,7 +2204,7 @@ start_union (GMarkupParseContext *context, union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION); - ((GIrNode *)union_)->name = g_strdup (name); + ((GIrNode *)union_)->name = g_strdup (name ? name : ""); union_->gtype_name = g_strdup (typename); union_->gtype_init = g_strdup (typeinit); if (deprecated) @@ -2205,8 +2212,9 @@ start_union (GMarkupParseContext *context, else union_->deprecated = FALSE; - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, union_); + if (ctx->node_stack == NULL) + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, union_); push_node (ctx, (GIrNode *)union_); state_switch (ctx, STATE_UNION); @@ -2684,6 +2692,41 @@ require_one_of_end_elements (GMarkupParseContext *context, return FALSE; } +static gboolean +state_switch_end_struct_or_union (GMarkupParseContext *context, + ParseContext *ctx, + const gchar *element_name, + GError **error) +{ + pop_node (ctx); + if (ctx->node_stack == NULL) + { + state_switch (ctx, STATE_NAMESPACE); + } + else + { + if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT) + state_switch (ctx, STATE_STRUCT); + else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION) + state_switch (ctx, STATE_UNION); + else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT) + state_switch (ctx, STATE_CLASS); + else + { + int line_number, char_number; + g_markup_parse_context_get_position (context, &line_number, &char_number); + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Unexpected end tag '%s' on line %d char %d", + element_name, + line_number, char_number); + return FALSE; + } + } + return TRUE; +} + static gboolean require_end_element (GMarkupParseContext *context, ParseContext *ctx, @@ -2897,8 +2940,7 @@ end_element_handler (GMarkupParseContext *context, case STATE_STRUCT: if (require_end_element (context, ctx, "record", element_name, error)) { - pop_node (ctx); - state_switch (ctx, STATE_NAMESPACE); + state_switch_end_struct_or_union (context, ctx, element_name, error); } break; @@ -2914,8 +2956,7 @@ end_element_handler (GMarkupParseContext *context, case STATE_UNION: if (require_end_element (context, ctx, "union", element_name, error)) { - pop_node (ctx); - state_switch (ctx, STATE_NAMESPACE); + state_switch_end_struct_or_union (context, ctx, element_name, error); } break; case STATE_IMPLEMENTS: From 314ad462dc48e255905646f64d0a200bbc0a0c5a Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 5 Feb 2009 00:40:14 +0000 Subject: [PATCH 201/692] Add utility functions for invocing closures given a GICallableInfo using 2009-02-04 Johan Dahlin * girepository/Makefile.am: * girepository/girffi.c (g_callable_info_get_ffi_arg_types), (g_callable_info_get_ffi_return_type), (g_callable_info_prepare_closure), (g_callable_info_free_closure): * girepository/girffi.h: Add utility functions for invocing closures given a GICallableInfo using libffi. svn path=/trunk/; revision=1084 --- Makefile.am | 2 +- girffi.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++ girffi.h | 15 +++++- 3 files changed, 154 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index dc8a6cae6..1a449b2a4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,7 +3,7 @@ include $(top_srcdir)/gcov.mak GCOVSOURCES = $(libgirepository_1_0_la_SOURCES) girepodir = $(includedir)/gobject-introspection-1.0/ -girepo_HEADERS = girepository.h +girepo_HEADERS = girepository.h girffi.h lib_LTLIBRARIES = libgirepository-1.0.la noinst_LTLIBRARIES = libgirepository-parser.la diff --git a/girffi.c b/girffi.c index d6eefb273..ffde85388 100644 --- a/girffi.c +++ b/girffi.c @@ -19,7 +19,12 @@ * Boston, MA 02111-1307, USA. */ #include +#include +#include +#include +#include #include "girffi.h" +#include "girepository.h" ffi_type * g_ir_ffi_get_ffi_type (GITypeTag tag) @@ -98,3 +103,137 @@ g_ir_ffi_get_ffi_type (GITypeTag tag) return NULL; } + +/** + * g_callable_info_get_ffi_arg_types: + * @callable_info: a callable info from a typelib + * + * Return value: an array of ffi_type*. The array itself + * should be freed using g_free() after use. + */ +ffi_type ** +g_callable_info_get_ffi_arg_types (GICallableInfo *callable_info) +{ + ffi_type **arg_types; + gint n_args, i; + + g_return_val_if_fail (callable_info != NULL, NULL); + + n_args = g_callable_info_get_n_args (callable_info); + + arg_types = (ffi_type **) g_new0 (ffi_type *, n_args + 1); + + for (i = 0; i < n_args; ++i) + { + GIArgInfo *arg_info = g_callable_info_get_arg (callable_info, i); + GITypeInfo *arg_type = g_arg_info_get_type (arg_info); + GITypeTag type_tag = g_type_info_get_tag (arg_type); + arg_types[i] = g_ir_ffi_get_ffi_type (type_tag); + g_base_info_unref ((GIBaseInfo *)arg_info); + g_base_info_unref ((GIBaseInfo *)arg_type); + } + arg_types[n_args] = NULL; + + return arg_types; +} + +/** + * g_callable_info_get_ffi_return_type: + * @callable_info: a callable info from a typelib + * + * Fetches the ffi_type for a corresponding return value of + * a #GICallableInfo + * Return value: the ffi_type for the return value + */ +ffi_type * +g_callable_info_get_ffi_return_type (GICallableInfo *callable_info) +{ + GITypeInfo *return_type; + GITypeTag type_tag; + + g_return_val_if_fail (callable_info != NULL, NULL); + + return_type = g_callable_info_get_return_type (callable_info); + type_tag = g_type_info_get_tag (return_type); + return g_ir_ffi_get_ffi_type (type_tag); +} + +/** + * g_callable_info_prepare_closure: + * @callable_info: a callable info from a typelib + * @cif: a ffi_cif structure + * @callback: the ffi callback + * @user_data: data to be passed into the callback + * + * Prepares a callback for ffi invocation. + * + * Note: this function requires the heap to be executable, which + * might not function properly on systems with SELinux enabled. + * + * Return value: the ffi_closure or NULL on error. + * The return value should be freed by calling g_callable_info_prepare_closure(). + */ +ffi_closure * +g_callable_info_prepare_closure (GICallableInfo *callable_info, + ffi_cif *cif, + GIFFIClosureCallback callback, + gpointer user_data) +{ + ffi_closure *closure; + ffi_status status; + + g_return_val_if_fail (callable_info != NULL, FALSE); + g_return_val_if_fail (cif != NULL, FALSE); + g_return_val_if_fail (callback != NULL, FALSE); + + closure = mmap (NULL, sizeof (ffi_closure), + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, sysconf (_SC_PAGE_SIZE)); + if (!closure) + { + g_warning("mmap failed: %s\n", strerror(errno)); + return NULL; + } + + status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, + g_callable_info_get_n_args (callable_info), + g_callable_info_get_ffi_return_type (callable_info), + g_callable_info_get_ffi_arg_types (callable_info)); + if (status != FFI_OK) + { + g_warning("ffi_prep_cif failed: %d\n", status); + munmap(closure, sizeof (closure)); + return NULL; + } + + status = ffi_prep_closure (closure, cif, callback, user_data); + if (status != FFI_OK) + { + g_warning ("ffi_prep_closure failed: %d\n", status); + munmap(closure, sizeof (closure)); + return NULL; + } + + if (mprotect(closure, sizeof (closure), PROT_READ | PROT_EXEC) == -1) + { + g_warning ("ffi_prep_closure failed: %s\n", strerror(errno)); + munmap(closure, sizeof (closure)); + return NULL; + } + + return closure; +} + +/** + * g_callable_info_prepare_closure: + * @callable_info: a callable info from a typelib + * @closure: ffi closure + * + * Frees a ffi_closure returned from g_callable_info_prepare_closure() + */ +void +g_callable_info_free_closure (GICallableInfo *callable_info, + ffi_closure *closure) +{ + munmap(closure, sizeof (closure)); +} diff --git a/girffi.h b/girffi.h index 842a2334c..a7d28766a 100644 --- a/girffi.h +++ b/girffi.h @@ -26,7 +26,20 @@ G_BEGIN_DECLS -ffi_type *g_ir_ffi_get_ffi_type (GITypeTag tag); +typedef void (*GIFFIClosureCallback) (ffi_cif *, + void *, + void **, + void *); + +ffi_type * g_ir_ffi_get_ffi_type (GITypeTag tag); +ffi_type ** g_callable_info_get_ffi_arg_types (GICallableInfo *callable_info); +ffi_type * g_callable_info_get_ffi_return_type (GICallableInfo *callable_info); +ffi_closure * g_callable_info_prepare_closure (GICallableInfo *callable_info, + ffi_cif *cif, + GIFFIClosureCallback callback, + gpointer user_data); +void g_callable_info_free_closure (GICallableInfo *callable_info, + ffi_closure *closure); G_END_DECLS From 1b22fa426f4c5be304706a7f492e7b096999307d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 5 Feb 2009 18:00:00 +0000 Subject: [PATCH 202/692] girnode.c: Fix copy & paste error This line is almost certainly a copy & paste error. It appears to be harmless, but it's better to not have it. svn path=/trunk/; revision=1085 --- girnode.c | 1 - 1 file changed, 1 deletion(-) diff --git a/girnode.c b/girnode.c index c4045ef7e..abec606a3 100644 --- a/girnode.c +++ b/girnode.c @@ -654,7 +654,6 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4); if (iface->gtype_init) size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4); - size += ALIGN_VALUE ( + 1, 4); size += 2 * (n + (n % 2)); for (l = iface->members; l; l = l->next) From ff6b28c17b58ed8a308931b6eb54a1e819a21a3e Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 6 Feb 2009 18:37:13 +0000 Subject: [PATCH 203/692] Bug 551738 - Associate classes with their structs Inside glibtransformer, we now look at structures ending in "Class" and see if they have an associated GlibObject (i.e. a structure of the same name without the "Class" suffix). If found, pair them up. The .gir file for gains an attribute denoting its associated class struct. Any many now have a glib:is-class-struct-for annotation which tells which (if any) for which it defines the layout. In the .typelib, we record the association between the class and its structure. Generic structures however just have a boolean saying whether they're a class struct. (Going from a generic class struct to its class should not be necessary). Finally, we expose GIRepository APIs to access both bits of information from the .typelib. svn path=/trunk/; revision=1088 --- ginfo.c | 37 +++++++++++++++++++++++++++++++++++++ girepository.h | 2 ++ girmodule.c | 2 +- girnode.c | 16 ++++++++++++---- girnode.h | 2 ++ girparser.c | 7 +++++++ gtypelib.c | 38 ++++++++++++++++++++++++++++++++++---- gtypelib.h | 7 +++++-- 8 files changed, 100 insertions(+), 11 deletions(-) diff --git a/ginfo.c b/ginfo.c index 289717d53..a51c6cb3c 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1178,6 +1178,24 @@ g_struct_info_get_alignment (GIStructInfo *info) return blob->alignment; } +/** + * g_struct_info_is_class_struct: + * @info: GIStructInfo + * + * Return true if this structure represents the "class structure" for some + * GObject. This function is mainly useful to hide this kind of structure + * from public APIs. + * + */ +gboolean +g_struct_info_is_class_struct (GIStructInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset]; + + return blob->is_class_struct; +} + gint g_enum_info_get_n_values (GIEnumInfo *info) { @@ -1469,6 +1487,25 @@ g_object_info_get_constant (GIObjectInfo *info, base->typelib, offset); } +/** + * g_object_info_get_class_struct: + * @info: A #GIObjectInfo to query + * + * Every GObject has two structures; an instance structure and a class + * structure. This function returns the metadata for the class structure. + */ +GIStructInfo * +g_object_info_get_class_struct (GIObjectInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + + if (blob->class_struct) + return (GIStructInfo *) g_info_from_entry (base->repository, + base->typelib, blob->class_struct); + else + return NULL; +} /* GIInterfaceInfo functions */ gint diff --git a/girepository.h b/girepository.h index 340c7fa48..ac1b279b0 100644 --- a/girepository.h +++ b/girepository.h @@ -412,6 +412,7 @@ GIFunctionInfo * g_struct_info_find_method (GIStructInfo *info, const gchar *name); gsize g_struct_info_get_size (GIStructInfo *info); gsize g_struct_info_get_alignment (GIStructInfo *info); +gboolean g_struct_info_is_class_struct (GIStructInfo *info); /* GIRegisteredTypeInfo */ @@ -455,6 +456,7 @@ GIVFuncInfo * g_object_info_get_vfunc (GIObjectInfo *in gint g_object_info_get_n_constants (GIObjectInfo *info); GIConstantInfo * g_object_info_get_constant (GIObjectInfo *info, gint n); +GIStructInfo * g_object_info_get_class_struct (GIObjectInfo *info); /* GIInterfaceInfo */ diff --git a/girmodule.c b/girmodule.c index 85103bff1..63d42cced 100644 --- a/girmodule.c +++ b/girmodule.c @@ -223,7 +223,7 @@ g_ir_module_build_typelib (GIrModule *module, header->signature_blob_size = 8; header->enum_blob_size = 20; header->struct_blob_size = 24; - header->object_blob_size = 32; + header->object_blob_size = sizeof(ObjectBlob); header->interface_blob_size = 28; header->union_blob_size = 32; diff --git a/girnode.c b/girnode.c index abec606a3..cc8aa5089 100644 --- a/girnode.c +++ b/girnode.c @@ -285,7 +285,8 @@ g_ir_node_free (GIrNode *node) g_free (node->name); g_free (iface->gtype_name); g_free (iface->gtype_init); - + + g_free (iface->class_struct); g_free (iface->parent); for (l = iface->interfaces; l; l = l->next) @@ -431,7 +432,7 @@ g_ir_node_get_size (GIrNode *node) GIrNodeInterface *iface = (GIrNodeInterface *)node; n = g_list_length (iface->interfaces); - size = 32 + 2 * (n + (n % 2)); + size = sizeof(ObjectBlob) + 2 * (n + (n % 2)); for (l = iface->members; l; l = l->next) size += g_ir_node_get_size ((GIrNode *)l->data); @@ -647,9 +648,11 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNodeInterface *iface = (GIrNodeInterface *)node; n = g_list_length (iface->interfaces); - size = 32; + size = sizeof(ObjectBlob); if (iface->parent) size += ALIGN_VALUE (strlen (iface->parent) + 1, 4); + if (iface->class_struct) + size += ALIGN_VALUE (strlen (iface->class_struct) + 1, 4); size += ALIGN_VALUE (strlen (node->name) + 1, 4); size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4); if (iface->gtype_init) @@ -1792,6 +1795,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->blob_type = BLOB_TYPE_STRUCT; blob->deprecated = struct_->deprecated; + blob->is_class_struct = struct_->is_gclass_struct; blob->reserved = 0; blob->name = write_string (node->name, strings, data, offset2); blob->alignment = struct_->alignment; @@ -2001,6 +2005,10 @@ g_ir_node_build_typelib (GIrNode *node, blob->parent = find_entry (module, modules, object->parent); else blob->parent = 0; + if (object->class_struct) + blob->class_struct = find_entry (module, modules, object->class_struct); + else + blob->class_struct = 0; blob->n_interfaces = 0; blob->n_fields = 0; @@ -2010,7 +2018,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->n_vfuncs = 0; blob->n_constants = 0; - *offset += 32; + *offset += sizeof(ObjectBlob); for (l = object->interfaces; l; l = l->next) { blob->n_interfaces++; diff --git a/girnode.h b/girnode.h index a1b8f0dc0..fad679911 100644 --- a/girnode.h +++ b/girnode.h @@ -228,6 +228,7 @@ struct _GIrNodeInterface gchar *gtype_init; gchar *parent; + gchar *class_struct; /* Only applies to classes */ GList *interfaces; GList *prerequisites; @@ -292,6 +293,7 @@ struct _GIrNodeStruct gboolean deprecated; gboolean disguised; + gboolean is_gclass_struct; gchar *gtype_name; gchar *gtype_init; diff --git a/girparser.c b/girparser.c index 3e1f9dfe5..eb3c11d3e 100644 --- a/girparser.c +++ b/girparser.c @@ -1530,6 +1530,7 @@ start_class (GMarkupParseContext *context, { const gchar *name; const gchar *parent; + const gchar *class_struct; const gchar *typename; const gchar *typeinit; const gchar *deprecated; @@ -1537,6 +1538,7 @@ start_class (GMarkupParseContext *context, name = find_attribute ("name", attribute_names, attribute_values); parent = find_attribute ("parent", attribute_names, attribute_values); + class_struct = find_attribute ("glib:class-struct", attribute_names, attribute_values); typename = find_attribute ("glib:type-name", attribute_names, attribute_values); typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); @@ -1557,6 +1559,7 @@ start_class (GMarkupParseContext *context, iface->gtype_name = g_strdup (typename); iface->gtype_init = g_strdup (typeinit); iface->parent = g_strdup (parent); + iface->class_struct = g_strdup (class_struct); if (deprecated) iface->deprecated = TRUE; else @@ -2122,6 +2125,7 @@ start_struct (GMarkupParseContext *context, const gchar *disguised; const gchar *gtype_name; const gchar *gtype_init; + const gchar *gclass_struct; GIrNodeStruct *struct_; name = find_attribute ("name", attribute_names, attribute_values); @@ -2129,6 +2133,7 @@ start_struct (GMarkupParseContext *context, disguised = find_attribute ("disguised", attribute_names, attribute_values); gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values); gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values); + gclass_struct = find_attribute ("glib:is-class-struct-for", attribute_names, attribute_values); if (name == NULL && ctx->node_stack == NULL) { @@ -2156,6 +2161,8 @@ start_struct (GMarkupParseContext *context, if (disguised && strcmp (disguised, "1") == 0) struct_->disguised = TRUE; + + struct_->is_gclass_struct = gclass_struct != NULL; struct_->gtype_name = g_strdup (gtype_name); struct_->gtype_init = g_strdup (gtype_init); diff --git a/gtypelib.c b/gtypelib.c index d7b09f214..e3b1214ed 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -181,7 +181,7 @@ g_typelib_check_sanity (void) CHECK_SIZE (PropertyBlob, 12); CHECK_SIZE (SignalBlob, 12); CHECK_SIZE (VFuncBlob, 16); - CHECK_SIZE (ObjectBlob, 32); + CHECK_SIZE (ObjectBlob, 36); CHECK_SIZE (InterfaceBlob, 28); CHECK_SIZE (ConstantBlob, 20); CHECK_SIZE (AnnotationBlob, 12); @@ -313,6 +313,15 @@ validate_header (ValidateContext *ctx, "Typelib size mismatch"); return FALSE; } + + /* This is a sanity check for a specific typelib; it + * prevents us from loading an incompatible typelib. It's OK to change + * these hardcoded constants to sizeof() as you see fit. + * + * We want to keep the hardcoded checks in g_typelib_check_sanity to + * protect against inadvertent or buggy changes to the typelib format + * itself. + */ if (header->entry_blob_size != 12 || header->function_blob_size != 20 || @@ -329,7 +338,7 @@ validate_header (ValidateContext *ctx, header->signature_blob_size != 8 || header->enum_blob_size != 20 || header->struct_blob_size != 24 || - header->object_blob_size != 32 || + header->object_blob_size != sizeof(ObjectBlob) || header->interface_blob_size != 28 || header->union_blob_size != 32) { @@ -1435,7 +1444,9 @@ validate_object_blob (ValidateContext *ctx, { DirEntry *entry; - entry = g_typelib_get_dir_entry (typelib, blob->parent); + entry = get_dir_entry_checked (typelib, blob->parent, error); + if (!entry) + return FALSE; if (entry->blob_type != BLOB_TYPE_OBJECT && (entry->local || entry->blob_type != 0)) { @@ -1447,6 +1458,23 @@ validate_object_blob (ValidateContext *ctx, } } + if (blob->class_struct != 0) + { + DirEntry *entry; + + entry = get_dir_entry_checked (typelib, blob->class_struct, error); + if (!entry) + return FALSE; + if (entry->blob_type != BLOB_TYPE_STRUCT && entry->local) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Class struct invalid type or not local"); + return FALSE; + } + } + if (typelib->len < offset + sizeof (ObjectBlob) + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + blob->n_fields * sizeof (FieldBlob) + @@ -1481,7 +1509,9 @@ validate_object_blob (ValidateContext *ctx, return FALSE; } - entry = g_typelib_get_dir_entry (typelib, iface); + entry = get_dir_entry_checked (typelib, iface, error); + if (!entry) + return FALSE; if (entry->blob_type != BLOB_TYPE_INTERFACE && (entry->local || entry->blob_type != 0)) diff --git a/gtypelib.h b/gtypelib.h index a68d00800..ee7442f37 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -306,8 +306,9 @@ typedef struct guint16 deprecated : 1; guint16 unregistered : 1; - guint16 alignment : 6; - guint16 reserved : 8; + guint16 is_class_struct : 1; + guint16 alignment : 6; + guint16 reserved : 7; guint32 name; @@ -438,6 +439,8 @@ typedef struct guint32 gtype_init; guint16 parent; + guint16 class_struct; + guint16 reserved2; guint16 n_interfaces; guint16 n_fields; From 8c2ef112b772b2838a576bb7e47682c74fb95fac Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 10 Feb 2009 21:01:08 +0000 Subject: [PATCH 204/692] Rename namespace to namespace_ to make the header compilable with a C++ compiler svn path=/trunk/; revision=1094 --- girepository.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/girepository.h b/girepository.h index ac1b279b0..7ec86129b 100644 --- a/girepository.h +++ b/girepository.h @@ -83,32 +83,32 @@ const char * g_irepository_load_typelib (GIRepository *repository, GIRepositoryLoadFlags flags, GError **error); gboolean g_irepository_is_registered (GIRepository *repository, - const gchar *namespace, + const gchar *namespace_, const gchar *version); GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, - const gchar *namespace, + const gchar *namespace_, const gchar *name); GTypelib * g_irepository_require (GIRepository *repository, - const gchar *namespace, + const gchar *namespace_, const gchar *version, GIRepositoryLoadFlags flags, GError **error); gchar ** g_irepository_get_dependencies (GIRepository *repository, - const gchar *namespace); + const gchar *namespace_); gchar ** g_irepository_get_loaded_namespaces (GIRepository *repository); GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository, GType gtype); gint g_irepository_get_n_infos (GIRepository *repository, - const gchar *namespace); + const gchar *namespace_); GIBaseInfo * g_irepository_get_info (GIRepository *repository, - const gchar *namespace, + const gchar *namespace_, gint index); const gchar * g_irepository_get_typelib_path (GIRepository *repository, - const gchar *namespace); + const gchar *namespace_); const gchar * g_irepository_get_shared_library (GIRepository *repository, - const gchar *namespace); + const gchar *namespace_); const gchar * g_irepository_get_version (GIRepository *repository, - const gchar *namespace); + const gchar *namespace_); GOptionGroup * g_irepository_get_option_group (void); From 3490a56ba4f651f30aa0fb9e7c81ad9b4f425c50 Mon Sep 17 00:00:00 2001 From: Rober Carr Date: Tue, 10 Feb 2009 23:34:04 +0000 Subject: [PATCH 205/692] =?UTF-8?q?Bug=20569633=20=E2=80=93=20Typelib=20co?= =?UTF-8?q?mpiler=20fails=20with=20vararg=20callbacks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2009-02-10 Rober Carr Bug 569633 – Typelib compiler fails with vararg callbacks * girepository/girparser.c: Also filter out callback functions which take vararg arguments. svn path=/trunk/; revision=1095 --- girparser.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 89 insertions(+), 11 deletions(-) diff --git a/girparser.c b/girparser.c index eb3c11d3e..b376234de 100644 --- a/girparser.c +++ b/girparser.c @@ -3040,18 +3040,20 @@ cleanup (GMarkupParseContext *context, } static GList * -post_filter_varargs_functions (GList *list) +post_filter_toplevel_varargs_functions (GList *list, + GList **varargs_callbacks_out) { GList *iter; - + GList *varargs_callbacks = *varargs_callbacks_out; + iter = list; while (iter) { GList *link = iter; GIrNode *node = iter->data; - + iter = iter->next; - + if (node->type == G_IR_NODE_FUNCTION) { if (((GIrNodeFunction*)node)->is_varargs) @@ -3059,7 +3061,76 @@ post_filter_varargs_functions (GList *list) list = g_list_delete_link (list, link); } } + if (node->type == G_IR_NODE_CALLBACK) + { + if (((GIrNodeFunction*)node)->is_varargs) + { + varargs_callbacks = g_list_append (varargs_callbacks, + node); + list = g_list_delete_link (list, link); + } + } } + + *varargs_callbacks_out = varargs_callbacks; + + return list; +} + +static GList * +post_filter_varargs_functions (GList *list, GList ** varargs_callbacks_out) +{ + GList *iter; + GList *varargs_callbacks; + + list = post_filter_toplevel_varargs_functions (list, varargs_callbacks_out); + + varargs_callbacks = *varargs_callbacks_out; + + iter = list; + while (iter) + { + GList *link = iter; + GIrNode *node = iter->data; + + iter = iter->next; + + if (node->type == G_IR_NODE_FUNCTION) + { + GList *param; + gboolean function_done = FALSE; + + for (param = ((GIrNodeFunction *)node)->parameters; + param; + param = param->next) + { + GIrNodeParam *node = (GIrNodeParam *)param->data; + + if (function_done) + break; + + if (node->type->is_interface) + { + GList *callback; + for (callback = varargs_callbacks; + callback; + callback = callback->next) + { + if (!strcmp (node->type->interface, + ((GIrNode *)varargs_callbacks->data)->name)) + { + list = g_list_delete_link (list, link); + function_done = TRUE; + break; + } + } + } + } + } + } + + *varargs_callbacks_out = varargs_callbacks; + return list; } @@ -3067,37 +3138,44 @@ static void post_filter (GIrModule *module) { GList *iter; - - module->entries = post_filter_varargs_functions (module->entries); + GList *varargs_callbacks = NULL; + + module->entries = post_filter_varargs_functions (module->entries, + &varargs_callbacks); iter = module->entries; while (iter) { GIrNode *node = iter->data; - + iter = iter->next; if (node->type == G_IR_NODE_OBJECT || node->type == G_IR_NODE_INTERFACE) { GIrNodeInterface *iface = (GIrNodeInterface*)node; - iface->members = post_filter_varargs_functions (iface->members); + iface->members = post_filter_varargs_functions (iface->members, + &varargs_callbacks); } else if (node->type == G_IR_NODE_BOXED) { GIrNodeBoxed *boxed = (GIrNodeBoxed*)node; - boxed->members = post_filter_varargs_functions (boxed->members); + boxed->members = post_filter_varargs_functions (boxed->members, + &varargs_callbacks); } else if (node->type == G_IR_NODE_STRUCT) { GIrNodeStruct *iface = (GIrNodeStruct*)node; - iface->members = post_filter_varargs_functions (iface->members); + iface->members = post_filter_varargs_functions (iface->members, + &varargs_callbacks); } else if (node->type == G_IR_NODE_UNION) { GIrNodeUnion *iface = (GIrNodeUnion*)node; - iface->members = post_filter_varargs_functions (iface->members); + iface->members = post_filter_varargs_functions (iface->members, + &varargs_callbacks); } } + g_list_free (varargs_callbacks); } /** From 97a2e7f5fc79a4cc0ba4c9773f789878deba5569 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 11 Feb 2009 00:08:49 +0000 Subject: [PATCH 206/692] Bug 571248 - Ignore unknown elements in girparser We want the gir to be extensible. svn path=/trunk/; revision=1096 --- girparser.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/girparser.c b/girparser.c index b376234de..97e3a1e09 100644 --- a/girparser.c +++ b/girparser.c @@ -66,7 +66,8 @@ typedef enum STATE_CLASS_CONSTANT, STATE_INTERFACE_CONSTANT, STATE_ALIAS, - STATE_TYPE + STATE_TYPE, + STATE_UNKNOWN } ParseState; typedef struct _ParseContext ParseContext; @@ -75,6 +76,7 @@ struct _ParseContext GIrParser *parser; ParseState state; + int unknown_depth; ParseState prev_state; GList *modules; @@ -2640,15 +2642,15 @@ start_element_handler (GMarkupParseContext *context, break; } - g_markup_parse_context_get_position (context, &line_number, &char_number); - - if (error && *error == NULL) - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_UNKNOWN_ELEMENT, - "Unexpected start tag '%s' on line %d char %d; current state=%d", - element_name, - line_number, char_number, ctx->state); + if (ctx->state != STATE_UNKNOWN) + { + state_switch (ctx, STATE_UNKNOWN); + ctx->unknown_depth = 1; + } + else + { + ctx->unknown_depth += 1; + } out: ; if (*error) @@ -3008,6 +3010,11 @@ end_element_handler (GMarkupParseContext *context, end_type (ctx); break; } + case STATE_UNKNOWN: + ctx->unknown_depth -= 1; + if (ctx->unknown_depth == 0) + state_switch (ctx, ctx->prev_state); + break; default: g_error ("Unhandled state %d in end_element_handler\n", ctx->state); } From 0a74fdfec0f39db2bf8ead7e277d29eeaf6c3f97 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 5 Feb 2009 17:36:35 -0500 Subject: [PATCH 207/692] Bug 567906 - Put pkg-config dependencies in .gir files When generating a .gir file, we now first parse all of our .gir includes to pick up their headers. Then, we merge that with the set of --pkg arguments passed to us, run pkg-config to gather the arguments, and finally save the merged pkg-config list to our new .gir file. This is useful for software which needs to map from .gir to pkg-config in a programmatic way. --- girparser.c | 60 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/girparser.c b/girparser.c index 97e3a1e09..fe2f76275 100644 --- a/girparser.c +++ b/girparser.c @@ -36,34 +36,35 @@ struct _GIrParser typedef enum { - STATE_START, - STATE_END, - STATE_REPOSITORY, - STATE_INCLUDE, - STATE_NAMESPACE, - STATE_ENUM, /* 5 */ - STATE_BITFIELD, - STATE_FUNCTION, - STATE_FUNCTION_RETURN, - STATE_FUNCTION_PARAMETERS, - STATE_FUNCTION_PARAMETER, /* 10 */ - STATE_CLASS, + STATE_START, + STATE_END, + STATE_REPOSITORY, + STATE_INCLUDE, + STATE_PACKAGE, + STATE_NAMESPACE, /* 5 */ + STATE_ENUM, + STATE_BITFIELD, + STATE_FUNCTION, + STATE_FUNCTION_RETURN, + STATE_FUNCTION_PARAMETERS, /* 10 */ + STATE_FUNCTION_PARAMETER, + STATE_CLASS, STATE_CLASS_FIELD, STATE_CLASS_PROPERTY, - STATE_INTERFACE, - STATE_INTERFACE_PROPERTY, /* 15 */ + STATE_INTERFACE, /* 15 */ + STATE_INTERFACE_PROPERTY, STATE_INTERFACE_FIELD, - STATE_IMPLEMENTS, + STATE_IMPLEMENTS, STATE_PREREQUISITE, - STATE_BOXED, - STATE_BOXED_FIELD, /* 20 */ - STATE_STRUCT, + STATE_BOXED, /* 20 */ + STATE_BOXED_FIELD, + STATE_STRUCT, STATE_STRUCT_FIELD, - STATE_ERRORDOMAIN, - STATE_UNION, - STATE_UNION_FIELD, /* 25 */ - STATE_NAMESPACE_CONSTANT, - STATE_CLASS_CONSTANT, + STATE_ERRORDOMAIN, + STATE_UNION, /* 25 */ + STATE_UNION_FIELD, + STATE_NAMESPACE_CONSTANT, + STATE_CLASS_CONSTANT, STATE_INTERFACE_CONSTANT, STATE_ALIAS, STATE_TYPE, @@ -2584,6 +2585,12 @@ start_element_handler (GMarkupParseContext *context, } goto out; } + else if (strcmp (element_name, "package") == 0 && + ctx->state == STATE_REPOSITORY) + { + state_switch (ctx, STATE_PACKAGE); + goto out; + } break; case 'r': @@ -2773,6 +2780,13 @@ end_element_handler (GMarkupParseContext *context, state_switch (ctx, STATE_REPOSITORY); } break; + + case STATE_PACKAGE: + if (require_end_element (context, ctx, "package", element_name, error)) + { + state_switch (ctx, STATE_REPOSITORY); + } + break; case STATE_NAMESPACE: if (require_end_element (context, ctx, "namespace", element_name, error)) From fe8c6d34c41789f938168ff1d38da079a5573945 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 12 Feb 2009 01:32:25 -0200 Subject: [PATCH 208/692] Add gtk-doc support --- ginfo.c | 4 +++ girepository.c | 77 +++++++++++++++++++++++++------------------------- girffi.c | 2 +- giroffsets.c | 2 +- girparser.c | 8 ++++-- gtypelib.c | 1 + 6 files changed, 51 insertions(+), 43 deletions(-) diff --git a/ginfo.c b/ginfo.c index a51c6cb3c..f4ca1310a 100644 --- a/ginfo.c +++ b/ginfo.c @@ -658,6 +658,7 @@ g_callable_info_get_n_args (GICallableInfo *info) /** * g_callable_info_get_arg: * @info: a #GICallableInfo + * @n: the argument index to fetch * * Get information about a particular argument of this callable. * @@ -1186,6 +1187,7 @@ g_struct_info_get_alignment (GIStructInfo *info) * GObject. This function is mainly useful to hide this kind of structure * from public APIs. * + * Returns: TRUE if it's a class struct, otherwise FALSE */ gboolean g_struct_info_is_class_struct (GIStructInfo *info) @@ -1493,6 +1495,8 @@ g_object_info_get_constant (GIObjectInfo *info, * * Every GObject has two structures; an instance structure and a class * structure. This function returns the metadata for the class structure. + * + * Returns: a GIStrucTInfo for the class struct or NULL if none found. */ GIStructInfo * g_object_info_get_class_struct (GIObjectInfo *info) diff --git a/girepository.c b/girepository.c index f35854a7d..40c478648 100644 --- a/girepository.c +++ b/girepository.c @@ -370,12 +370,12 @@ register_internal (GIRepository *repository, } /** - * g_irepository_get_dependencies + * g_irepository_get_dependencies: * @repository: A #GIRepository, may be %NULL for the default - * @namespace: Namespace of interest + * @namespace_: Namespace of interest * * Return an array of all (transitive) dependencies for namespace - * @namespace, including version. The returned strings are of the + * @namespace_, including version. The returned strings are of the * form namespace-version. * * Note: The namespace must have already been loaded using a function @@ -436,10 +436,10 @@ g_irepository_load_typelib (GIRepository *repository, } /** - * g_irepository_is_registered + * g_irepository_is_registered: * @repository: A #GIRepository, may be %NULL for the default - * @namespace: Namespace of interest - * @version: : Required version, may be %NULL for latest + * @namespace_: Namespace of interest + * @version: (allow-none): Required version, may be %NULL for latest * * Check whether a particular namespace (and optionally, a specific * version thereof) is currently loaded. This function is likely to @@ -460,7 +460,7 @@ g_irepository_is_registered (GIRepository *repository, } /** - * g_irepository_get_default + * g_irepository_get_default: * * Returns the singleton process-global default #GIRepository. It is * not currently supported to have multiple repositories in a @@ -482,12 +482,12 @@ g_irepository_get_default (void) } /** - * g_irepository_get_n_infos + * g_irepository_get_n_infos: * @repository: A #GIRepository, may be %NULL for the default - * @namespace: Namespace to inspect + * @namespace_: Namespace to inspect * * This function returns the number of metadata entries in - * given namespace @namespace. The namespace must have + * given namespace @namespace_. The namespace must have * already been loaded before calling this function. * * Returns: number of metadata entries @@ -591,13 +591,13 @@ find_interface (gpointer key, } /** - * g_irepository_get_info + * g_irepository_get_info: * @repository: A #GIRepository, may be %NULL for the default - * @namespace: Namespace to inspect + * @namespace_: Namespace to inspect * @index: Offset into namespace metadata for entry * * This function returns a particular metadata entry in the - * given namespace @namespace. The namespace must have + * given namespace @namespace_. The namespace must have * already been loaded before calling this function. * * Returns: #GIBaseInfo containing metadata @@ -630,9 +630,9 @@ g_irepository_get_info (GIRepository *repository, } /** - * g_irepository_find_by_gtype + * g_irepository_find_by_gtype: * @repository: A #GIRepository, may be %NULL for the default - * @type: GType to search for + * @gtype: GType to search for * * Searches all loaded namespaces for a particular #GType. Note that * in order to locate the metadata, the namespace corresponding to @@ -645,7 +645,7 @@ g_irepository_get_info (GIRepository *repository, */ GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository, - GType type) + GType gtype) { IfaceData data; @@ -676,9 +676,9 @@ g_irepository_find_by_gtype (GIRepository *repository, } /** - * g_irepository_find_by_name + * g_irepository_find_by_name: * @repository: A #GIRepository, may be %NULL for the default - * @namespace: Namespace which will be searched + * @namespace_: Namespace which will be searched * @name: Entry name to find * * Searches for a particular entry in a namespace. Before calling @@ -726,12 +726,12 @@ collect_namespaces (gpointer key, } /** - * g_irepository_get_namespaces + * g_irepository_get_namespaces: * @repository: A #GIRepository, may be %NULL for the default * * Return the list of currently loaded namespaces. * - * Returns: : List of namespaces + * Returns: (utf8) (transfer full): List of namespaces */ gchar ** g_irepository_get_loaded_namespaces (GIRepository *repository) @@ -755,12 +755,12 @@ g_irepository_get_loaded_namespaces (GIRepository *repository) } /** - * g_irepository_get_version + * g_irepository_get_version: * @repository: A #GIRepository, may be %NULL for the default - * @namespace: Namespace to inspect + * @namespace_: Namespace to inspect * * This function returns the loaded version associated with the given - * namespace @namespace. + * namespace @namespace_. * * Note: The namespace must have already been loaded using a function * such as #g_irepository_require before calling this function. @@ -787,12 +787,12 @@ g_irepository_get_version (GIRepository *repository, } /** - * g_irepository_get_shared_library + * g_irepository_get_shared_library: * @repository: A #GIRepository, may be %NULL for the default - * @namespace: Namespace to inspect + * @namespace_: Namespace to inspect * * This function returns the full path to the shared C library - * associated with the given namespace @namespace. There may be no + * associated with the given namespace @namespace_. There may be no * shared library path associated, in which case this function will * return %NULL. * @@ -824,17 +824,16 @@ g_irepository_get_shared_library (GIRepository *repository, } /** - * g_irepository_get_typelib_path + * g_irepository_get_typelib_path: * @repository: Repository, may be %NULL for the default - * @namespace: GI namespace to use, e.g. "Gtk" - * @version: : Version of namespace to use, e.g. "0.8", may be %NULL + * @namespace_: GI namespace to use, e.g. "Gtk" * - * If namespace @namespace is loaded, return the full path to the + * If namespace @namespace_ is loaded, return the full path to the * .typelib file it was loaded from. If the typelib for - * namespace @namespace was included in a shared library, return - * the special string "". + * namespace @namespace_ was included in a shared library, return + * the special string "$lt;builtin$gt;". * - * Returns: Filesystem path (or ) if successful, %NULL if namespace is not loaded + * Returns: Filesystem path (or $lt;builtin$gt;) if successful, %NULL if namespace is not loaded */ const gchar * @@ -1080,15 +1079,15 @@ find_namespace_latest (const gchar *namespace, } /** - * g_irepository_require - * @repository: : Repository, may be %NULL for the default - * @namespace: GI namespace to use, e.g. "Gtk" - * @version: : Version of namespace, may be %NULL for latest + * g_irepository_require: + * @repository: (allow-none): Repository, may be %NULL for the default + * @namespace_: GI namespace to use, e.g. "Gtk" + * @version: (allow-none): Version of namespace, may be %NULL for latest * @flags: Set of %GIRepositoryLoadFlags, may be %0 * @error: a #GError. * - * Force the namespace @namespace to be loaded if it isn't already. - * If @namespace is not loaded, this function will search for a + * Force the namespace @namespace_ to be loaded if it isn't already. + * If @namespace_ is not loaded, this function will search for a * ".typelib" file using the repository search path. In addition, a * version @version of namespace may be specified. If @version is * not specified, the latest will be used. diff --git a/girffi.c b/girffi.c index ffde85388..4611a6303 100644 --- a/girffi.c +++ b/girffi.c @@ -225,7 +225,7 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, } /** - * g_callable_info_prepare_closure: + * g_callable_info_free_closure: * @callable_info: a callable info from a typelib * @closure: ffi closure * diff --git a/giroffsets.c b/giroffsets.c index cc56d0bc8..d83474646 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -462,7 +462,7 @@ check_needs_computation (GIrNode *node, * g_ir_node_compute_offsets: * @node: a #GIrNode * @module: Current module being processed - * @moudles: all currently loaded modules + * @modules: all currently loaded modules * * If a node is a a structure or union, makes sure that the field * offsets have been computed, and also computes the overall size and diff --git a/girparser.c b/girparser.c index 97e3a1e09..1c7f5b34f 100644 --- a/girparser.c +++ b/girparser.c @@ -3188,12 +3188,15 @@ post_filter (GIrModule *module) /** * g_ir_parser_parse_string: * @parser: a #GIrParser + * @namespace: the namespace of the string + * @buffer: the data containing the XML + * @length: length of the data * @error: return location for a #GError, or %NULL * * Parse a string that holds a complete GIR XML file, and return a list of a * a #GirModule for each <namespace/> element within the file. * - * @returns: a newly allocated list of #GIrModule. The modules themselves + * Returns: a newly allocated list of #GIrModule. The modules themselves * are owned by the #GIrParser and will be freed along with the parser. */ GList * @@ -3258,12 +3261,13 @@ g_ir_parser_parse_string (GIrParser *parser, /** * g_ir_parser_parse_file: * @parser: a #GIrParser + * @filename: filename to parse * @error: return location for a #GError, or %NULL * * Parse GIR XML file, and return a list of a a #GirModule for each * <namespace/> element within the file. * - * @returns: a newly allocated list of #GIrModule. The modules themselves + * Returns: a newly allocated list of #GIrModule. The modules themselves * are owned by the #GIrParser and will be freed along with the parser. */ GList * diff --git a/gtypelib.c b/gtypelib.c index e3b1214ed..b228a23f8 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -2124,6 +2124,7 @@ g_typelib_get_namespace (GTypelib *typelib) /** * g_typelib_symbol: + * @typelib: the typelib * @symbol_name: name of symbol to be loaded * @symbol: returns a pointer to the symbol value * From cd46d2fa0b82dc20ff9b9c94aa4c8219fa98f6d6 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Thu, 12 Feb 2009 09:51:16 -0500 Subject: [PATCH 209/692] Fix build --- girepository.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/girepository.c b/girepository.c index 40c478648..06ea13c5e 100644 --- a/girepository.c +++ b/girepository.c @@ -652,14 +652,14 @@ g_irepository_find_by_gtype (GIRepository *repository, repository = get_repository (repository); data.iface = g_hash_table_lookup (repository->priv->info_by_gtype, - (gpointer)type); + (gpointer)gtype); if (data.iface) return g_base_info_ref (data.iface); data.repo = repository; data.name = NULL; - data.type = g_type_name (type); + data.type = g_type_name (gtype); data.index = -1; data.iface = NULL; @@ -668,7 +668,7 @@ g_irepository_find_by_gtype (GIRepository *repository, if (data.iface) g_hash_table_insert (repository->priv->info_by_gtype, - (gpointer) type, + (gpointer) gtype, g_base_info_ref (data.iface)); From ff6c10e53c5974370973f06ee567f71afff1e343 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 11 Feb 2009 20:46:59 -0500 Subject: [PATCH 210/692] Bug 571373 - Move typelib docs from typelib-format.txt into girepository.h typelib-format.txt was growing out of date; a good solution to this is to move it closer to the code it's documenting. By doing this we also gain the ability to use gtk-doc on it. --- girepository.h | 15 +- gtypelib.h | 587 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 540 insertions(+), 62 deletions(-) diff --git a/girepository.h b/girepository.h index 7ec86129b..3508f4ddb 100644 --- a/girepository.h +++ b/girepository.h @@ -279,11 +279,16 @@ typedef enum { } GIDirection; typedef enum { - GI_SCOPE_TYPE_INVALID, - GI_SCOPE_TYPE_CALL, - GI_SCOPE_TYPE_OBJECT, - GI_SCOPE_TYPE_ASYNC, - GI_SCOPE_TYPE_NOTIFIED + GI_SCOPE_TYPE_INVALID, /* The argument is not of callback type */ + GI_SCOPE_TYPE_CALL, /* The callback and associated user_data is only used during the + call to this function */ + GI_SCOPE_TYPE_OBJECT, /* The callback and associated user_data is used until + the object containing this method is destroyed */ + GI_SCOPE_TYPE_ASYNC, /* The callback and associated user_data is + only used until the callback is invoked, and the callback + is invoked always exactly once. */ + GI_SCOPE_TYPE_NOTIFIED /* The callback and and associated user_data is + used until the caller is notfied via the destroy_notify */ } GIScopeType; GIDirection g_arg_info_get_direction (GIArgInfo *info); diff --git a/gtypelib.h b/gtypelib.h index ee7442f37..5ab2acb38 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -2,6 +2,7 @@ * typelib format, validation * * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,10 +28,134 @@ G_BEGIN_DECLS +/** + * SECTION:gtypelib + * @short_description: Layout and accessors for typelib + * @stability: Stable + * + * The "typelib" is a binary, readonly, memory-mappable database + * containing reflective information about a GObject library. + * + * The format of GObject typelib is strongly influenced by the Mozilla XPCOM + * format. + * + * Some of the differences to XPCOM include: + * - Type information is stored not quite as compactly (XPCOM stores it inline + * in function descriptions in variable-sized blobs of 1 to n bytes. We store + * 16 bits of type information for each parameter, which is enough to encode + * simple types inline. Complex (e.g. recursive) types are stored out of line + * in a separate list of types. + * - String and complex type data is stored outside of typelib entry blobs, + * references are stored as offsets relative to the start of the typelib. + * One possibility is to store the strings and types in a pools at the end + * of the typelib. + * + * The typelib has the following general format. + * + * typelib ::= header, directory, blobs, annotations + * + * directory ::= list of entries + * + * entry ::= blob type, name, namespace, offset + * blob ::= function|callback|struct|boxed|enum|flags|object|interface|constant|errordomain|union + * annotations ::= list of annotations, sorted by offset + * annotation ::= offset, key, value + * + * Details + * + * We describe the fragments that make up the typelib in the form of C structs + * (although some fall short of being valid C structs since they contain multiple + * flexible arrays). + */ + +/* +TYPELIB HISTORY +----- +Version 1.0 + +Changes since 0.9: +- Add padding to structures + +Changes since 0.8: +- Add class struct concept to ObjectBlob +- Add is_class_struct bit to StructBlob + +Changes since 0.7: +- Add dependencies + +Changes since 0.6: +- rename metadata to typelib, to follow xpcom terminology + +Changes since 0.5: +- basic type cleanup: + + remove GString + + add [u]int, [u]long, [s]size_t + + rename string to utf8, add filename +- allow blob_type to be zero for non-local entries + +Changes since 0.4: +- add a UnionBlob + +Changes since 0.3: +- drop short_name for ValueBlob + +Changes since 0.2: +- make inline types 4 bytes after all, remove header->types and allow + types to appear anywhere +- allow error domains in the directory + +Changes since 0.1: + +- drop comments about _GOBJ_METADATA +- drop string pool, strings can appear anywhere +- use 'blob' as collective name for the various blob types +- rename 'type' field in blobs to 'blob_type' +- rename 'type_name' and 'type_init' fields to 'gtype_name', 'gtype_init' +- shrink directory entries to 12 bytes +- merge struct and boxed blobs +- split interface blobs into enum, object and interface blobs +- add an 'unregistered' flag to struct and enum blobs +- add a 'wraps_vfunc' flag to function blobs and link them to + the vfuncs they wrap +- restrict value blobs to only occur inside enums and flags again +- add constant blobs, allow them toplevel, in interfaces and in objects +- rename 'receiver_owns_value' and 'receiver_owns_container' to + 'transfer_ownership' and 'transfer_container_ownership' +- add a 'struct_offset' field to virtual function and field blobs +- add 'dipper' and 'optional' flags to arg blobs +- add a 'true_stops_emit' flag to signal blobs +- add variable blob sizes to header +- store offsets to signature blobs instead of including them directly +- change the type offset to be measured in words rather than bytes +*/ + +/** + * G_IR_MAGIC: + * + * Identifying prefix for the typelib. This was inspired by XPCOM, + * which in turn borrowed from PNG. + */ #define G_IR_MAGIC "GOBJ\nMETADATA\r\n\032" -enum -{ +/** + * GTypelibBlobType: + * @BLOB_TYPE_INVALID: Should not appear in code + * @BLOB_TYPE_FUNCTION: A #FunctionBlob + * @BLOB_TYPE_CALLBACK: A #CallbackBlob + * @BLOB_TYPE_STRUCT: A #StructBlob + * @BLOB_TYPE_BOXED: Can be either a #StructBlob or #UnionBlob + * @BLOB_TYPE_ENUM: An #EnumBlob + * @BLOB_TYPE_FLAGS: An #EnumBlob + * @BLOB_TYPE_OBJECT: An #ObjectBlob + * @BLOB_TYPE_INTERFACE: An #InterfaceBlob + * @BLOB_TYPE_CONSTANT: A #ConstantBlob + * @BLOB_TYPE_ERROR_DOMAIN: A #ErrorDomainBlob + * @BLOB_TYPE_UNION: A #UnionBlob + * + * The integral value of this enumeration appears in each "Blob" + * component of a typelib to identify its type. + */ +typedef enum { BLOB_TYPE_INVALID, BLOB_TYPE_FUNCTION, BLOB_TYPE_CALLBACK, @@ -43,7 +168,7 @@ enum BLOB_TYPE_CONSTANT, BLOB_TYPE_ERROR_DOMAIN, BLOB_TYPE_UNION -}; +} GTypelibBlobType; #define BLOB_IS_REGISTERED_TYPE(blob) \ ((blob)->blob_type == BLOB_TYPE_STRUCT || \ @@ -52,8 +177,58 @@ enum (blob)->blob_type == BLOB_TYPE_OBJECT || \ (blob)->blob_type == BLOB_TYPE_INTERFACE) -typedef struct -{ +/** + * Header: + * @magic: See #G_IR_MAGIC. + * @major_version: The version of the typelib format. Minor version changes indicate + * compatible changes and should still allow the typelib to be parsed + * by a parser designed for the same major_version. + * @minor_version: See major_version. + * @n_entries: The number of entries in the directory. + * @n_local_entries: The number of entries referring to blobs in this typelib. The + * local entries must occur before the unresolved entries. + * @directory: Offset of the directory in the typelib. + * @n_annotations: Number of annotation blocks + * @annotations: Offset of the list of annotations in the typelib. + * @dependencies: Offset of a single string, which is the list of + * dependencies, separated by the '|' character. The + * dependencies are required in order to avoid having programs + * consuming a typelib check for an "Unresolved" type return + * from every API call. + * @size: The size in bytes of the typelib. + * @namespace: Offset of the namespace string in the typelib. + * @nsversion: Offset of the namespace version string in the typelib. + * @shared_library: This field is the set of shared libraries associated + * with the typelib. The entries are separated by the '|' (pipe) character. + * @entry_blob_size: The sizes of fixed-size blobs. Recording this information here + * allows to write parser which continue to work if the format is + * extended by adding new fields to the end of the fixed-size blobs. + * @function_blob_size: See above. + * @callback_blob_size: See above. + * @signal_blob_size: See above. + * @vfunc_blob_size: See above. + * @arg_blob_size: See above. + * @property_blob_size: See above. + * @field_blob_size: See above. + * @value_blob_size: See above. + * @annotation_blob_size: See above. + * @constant_blob_size: See above. + * @object_blob_size: See above. + * @union_blob_size: See above. + * @signature_blob_size: See above. + * @enum_blob_size: See above. + * @struct_blob_size: See above. + * @error_domain_blob_size: See above. + * @interface_blob_size: For variable-size blobs, the size of the struct up to the first + * flexible array member. Recording this information here allows to + * write parser which continue to work if the format is extended by + * adding new fields before the first flexible array member in + * variable-size blobs. + * + * The header structure appears exactly once at the beginning of a typelib. It is a + * collection of meta-information, such as the number of entries and dependencies. + */ +typedef struct { gchar magic[16]; guint8 major_version; guint8 minor_version; @@ -94,8 +269,21 @@ typedef struct guint16 padding[7]; } Header; -typedef struct -{ +/** + * DirEntry: + * @blob_type: A #GTypelibBlobType + * @local: Whether this entry refers to a blob in this typelib. + * @name: The name of the entry. + * @offset: If is_local is set, this is the offset of the blob in the typelib. + * Otherwise, it is the offset of the namespace in which the blob has + * to be looked up by name. + * + * References to directory entries are stored as 1-based 16-bit indexes. + * + * All blobs pointed to by a directory entry start with the same layout for + * the first 8 bytes (the reserved flags may be used by some blob types) + */ +typedef struct { guint16 blob_type; guint16 local : 1; @@ -105,7 +293,14 @@ typedef struct guint32 offset; } DirEntry; - +/** + * SimpleTypeBlob: + * @is_pointer: Indicates whether the type is passed by reference. + * @tag: A #GITypeTag + * @offset: Offset relative to header->types that points to a TypeBlob. + * Unlike other offsets, this is in words (ie 32bit units) rather + * than bytes. + */ typedef union { struct @@ -119,9 +314,50 @@ typedef union guint32 offset; } SimpleTypeBlob; - -typedef struct -{ +/* + * ArgBlob: + * @name: A suggested name for the parameter. + * @in: The parameter is an input to the function + * @out: The parameter is used to return an output of the function. + * Parameters can be both in and out. Out parameters implicitly + * add another level of indirection to the parameter type. Ie if + * the type is uint32 in an out parameter, the function actually + * takes an uint32*. + * @dipper: The parameter is a pointer to a struct or object that will + * receive an output of the function. + * @allow_none: Only meaningful for types which are passed as pointers. + * For an in parameter, indicates if it is ok to pass NULL in, for + * an out parameter, whether it may return NULL. Note that NULL is a + * valid GList and GSList value, thus allow_none will normally be set + * for parameters of these types. + * @optional: For an out parameter, indicates that NULL may be passed in + * if the value is not needed. + * @transfer_ownership: For an in parameter, indicates that the function takes over + * ownership of the parameter value. For an out parameter, it + * indicates that the caller is responsible for freeing the return + * value. + * @transfer_container_ownership: For container types, indicates that the + * ownership of the container, but not of its contents is transferred. This is typically the case + * for out parameters returning lists of statically allocated things. + * @is_return_value: The parameter should be considered the return value of the function. + * Only out parameters can be marked as return value, and there can be + * at most one per function call. If an out parameter is marked as + * return value, the actual return value of the function should be + * either void or a boolean indicating the success of the call. + * @scope: A #GIScopeType. If the parameter is of a callback type, this denotes the scope + * of the user_data and the callback function pointer itself + * (for languages that emit code at run-time). + * @closure: Index of the closure (user_data) parameter associated with the callback, + * or -1. + * @destroy: Index of the destroy notfication callback parameter associated with + * the callback, or -1. + * @arg_type: Describes the type of the parameter. See details below. + * + * Types are specified by four bytes. If the three high bytes are zero, + * the low byte describes a basic type, otherwise the 32bit number is an + * offset which points to a TypeBlob. + */ +typedef struct { guint32 name; guint in : 1; @@ -141,8 +377,21 @@ typedef struct SimpleTypeBlob arg_type; } ArgBlob; -typedef struct -{ +/** + * SignatureBlob: + * @return_type: Describes the type of the return value. See details below. + * @may_return_null: Only relevant for pointer types. Indicates whether the caller + * must expect NULL as a return value. + * @caller_owns_return_value: If set, the caller is responsible for freeing the return value + * if it is no longer needed. + * @caller_owns_return_container: This flag is only relevant if the return type is a container type. + * If the flag is set, the caller is resonsible for freeing the + * container, but not its contents. + * @n_arguments: The number of arguments that this function expects, also the length + * of the array of ArgBlobs. + * @arguments: An array of ArgBlob for the arguments of the function. + */ +typedef struct { SimpleTypeBlob return_type; guint16 may_return_null : 1; @@ -155,8 +404,16 @@ typedef struct ArgBlob arguments[]; } SignatureBlob; -typedef struct -{ +/** + * CommonBlob: + * @blob_type: A #GTypelibBlobType + * @deprecated: Whether the blob is deprecated. + * @name: The name of the blob. + * + * The #CommonBlob is shared between #FunctionBlob, + * #CallbackBlob, #SignalBlob. + */ +typedef struct { guint16 blob_type; /* 1 */ guint16 deprecated : 1; @@ -165,8 +422,30 @@ typedef struct guint32 name; } CommonBlob; -typedef struct -{ +/** + * FunctionBlob: + * @blob_Type: #BLOB_TYPE_FUNCTION + * @symbol: The symbol which can be used to obtain the function pointer with + * dlsym(). + * @deprecated: The function is deprecated. + * @setter: The function is a setter for a property. Language bindings may + * prefer to not bind individual setters and rely on the generic + * g_object_set(). + * @getter: The function is a getter for a property. Language bindings may + * prefer to not bind individual getters and rely on the generic + * g_object_get(). + * @constructor:The function acts as a constructor for the object it is contained + * in. + * @wraps_vfunc: The function is a simple wrapper for a virtual function. + * @index: Index of the property that this function is a setter or getter of + * in the array of properties of the containing interface, or index + * of the virtual function that this function wraps. + * @signature: Offset of the SignatureBlob describing the parameter types and the + * return value type. + * @is_static: The function is a "static method"; in other words it's a pure + * function whose name is conceptually scoped to the object. + */ +typedef struct { guint16 blob_type; /* 1 */ guint16 deprecated : 1; @@ -189,8 +468,12 @@ typedef struct guint16 reserved2 : 16; } FunctionBlob; -typedef struct -{ +/** + * CallbackBlob: + * @signature: Offset of the #SignatureBlob describing the parameter types and the + * return value type. + */ +typedef struct { guint16 blob_type; /* 2 */ guint16 deprecated : 1; @@ -200,8 +483,16 @@ typedef struct guint32 signature; } CallbackBlob; -typedef struct -{ +/** + * InterfaceTypeBlob: + * @pointer: Whether this type represents an indirection + * @tag: A #GITypeTag + * @interface: Index of the directory entry for the interface. + * + * Types which are described by an entry in the typelib have a tag value of 21. + * If the interface is an enum of flags type, is_pointer is 0, otherwise it is 1. + */ +typedef struct { guint8 pointer :1; guint8 reserved :2; guint8 tag :5; @@ -209,8 +500,23 @@ typedef struct guint16 interface; } InterfaceTypeBlob; -typedef struct -{ +/** + * ArrayTypeBlob: + * @zero_terminated: Indicates that the array must be terminated by a suitable #NULL + * value. + * @has_length: Indicates that length points to a parameter specifying the length + * of the array. If both has_length and zero_terminated are set, the + * convention is to pass -1 for the length if the array is + * zero-terminated. + * @length: The index of the parameter which is used to pass the length of the + * array. The parameter must be an integer type and have the same + * direction as this one. + * @type: The type of the array elements. + * + * Arrays have a tag value of 20. They are passed by reference, thus is_pointer + * is always 1. + */ +typedef struct { guint16 pointer :1; guint16 reserved :2; guint16 tag :5; @@ -228,8 +534,13 @@ typedef struct SimpleTypeBlob type; } ArrayTypeBlob; -typedef struct -{ +/** + * ParamTypeBlob: + * @n_types: The number of parameter types to follow. + * @type: Describes the type of the list elements. + * + */ +typedef struct { guint8 pointer :1; guint8 reserved :2; guint8 tag :5; @@ -240,8 +551,12 @@ typedef struct SimpleTypeBlob type[]; } ParamTypeBlob; -typedef struct -{ +/** + * ErrorTypeBlob: + * @n_domains: The number of domains to follow + * @domains: Indices of the directory entries for the error domains + */ +typedef struct { guint8 pointer :1; guint8 reserved :2; guint8 tag :5; @@ -252,8 +567,14 @@ typedef struct guint16 domains[]; } ErrorTypeBlob; -typedef struct -{ +/** + * ErrorDomainBlob: + * @get_quark: The symbol name of the function which must be called to obtain the + * GQuark for the error domain. + * @error_codes: Index of the InterfaceBlob describing the enumeration which lists + * the possible error codes. + */ +typedef struct { guint16 blob_type; /* 10 */ guint16 deprecated : 1; @@ -266,16 +587,34 @@ typedef struct guint16 reserved2; } ErrorDomainBlob; -typedef struct -{ +/** + * ValueBlob: + * @deprecated: Whether this value is deprecated + * @value: The numerical value + * @name: Name of blob + * + * Values commonly occur in enums and flags. + */ +typedef struct { guint32 deprecated : 1; guint32 reserved :31; guint32 name; guint32 value; } ValueBlob; -typedef struct -{ +/** + * FieldBlob: + * @name: The name of the field. + * @readable: + * @writable: How the field may be accessed. + * @bits: If this field is part of a bitfield, the number of bits which it + * uses, otherwise 0. + * @struct_offset: + * The offset of the field in the struct. The value 0xFFFF indicates + * that the struct offset is unknown. + * @type: The type of the field. + */ +typedef struct { guint32 name; guint8 readable :1; @@ -288,8 +627,12 @@ typedef struct SimpleTypeBlob type; } FieldBlob; -typedef struct -{ +/** + * RegisteredTypeBlob: + * @gtype_name: The name under which the type is registered with GType. + * @gtype_init: The symbol name of the get_type() function which registers the type. + */ +typedef struct { guint16 blob_type; guint16 deprecated : 1; guint16 unregistered : 1; @@ -300,8 +643,23 @@ typedef struct guint32 gtype_init; } RegisteredTypeBlob; -typedef struct -{ +/** + * StructBlob: + * @blob_type: #BLOB_TYPE_STRUCT + * @deprecated: Whether this structure is deprecated + * @unregistered: If this is set, the type is not registered with GType. + * @alignment: The byte boundary that the struct is aligned to in memory + * @is_class_struct: Whether this structure is the "class structure" for a GObject + * @size: The size of the struct in bytes. + * @gtype_name: String name of the associated #GType + * @gtype_init: String naming the symbol which gets the runtime #GType + * @n_fields: + * @n_functions: The lengths of the arrays. + * @fields: An array of n_fields FieldBlobs. + * @functions: An array of n_functions FunctionBlobs. The described functions + * should be considered as methods of the struct. + */ +typedef struct { guint16 blob_type; guint16 deprecated : 1; @@ -327,8 +685,24 @@ typedef struct #endif } StructBlob; -typedef struct -{ +/** + * UnionBlob; + * @unregistered: If this is set, the type is not registered with GType. + * @discriminated: Is set if the union is discriminated + * @alignment: The byte boundary that the union is aligned to in memory + * @size: The size of the union in bytes. + * @gtype_name: String name of the associated #GType + * @gtype_init: String naming the symbol which gets the runtime #GType + * @n_fields: Length of the arrays + * @discriminator_offset: Offset from the beginning of the union where the + * discriminator of a discriminated union is located. + * The value 0xFFFF indicates that the discriminator offset + * is unknown. + * @discriminator_type: Type of the discriminator + * @discriminator_values: On discriminator value per field + * @fields: Array of FieldBlobs describing the alternative branches of the union + */ +typedef struct { guint16 blob_type; guint16 deprecated : 1; guint16 unregistered : 1; @@ -355,8 +729,17 @@ typedef struct #endif } UnionBlob; -typedef struct -{ +/** + * EnumBlob: + * @unregistered: If this is set, the type is not registered with GType. + * @storage_type: The tag of the type used for the enum in the C ABI + * (will be a signed or unsigned integral type) + * @gtype_name: String name of the associated #GType + * @gtype_init: String naming the symbol which gets the runtime #GType + * @n_values: The lengths of the values arrays. + * @values: Describes the enum values. + */ +typedef struct { guint16 blob_type; guint16 deprecated : 1; @@ -375,8 +758,16 @@ typedef struct ValueBlob values[]; } EnumBlob; -typedef struct -{ +/** + * PropertyBlob: + * @name: The name of the property. + * @readable: + * @writable: + * @construct: + * @construct_only: The ParamFlags used when registering the property. + * @type: Describes the type of the property. + */ +typedef struct { guint32 name; guint32 deprecated : 1; @@ -390,8 +781,24 @@ typedef struct } PropertyBlob; -typedef struct -{ +/** + * SignalBlob: + * @name: The name of the signal. + * @run_first: + * @run_last: + * @run_cleanup: + * @no_recurse: + * @detailed: + * @action: + * @no_hooks: The flags used when registering the signal. + * @has_class_closure: Set if the signal has a class closure. + * @true_stops_emit: Whether the signal has true-stops-emit semantics + * @class_closure: The index of the class closure in the list of virtual functions + * of the object or interface on which the signal is defined. + * @signature: Offset of the SignatureBlob describing the parameter types and the + * return value type. + */ +typedef struct { guint16 deprecated : 1; guint16 run_first : 1; guint16 run_last : 1; @@ -411,8 +818,24 @@ typedef struct guint32 signature; } SignalBlob; -typedef struct -{ +/** + * VFuncBlob: + * @name: The name of the virtual function. + * @must_chain_up: If set, every implementation of this virtual function must + * chain up to the implementation of the parent class. + * @must_be_implemented: If set, every derived class must override this virtual function. + * @must_not_be_implemented: If set, derived class must not override this virtual function. + * @class_closure: Set if this virtual function is the class closure of a signal. + * @signal: The index of the signal in the list of signals of the object or + * interface to which this virtual function belongs. + * @struct_offset: + * The offset of the function pointer in the class struct. The value + * 0xFFFF indicates that the struct offset is unknown. + * @signature: + * Offset of the SignatureBlob describing the parameter types and the + * return value type. + */ +typedef struct { guint32 name; guint16 must_chain_up : 1; @@ -427,8 +850,31 @@ typedef struct guint32 signature; } VFuncBlob; -typedef struct -{ +/** + * ObjectBlob: + * @blob_type: #BLOB_TYPE_OBJECT + * @gtype_name: String name of the associated #GType + * @gtype_init: String naming the symbol which gets the runtime #GType + * @parent: The directory index of the parent type. This is only set for + * objects. If an object does not have a parent, it is zero. + * @n_interfaces: + * @n_fields: + * @n_properties: + * @n_methods: + * @n_signals: + * @n_vfuncs: + * @n_constants: The lengths of the arrays.Up to 16bits of padding may be inserted + * between the arrays to ensure that they start on a 32bit boundary. + * @interfaces: An array of indices of directory entries for the implemented + * interfaces. + * @fields: Describes the fields. + * @methods: Describes the methods, constructors, setters and getters. + * @properties: Describes the properties. + * @signals: Describes the signals. + * @vfuncs: Describes the virtual functions. + * @constants: Describes the constants. + */ +typedef struct { guint16 blob_type; /* 7 */ guint16 deprecated : 1; guint16 abstract : 1; @@ -463,8 +909,24 @@ typedef struct #endif } ObjectBlob; -typedef struct -{ +/** + * InterfaceBlob: + * @n_prerequisites: Number of prerequisites + * @n_properties: Number of properties + * @n_methods: Number of methods + * @n_signals: Number of signals + * @n_vfuncs: Number of virtual functions + * @n_constants: The lengths of the arrays. + * Up to 16bits of padding may be inserted between the arrays to ensure that they + * start on a 32bit boundary. + * @prerequisites: An array of indices of directory entries for required interfaces. + * @methods: Describes the methods, constructors, setters and getters. + * @properties: Describes the properties. + * @signals: Describes the signals. + * @vfuncs: Describes the virtual functions. + * @constants: Describes the constants. + */ +typedef struct { guint16 blob_type; guint16 deprecated : 1; guint16 reserved :15; @@ -492,9 +954,14 @@ typedef struct #endif } InterfaceBlob; - -typedef struct -{ +/** + * ConstantBlob: + * @type: The type of the value. In most cases this should be a numeric + * type or string. + * @size: The size of the value in bytes. + * @offset: The offset of the value in the typelib. + */ +typedef struct { guint16 blob_type; guint16 deprecated : 1; guint16 reserved :15; @@ -506,14 +973,20 @@ typedef struct guint32 offset; } ConstantBlob; -typedef struct -{ +/** + * AnnotationBlob: + * @offset: The offset of the typelib entry to which this annotation refers. + * Annotations are kept sorted by offset, so that the annotations + * of an entry can be found by a binary search. + * @name: The name of the annotation, a string. + * @value: The value of the annotation (also a string) + */ +typedef struct { guint32 offset; guint32 name; guint32 value; } AnnotationBlob; - struct _GTypelib { guchar *data; gsize len; From 83c0d9b93b5a4281e41fddb5866bb229bfebdbf2 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 11 Feb 2009 23:36:31 -0500 Subject: [PATCH 211/692] Bug 571373 - Consistently use sizeof () inside gtypelib and girmodule This not only makes it easier to change these structures, it becomes clearer exactly what each magic number is just for reference. --- girmodule.c | 34 +++++++++++++++++----------------- gtypelib.c | 40 ++++++++++++++++++++-------------------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/girmodule.c b/girmodule.c index 63d42cced..5f5ae0928 100644 --- a/girmodule.c +++ b/girmodule.c @@ -163,7 +163,7 @@ g_ir_module_build_typelib (GIrModule *module, g_message ("%d entries (%d local), %d dependencies\n", n_entries, n_local_entries, g_list_length (module->dependencies)); - dir_size = n_entries * 12; + dir_size = n_entries * sizeof (DirEntry); size = header_size + dir_size; size += ALIGN_VALUE (strlen (module->name) + 1, 4); @@ -208,24 +208,24 @@ g_ir_module_build_typelib (GIrModule *module, write_string (module->shared_library, strings, data, &header_size) : 0); header->directory = ALIGN_VALUE (header_size, 4); - header->entry_blob_size = 12; + header->entry_blob_size = sizeof (DirEntry); header->function_blob_size = sizeof (FunctionBlob); - header->callback_blob_size = 12; - header->signal_blob_size = 12; - header->vfunc_blob_size = 16; - header->arg_blob_size = 16; - 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 = 24; + header->callback_blob_size = sizeof (CallbackBlob); + header->signal_blob_size = sizeof (SignalBlob); + header->vfunc_blob_size = sizeof (VFuncBlob); + header->arg_blob_size = sizeof (ArgBlob); + header->property_blob_size = sizeof (PropertyBlob); + header->field_blob_size = sizeof (FieldBlob); + header->value_blob_size = sizeof (ValueBlob); + header->constant_blob_size = sizeof (ConstantBlob); + header->error_domain_blob_size = sizeof (ErrorDomainBlob); + header->annotation_blob_size = sizeof (AnnotationBlob); + header->signature_blob_size = sizeof (SignatureBlob); + header->enum_blob_size = sizeof (EnumBlob); + header->struct_blob_size = sizeof (StructBlob); header->object_blob_size = sizeof(ObjectBlob); - header->interface_blob_size = 28; - header->union_blob_size = 32; + header->interface_blob_size = sizeof (InterfaceBlob); + header->union_blob_size = sizeof (UnionBlob); /* fill in directory and content */ entry = (DirEntry *)&data[header->directory]; diff --git a/gtypelib.c b/gtypelib.c index b228a23f8..6de621795 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -168,6 +168,7 @@ g_typelib_check_sanity (void) CHECK_SIZE (SignatureBlob, 8); CHECK_SIZE (CommonBlob, 8); CHECK_SIZE (FunctionBlob, 20); + CHECK_SIZE (CallbackBlob, 12); CHECK_SIZE (InterfaceTypeBlob, 4); CHECK_SIZE (ArrayTypeBlob, 8); CHECK_SIZE (ParamTypeBlob, 4); @@ -315,32 +316,31 @@ validate_header (ValidateContext *ctx, } /* This is a sanity check for a specific typelib; it - * prevents us from loading an incompatible typelib. It's OK to change - * these hardcoded constants to sizeof() as you see fit. + * prevents us from loading an incompatible typelib. * - * We want to keep the hardcoded checks in g_typelib_check_sanity to + * The hardcoded checks in g_typelib_check_sanity to * protect against inadvertent or buggy changes to the typelib format * itself. */ - if (header->entry_blob_size != 12 || - header->function_blob_size != 20 || - header->callback_blob_size != 12 || - header->signal_blob_size != 12 || - header->vfunc_blob_size != 16 || - header->arg_blob_size != 16 || - 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 != 24 || + if (header->entry_blob_size != sizeof (DirEntry) || + header->function_blob_size != sizeof (FunctionBlob) || + header->callback_blob_size != sizeof (CallbackBlob) || + header->signal_blob_size != sizeof (SignalBlob) || + header->vfunc_blob_size != sizeof (VFuncBlob) || + header->arg_blob_size != sizeof (ArgBlob) || + header->property_blob_size != sizeof (PropertyBlob) || + header->field_blob_size != sizeof (FieldBlob) || + header->value_blob_size != sizeof (ValueBlob) || + header->constant_blob_size != sizeof (ConstantBlob) || + header->error_domain_blob_size != sizeof (ErrorDomainBlob) || + header->annotation_blob_size != sizeof (AnnotationBlob) || + header->signature_blob_size != sizeof (SignatureBlob) || + header->enum_blob_size != sizeof (EnumBlob) || + header->struct_blob_size != sizeof (StructBlob) || header->object_blob_size != sizeof(ObjectBlob) || - header->interface_blob_size != 28 || - header->union_blob_size != 32) + header->interface_blob_size != sizeof (InterfaceBlob) || + header->union_blob_size != sizeof (UnionBlob)) { g_set_error (error, G_TYPELIB_ERROR, From b4d4ca5d38821c8de4766ede1483c0fc62d87c0f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 11 Feb 2009 23:51:28 -0500 Subject: [PATCH 212/692] Bug 571373 - Remove hardcoded offsets in ginfo.c In a few places we had hardcoded sizes for accessing structure members and computing into variable size arrays. Remove those. --- ginfo.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ginfo.c b/ginfo.c index f4ca1310a..7ecfe6337 100644 --- a/ginfo.c +++ b/ginfo.c @@ -775,7 +775,7 @@ g_arg_info_get_type (GIArgInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - return g_type_info_new (base, base->typelib, base->offset + 12); + return g_type_info_new (base, base->typelib, base->offset + G_STRUCT_OFFSET (ArgBlob, arg_type)); } /* GITypeInfo functions */ @@ -828,7 +828,9 @@ g_type_info_get_param_type (GITypeInfo *info, case GI_TYPE_TAG_GLIST: case GI_TYPE_TAG_GSLIST: case GI_TYPE_TAG_GHASH: - return g_type_info_new (base, base->typelib, base->offset + 4 + 4 * n); + return g_type_info_new (base, base->typelib, + base->offset + sizeof (ParamTypeBlob) + + sizeof (SimpleTypeBlob) * n); break; default: ; @@ -1024,7 +1026,7 @@ g_field_info_get_type (GIFieldInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - return g_type_info_new (base, base->typelib, base->offset + 8); + return g_type_info_new (base, base->typelib, base->offset + G_STRUCT_OFFSET (FieldBlob, type)); } /* GIRegisteredTypeInfo functions */ @@ -1722,7 +1724,7 @@ g_property_info_get_type (GIPropertyInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - return g_type_info_new (base, base->typelib, base->offset + 8); + return g_type_info_new (base, base->typelib, base->offset + G_STRUCT_OFFSET (PropertyBlob, type)); } From 8abbc0b2f99acc88c9b4def52f4ec55058b6df06 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 11 Feb 2009 23:53:05 -0500 Subject: [PATCH 213/692] Bug 571373 - Remove hardcoded sizes/offsets in girnode.c Where appropriate we now use G_STRUCT_OFFSET and sizeof() instead of hardcoded integers. Add comments for some special cases. --- girnode.c | 155 +++++++++++++++++++++++++++++------------------------- 1 file changed, 82 insertions(+), 73 deletions(-) diff --git a/girnode.c b/girnode.c index cc8aa5089..6d71ebebe 100644 --- a/girnode.c +++ b/girnode.c @@ -412,7 +412,7 @@ g_ir_node_get_size (GIrNode *node) switch (node->type) { case G_IR_NODE_CALLBACK: - size = 12; + size = sizeof (CallbackBlob); break; case G_IR_NODE_FUNCTION: @@ -420,11 +420,12 @@ g_ir_node_get_size (GIrNode *node) break; case G_IR_NODE_PARAM: - size = 12; + /* See the comment in the G_IR_NODE_PARAM/ArgBlob writing below */ + size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob); break; case G_IR_NODE_TYPE: - size = 4; + size = sizeof (SimpleTypeBlob); break; case G_IR_NODE_OBJECT: @@ -432,7 +433,7 @@ g_ir_node_get_size (GIrNode *node) GIrNodeInterface *iface = (GIrNodeInterface *)node; n = g_list_length (iface->interfaces); - size = sizeof(ObjectBlob) + 2 * (n + (n % 2)); + size = sizeof (ObjectBlob) + 2 * (n + (n % 2)); for (l = iface->members; l; l = l->next) size += g_ir_node_get_size ((GIrNode *)l->data); @@ -444,7 +445,7 @@ g_ir_node_get_size (GIrNode *node) GIrNodeInterface *iface = (GIrNodeInterface *)node; n = g_list_length (iface->prerequisites); - size = 28 + 2 * (n + (n % 2)); + size = sizeof (InterfaceBlob) + 2 * (n + (n % 2)); for (l = iface->members; l; l = l->next) size += g_ir_node_get_size ((GIrNode *)l->data); @@ -456,21 +457,21 @@ g_ir_node_get_size (GIrNode *node) { GIrNodeEnum *enum_ = (GIrNodeEnum *)node; - size = 20; + size = sizeof (EnumBlob); for (l = enum_->values; l; l = l->next) size += g_ir_node_get_size ((GIrNode *)l->data); } break; case G_IR_NODE_VALUE: - size = 12; + size = sizeof (ValueBlob); break; case G_IR_NODE_STRUCT: { GIrNodeStruct *struct_ = (GIrNodeStruct *)node; - size = 24; + size = sizeof (StructBlob); for (l = struct_->members; l; l = l->next) size += g_ir_node_get_size ((GIrNode *)l->data); } @@ -480,34 +481,34 @@ g_ir_node_get_size (GIrNode *node) { GIrNodeBoxed *boxed = (GIrNodeBoxed *)node; - size = 24; + size = sizeof (StructBlob); for (l = boxed->members; l; l = l->next) size += g_ir_node_get_size ((GIrNode *)l->data); } break; case G_IR_NODE_PROPERTY: - size = 12; + size = sizeof (PropertyBlob); break; case G_IR_NODE_SIGNAL: - size = 12; + size = sizeof (SignalBlob); break; case G_IR_NODE_VFUNC: - size = 16; + size = sizeof (VFuncBlob); break; case G_IR_NODE_FIELD: - size = 12; + size = sizeof (FieldBlob); break; case G_IR_NODE_CONSTANT: - size = 20; + size = sizeof (ConstantBlob); break; case G_IR_NODE_ERROR_DOMAIN: - size = 16; + size = sizeof (ErrorDomainBlob); break; case G_IR_NODE_XREF: @@ -518,7 +519,7 @@ g_ir_node_get_size (GIrNode *node) { GIrNodeUnion *union_ = (GIrNodeUnion *)node; - size = 32; + size = sizeof (UnionBlob); for (l = union_->members; l; l = l->next) size += g_ir_node_get_size ((GIrNode *)l->data); for (l = union_->discriminators; l; l = l->next) @@ -557,7 +558,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, case G_IR_NODE_CALLBACK: { GIrNodeFunction *function = (GIrNodeFunction *)node; - size = 12; + size = sizeof (CallbackBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); for (l = function->parameters; l; l = l->next) { @@ -570,7 +571,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, case G_IR_NODE_FUNCTION: { GIrNodeFunction *function = (GIrNodeFunction *)node; - size = 24; + size = sizeof (FunctionBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); size += ALIGN_VALUE (strlen (function->symbol) + 1, 4); for (l = function->parameters; l; l = l->next) @@ -583,7 +584,8 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeParam *param = (GIrNodeParam *)node; - size = 16; + /* See the comment in the G_IR_NODE_PARAM/ArgBlob writing below */ + size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob); if (node->name) size += ALIGN_VALUE (strlen (node->name) + 1, 4); size += g_ir_node_get_full_size_internal (node, (GIrNode *)param->type); @@ -593,9 +595,8 @@ g_ir_node_get_full_size_internal (GIrNode *parent, case G_IR_NODE_TYPE: { GIrNodeType *type = (GIrNodeType *)node; - if (type->tag < GI_TYPE_TAG_ARRAY) - size = 4; - else + size = sizeof (SimpleTypeBlob); + if (type->tag >= GI_TYPE_TAG_ARRAY) { g_debug ("node %p type tag '%s'", node, g_type_tag_to_string (type->tag)); @@ -603,21 +604,21 @@ g_ir_node_get_full_size_internal (GIrNode *parent, switch (type->tag) { case GI_TYPE_TAG_ARRAY: - size = 4 + 4; + size = sizeof (ArrayTypeBlob); if (type->parameter_type1) size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1); break; case GI_TYPE_TAG_INTERFACE: - size = 4 + 4; + size += sizeof (InterfaceTypeBlob); break; case GI_TYPE_TAG_GLIST: case GI_TYPE_TAG_GSLIST: - size = 4 + 4; + size += sizeof (ParamTypeBlob); if (type->parameter_type1) size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1); break; case GI_TYPE_TAG_GHASH: - size = 4 + 4 + 4; + size += sizeof (ParamTypeBlob) * 2; if (type->parameter_type1) size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1); if (type->parameter_type2) @@ -632,7 +633,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, else n = 0; - size = 4 + 4 + 2 * (n + n % 2); + size += sizeof (ErrorTypeBlob) + 2 * (n + n % 2); } break; default: @@ -669,7 +670,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNodeInterface *iface = (GIrNodeInterface *)node; n = g_list_length (iface->prerequisites); - size = 28; + size = sizeof (InterfaceBlob); 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); @@ -685,7 +686,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeEnum *enum_ = (GIrNodeEnum *)node; - size = 20; + size = sizeof (EnumBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); if (enum_->gtype_name) { @@ -700,7 +701,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, case G_IR_NODE_VALUE: { - size = 12; + size = sizeof (ValueBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); } break; @@ -709,7 +710,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeStruct *struct_ = (GIrNodeStruct *)node; - size = 24; + size = sizeof (StructBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); if (struct_->gtype_name) size += ALIGN_VALUE (strlen (struct_->gtype_name) + 1, 4); @@ -724,7 +725,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeBoxed *boxed = (GIrNodeBoxed *)node; - size = 24; + size = sizeof (StructBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); if (boxed->gtype_name) { @@ -740,7 +741,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeProperty *prop = (GIrNodeProperty *)node; - size = 12; + size = sizeof (PropertyBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); size += g_ir_node_get_full_size_internal (node, (GIrNode *)prop->type); } @@ -750,7 +751,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeSignal *signal = (GIrNodeSignal *)node; - size = 12; + size = sizeof (SignalBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); for (l = signal->parameters; l; l = l->next) size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); @@ -762,7 +763,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node; - size = 16; + size = sizeof (VFuncBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); for (l = vfunc->parameters; l; l = l->next) size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); @@ -774,7 +775,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeField *field = (GIrNodeField *)node; - size = 12; + size = sizeof (FieldBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->type); } @@ -784,7 +785,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeConstant *constant = (GIrNodeConstant *)node; - size = 20; + size = sizeof (ConstantBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); /* FIXME non-string values */ size += ALIGN_VALUE (strlen (constant->value) + 1, 4); @@ -796,7 +797,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node; - size = 16; + size = sizeof (ErrorDomainBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); size += ALIGN_VALUE (strlen (domain->getquark) + 1, 4); } @@ -816,7 +817,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeUnion *union_ = (GIrNodeUnion *)node; - size = 32; + size = sizeof (UnionBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); if (union_->gtype_name) size += ALIGN_VALUE (strlen (union_->gtype_name) + 1, 4); @@ -1371,7 +1372,7 @@ g_ir_node_build_typelib (GIrNode *node, GIrNodeType *type = (GIrNodeType *)node; SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset]; - *offset += 4; + *offset += sizeof (SimpleTypeBlob); if (type->tag < GI_TYPE_TAG_ARRAY || type->tag == GI_TYPE_TAG_UTF8 || @@ -1427,8 +1428,8 @@ g_ir_node_build_typelib (GIrNode *node, else array->length = -1; - pos = *offset2 + 4; - *offset2 += 8; + pos = *offset2 + G_STRUCT_OFFSET (ArrayTypeBlob, type); + *offset2 += sizeof (ArrayTypeBlob); g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, module, modules, strings, types, @@ -1439,7 +1440,7 @@ g_ir_node_build_typelib (GIrNode *node, case GI_TYPE_TAG_INTERFACE: { InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2]; - *offset2 += 4; + *offset2 += sizeof (InterfaceTypeBlob); iface->pointer = type->is_pointer; iface->reserved = 0; @@ -1462,8 +1463,8 @@ g_ir_node_build_typelib (GIrNode *node, param->reserved2 = 0; param->n_types = 1; - pos = *offset2 + 4; - *offset2 += 8; + pos = *offset2 + G_STRUCT_OFFSET (ParamTypeBlob, type); + *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob); g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, module, modules, strings, types, @@ -1482,8 +1483,8 @@ g_ir_node_build_typelib (GIrNode *node, param->reserved2 = 0; param->n_types = 2; - pos = *offset2 + 4; - *offset2 += 12; + pos = *offset2 + G_STRUCT_OFFSET (ParamTypeBlob, type); + *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob)*2; g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, module, modules, strings, types, @@ -1508,7 +1509,8 @@ g_ir_node_build_typelib (GIrNode *node, else blob->n_domains = 0; - *offset2 = ALIGN_VALUE (*offset2 + 4 + 2 * blob->n_domains, 4); + *offset2 = ALIGN_VALUE (*offset2 + G_STRUCT_OFFSET (ErrorTypeBlob, domains) + + 2 * blob->n_domains, 4); for (i = 0; i < blob->n_domains; i++) blob->domains[i] = find_entry (module, modules, type->errors[i]); } @@ -1529,7 +1531,8 @@ g_ir_node_build_typelib (GIrNode *node, FieldBlob *blob; blob = (FieldBlob *)&data[*offset]; - *offset += 8; + /* We handle the size member specially below, so subtract it */ + *offset += sizeof (FieldBlob) - sizeof (SimpleTypeBlob); blob->name = write_string (node->name, strings, data, offset2); blob->readable = field->readable; @@ -1551,7 +1554,8 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNodeProperty *prop = (GIrNodeProperty *)node; PropertyBlob *blob = (PropertyBlob *)&data[*offset]; - *offset += 8; + /* We handle the size member specially below, so subtract it */ + *offset += sizeof (PropertyBlob) - sizeof (SimpleTypeBlob); blob->name = write_string (node->name, strings, data, offset2); blob->deprecated = prop->deprecated; @@ -1578,8 +1582,8 @@ g_ir_node_build_typelib (GIrNode *node, signature = *offset2; n = g_list_length (function->parameters); - *offset += sizeof(FunctionBlob); - *offset2 += sizeof(SignatureBlob) + n * sizeof(ArgBlob); + *offset += sizeof (FunctionBlob); + *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob); blob->blob_type = BLOB_TYPE_FUNCTION; blob->deprecated = function->deprecated; @@ -1631,8 +1635,8 @@ g_ir_node_build_typelib (GIrNode *node, signature = *offset2; n = g_list_length (function->parameters); - *offset += sizeof(CallbackBlob); - *offset2 += sizeof(SignatureBlob) + n * sizeof(ArgBlob); + *offset += sizeof (CallbackBlob); + *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob); blob->blob_type = BLOB_TYPE_CALLBACK; blob->deprecated = function->deprecated; @@ -1674,8 +1678,8 @@ g_ir_node_build_typelib (GIrNode *node, signature = *offset2; n = g_list_length (signal->parameters); - *offset += sizeof(SignalBlob); - *offset2 += sizeof(SignatureBlob) + n * sizeof(ArgBlob); + *offset += sizeof (SignalBlob); + *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob); blob->deprecated = signal->deprecated; blob->run_first = signal->run_first; @@ -1725,8 +1729,8 @@ g_ir_node_build_typelib (GIrNode *node, signature = *offset2; n = g_list_length (vfunc->parameters); - *offset += sizeof(VFuncBlob); - *offset2 += sizeof(SignatureBlob) + n * sizeof(ArgBlob); + *offset += sizeof (VFuncBlob); + *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob); blob->name = write_string (node->name, strings, data, offset2); blob->must_chain_up = 0; /* FIXME */ @@ -1765,8 +1769,11 @@ g_ir_node_build_typelib (GIrNode *node, { ArgBlob *blob = (ArgBlob *)&data[*offset]; GIrNodeParam *param = (GIrNodeParam *)node; - - *offset += 12; + + /* The offset for this one is smaller than the struct because + * we recursively build the simple type inline here below. + */ + *offset += sizeof (ArgBlob) - sizeof (SimpleTypeBlob); blob->name = write_string (node->name, strings, data, offset2); blob->in = param->in; @@ -1817,7 +1824,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->n_fields = 0; blob->n_methods = 0; - *offset += 24; + *offset += sizeof (StructBlob); members = g_list_copy (struct_->members); @@ -1854,7 +1861,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->n_fields = 0; blob->n_methods = 0; - *offset += 24; + *offset += sizeof (StructBlob); members = g_list_copy (boxed->members); @@ -1902,6 +1909,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->discriminator_offset = union_->discriminator_offset; + /* We don't support Union discriminators right now. */ if (union_->discriminator_type) { *offset += 28; @@ -1912,10 +1920,11 @@ g_ir_node_build_typelib (GIrNode *node, } else { - *offset += 32; - blob->discriminated = FALSE; - blob->discriminator_type.offset = 0; - } + */ + /* Always do the non-discriminated case */ + *offset += sizeof (UnionBlob); + blob->discriminated = FALSE; + blob->discriminator_type.offset = 0; members = g_list_copy (union_->members); @@ -1950,8 +1959,8 @@ g_ir_node_build_typelib (GIrNode *node, EnumBlob *blob = (EnumBlob *)&data[*offset]; GIrNodeEnum *enum_ = (GIrNodeEnum *)node; - *offset += 20; - + *offset += sizeof (EnumBlob); + if (node->type == G_IR_NODE_ENUM) blob->blob_type = BLOB_TYPE_ENUM; else @@ -2083,7 +2092,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->n_vfuncs = 0; blob->n_constants = 0; - *offset += 28; + *offset += sizeof (InterfaceBlob); for (l = iface->prerequisites; l; l = l->next) { blob->n_prerequisites++; @@ -2129,7 +2138,7 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNodeValue *value = (GIrNodeValue *)node; ValueBlob *blob = (ValueBlob *)&data[*offset]; - *offset += 12; + *offset += sizeof (ValueBlob); blob->deprecated = value->deprecated; blob->reserved = 0; @@ -2142,7 +2151,7 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node; ErrorDomainBlob *blob = (ErrorDomainBlob *)&data[*offset]; - *offset += 16; + *offset += sizeof (ErrorDomainBlob); blob->blob_type = BLOB_TYPE_ERROR_DOMAIN; blob->deprecated = domain->deprecated; @@ -2160,8 +2169,8 @@ g_ir_node_build_typelib (GIrNode *node, ConstantBlob *blob = (ConstantBlob *)&data[*offset]; guint32 pos; - pos = *offset + 8; - *offset += 20; + pos = *offset + G_STRUCT_OFFSET (ConstantBlob, type); + *offset += sizeof (ConstantBlob); blob->blob_type = BLOB_TYPE_CONSTANT; blob->deprecated = constant->deprecated; From 361de29ba0f1e53f2109d72c6c1a2af2475c4a32 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 12 Feb 2009 15:17:25 -0500 Subject: [PATCH 214/692] Bug 571373 - Add padding to typelib objects Expand various typelib objects to ensure we have at least 16 bits left for each one to add another string indirection or directory offset, and also that we have at least a few bits for more flags. --- gtypelib.c | 20 ++++++++++---------- gtypelib.h | 29 ++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/gtypelib.c b/gtypelib.c index 6de621795..673436a04 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -175,18 +175,18 @@ g_typelib_check_sanity (void) CHECK_SIZE (ErrorTypeBlob, 4); CHECK_SIZE (ErrorDomainBlob, 16); CHECK_SIZE (ValueBlob, 12); - CHECK_SIZE (FieldBlob, 12); + CHECK_SIZE (FieldBlob, 16); CHECK_SIZE (RegisteredTypeBlob, 16); - CHECK_SIZE (StructBlob, 24); - CHECK_SIZE (EnumBlob, 20); - CHECK_SIZE (PropertyBlob, 12); - CHECK_SIZE (SignalBlob, 12); - CHECK_SIZE (VFuncBlob, 16); - CHECK_SIZE (ObjectBlob, 36); - CHECK_SIZE (InterfaceBlob, 28); - CHECK_SIZE (ConstantBlob, 20); + CHECK_SIZE (StructBlob, 32); + CHECK_SIZE (EnumBlob, 24); + CHECK_SIZE (PropertyBlob, 16); + CHECK_SIZE (SignalBlob, 16); + CHECK_SIZE (VFuncBlob, 20); + CHECK_SIZE (ObjectBlob, 44); + CHECK_SIZE (InterfaceBlob, 36); + CHECK_SIZE (ConstantBlob, 24); CHECK_SIZE (AnnotationBlob, 12); - CHECK_SIZE (UnionBlob, 32); + CHECK_SIZE (UnionBlob, 40); #undef CHECK_SIZE g_assert (size_check_ok); diff --git a/gtypelib.h b/gtypelib.h index 5ab2acb38..9a78873e7 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -622,7 +622,9 @@ typedef struct { guint8 reserved :6; guint8 bits; - guint16 struct_offset; + guint16 struct_offset; + + guint32 reserved2; SimpleTypeBlob type; } FieldBlob; @@ -678,6 +680,9 @@ typedef struct { guint16 n_fields; guint16 n_methods; + guint32 reserved2; + guint32 reserved3; + #if 0 /* variable-length parts of the blob */ FieldBlob fields[]; @@ -719,6 +724,9 @@ typedef struct { guint16 n_fields; guint16 n_functions; + guint32 reserved2; + guint32 reserved3; + gint32 discriminator_offset; SimpleTypeBlob discriminator_type; @@ -755,6 +763,8 @@ typedef struct { guint16 n_values; guint16 reserved2; + guint32 reserved3; + ValueBlob values[]; } EnumBlob; @@ -777,8 +787,9 @@ typedef struct { guint32 construct_only : 1; guint32 reserved :27; - SimpleTypeBlob type; + guint32 reserved2; + SimpleTypeBlob type; } PropertyBlob; /** @@ -815,6 +826,8 @@ typedef struct { guint32 name; + guint32 reserved2; + guint32 signature; } SignalBlob; @@ -847,6 +860,8 @@ typedef struct { guint16 struct_offset; guint16 reserved2; + + guint32 reserved3; guint32 signature; } VFuncBlob; @@ -886,7 +901,6 @@ typedef struct { guint16 parent; guint16 class_struct; - guint16 reserved2; guint16 n_interfaces; guint16 n_fields; @@ -895,6 +909,10 @@ typedef struct { guint16 n_signals; guint16 n_vfuncs; guint16 n_constants; + guint16 reserved2; + + guint32 reserved3; + guint32 reserved4; guint16 interfaces[]; @@ -942,6 +960,9 @@ typedef struct { guint16 n_vfuncs; guint16 n_constants; + guint32 reserved2; + guint32 reserved3; + guint16 prerequisites[]; #if 0 @@ -971,6 +992,8 @@ typedef struct { guint32 size; guint32 offset; + + guint32 reserved2; } ConstantBlob; /** From 865ac8e510de2b0fdd80e3324049c0c9e628e74a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 19 Feb 2009 09:56:20 -0500 Subject: [PATCH 215/692] Fix bad merge introduced in commit b006d50 --- girnode.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/girnode.c b/girnode.c index 6d71ebebe..744f908a1 100644 --- a/girnode.c +++ b/girnode.c @@ -1918,10 +1918,15 @@ g_ir_node_build_typelib (GIrNode *node, module, modules, strings, types, data, offset, offset2); } - else + /* Always do the non-discriminated case */ + /* + else { - */ - /* Always do the non-discriminated case */ + *offset += 32; + blob->discriminated = FALSE; + blob->discriminator_type.offset = 0; + } + */ *offset += sizeof (UnionBlob); blob->discriminated = FALSE; blob->discriminator_type.offset = 0; From 9a467b6cd84d2002ed7276e8acf16aa2befeda03 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 19 Feb 2009 11:18:48 -0500 Subject: [PATCH 216/692] Further cleanup for commented-out Union discriminator handling --- girnode.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/girnode.c b/girnode.c index 744f908a1..6400da937 100644 --- a/girnode.c +++ b/girnode.c @@ -1910,6 +1910,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->discriminator_offset = union_->discriminator_offset; /* We don't support Union discriminators right now. */ + /* if (union_->discriminator_type) { *offset += 28; @@ -1918,14 +1919,8 @@ g_ir_node_build_typelib (GIrNode *node, module, modules, strings, types, data, offset, offset2); } - /* Always do the non-discriminated case */ - /* else { - *offset += 32; - blob->discriminated = FALSE; - blob->discriminator_type.offset = 0; - } */ *offset += sizeof (UnionBlob); blob->discriminated = FALSE; From 86c1c589175cdf3cc2e5215ffb66da3bce6f2256 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 20 Feb 2009 11:05:53 -0500 Subject: [PATCH 217/692] typelib building: Compress 5 arguments for g_ir_node_build_typelib This makes it easier to add more over time without changing lots of unrelated code. --- girmodule.c | 9 +++- girnode.c | 136 ++++++++++++++++++---------------------------------- girnode.h | 21 ++++---- 3 files changed, 67 insertions(+), 99 deletions(-) diff --git a/girmodule.c b/girmodule.c index 5f5ae0928..107b21bb0 100644 --- a/girmodule.c +++ b/girmodule.c @@ -234,6 +234,7 @@ g_ir_module_build_typelib (GIrModule *module, for (e = module->entries, i = 0; e; e = e->next, i++) { + GIrTypelibBuild build; GIrNode *node = e->data; if (strchr (node->name, '.')) @@ -277,8 +278,12 @@ g_ir_module_build_typelib (GIrModule *module, entry->offset = offset; entry->name = write_string (node->name, strings, data, &offset2); - g_ir_node_build_typelib (node, module, modules, - strings, types, data, &offset, &offset2); + build.module = module; + build.modules = modules; + build.strings = strings; + build.types = types; + build.data = data; + g_ir_node_build_typelib (node, &build, &offset, &offset2); if (offset2 > old_offset + g_ir_node_get_full_size (node)) g_error ("left a hole of %d bytes\n", offset2 - old_offset - g_ir_node_get_full_size (node)); diff --git a/girnode.c b/girnode.c index 6400da937..0aafa44de 100644 --- a/girnode.c +++ b/girnode.c @@ -1287,11 +1287,7 @@ static void g_ir_node_build_members (GList **members, GIrNodeTypeId type, guint16 *count, - GIrModule *module, - GList *modules, - GHashTable *strings, - GHashTable *types, - guchar *data, + GIrTypelibBuild *build, guint32 *offset, guint32 *offset2) { @@ -1305,8 +1301,7 @@ g_ir_node_build_members (GList **members, if (member->type == type) { (*count)++; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, build, offset, offset2); *members = g_list_delete_link (*members, l); } l = next; @@ -1343,15 +1338,16 @@ g_ir_node_check_unhandled_members (GList **members, } void -g_ir_node_build_typelib (GIrNode *node, - GIrModule *module, - GList *modules, - GHashTable *strings, - GHashTable *types, - guchar *data, - guint32 *offset, - guint32 *offset2) +g_ir_node_build_typelib (GIrNode *node, + GIrTypelibBuild *build, + guint32 *offset, + guint32 *offset2) { + GIrModule *module = build->module; + GList *modules = build->modules; + GHashTable *strings = build->strings; + GHashTable *types = build->types; + guchar *data = build->data; GList *l; guint32 old_offset = *offset; guint32 old_offset2 = *offset2; @@ -1432,8 +1428,7 @@ g_ir_node_build_typelib (GIrNode *node, *offset2 += sizeof (ArrayTypeBlob); g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, - module, modules, strings, types, - data, &pos, offset2); + build, &pos, offset2); } break; @@ -1467,8 +1462,7 @@ g_ir_node_build_typelib (GIrNode *node, *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob); g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, - module, modules, strings, types, - data, &pos, offset2); + build, &pos, offset2); } break; @@ -1487,11 +1481,9 @@ g_ir_node_build_typelib (GIrNode *node, *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob)*2; g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, - module, modules, strings, types, - data, &pos, offset2); + build, &pos, offset2); g_ir_node_build_typelib ((GIrNode *)type->parameter_type2, - module, modules, strings, types, - data, &pos, offset2); + build, &pos, offset2); } break; @@ -1545,8 +1537,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->struct_offset = 0xFFFF; /* mark as unknown */ g_ir_node_build_typelib ((GIrNode *)field->type, - module, modules, strings, types, - data, offset, offset2); + build, offset, offset2); } break; @@ -1566,8 +1557,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->reserved = 0; g_ir_node_build_typelib ((GIrNode *)prop->type, - module, modules, strings, types, - data, offset, offset2); + build, offset, offset2); } break; @@ -1601,8 +1591,7 @@ g_ir_node_build_typelib (GIrNode *node, g_debug ("building function '%s'", function->symbol); g_ir_node_build_typelib ((GIrNode *)function->result->type, - module, modules, strings, types, - data, &signature, offset2); + build, &signature, offset2); blob2->may_return_null = function->result->allow_none; blob2->caller_owns_return_value = function->result->transfer; @@ -1616,9 +1605,7 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - g_ir_node_build_typelib (param, - module, modules, strings, types, - data, &signature, offset2); + g_ir_node_build_typelib (param, build, &signature, offset2); } } @@ -1645,8 +1632,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->signature = signature; g_ir_node_build_typelib ((GIrNode *)function->result->type, - module, modules, strings, types, - data, &signature, offset2); + build, &signature, offset2); blob2->may_return_null = function->result->allow_none; blob2->caller_owns_return_value = function->result->transfer; @@ -1660,9 +1646,7 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - g_ir_node_build_typelib (param, - module, modules, strings, types, - data, &signature, offset2); + g_ir_node_build_typelib (param, build, &signature, offset2); } } break; @@ -1697,8 +1681,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->signature = signature; g_ir_node_build_typelib ((GIrNode *)signal->result->type, - module, modules, strings, types, - data, &signature, offset2); + build, &signature, offset2); blob2->may_return_null = signal->result->allow_none; blob2->caller_owns_return_value = signal->result->transfer; @@ -1712,8 +1695,7 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - g_ir_node_build_typelib (param, module, modules, strings, types, - data, &signature, offset2); + g_ir_node_build_typelib (param, build, &signature, offset2); } } break; @@ -1744,8 +1726,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->signature = signature; g_ir_node_build_typelib ((GIrNode *)vfunc->result->type, - module, modules, strings, types, - data, &signature, offset2); + build, &signature, offset2); blob2->may_return_null = vfunc->result->allow_none; blob2->caller_owns_return_value = vfunc->result->transfer; @@ -1759,8 +1740,7 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - g_ir_node_build_typelib (param, module, modules, strings, - types, data, &signature, offset2); + g_ir_node_build_typelib (param, build, &signature, offset2); } } break; @@ -1789,8 +1769,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->closure = param->closure; blob->destroy = param->destroy; - g_ir_node_build_typelib ((GIrNode *)param->type, module, modules, - strings, types, data, offset, offset2); + g_ir_node_build_typelib ((GIrNode *)param->type, build, offset, offset2); } break; @@ -1829,12 +1808,10 @@ g_ir_node_build_typelib (GIrNode *node, members = g_list_copy (struct_->members); g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, - module, modules, strings, - types, data, offset, offset2); + build, offset, offset2); g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, - module, modules, strings, - types, data, offset, offset2); + build, offset, offset2); g_ir_node_check_unhandled_members (&members, node->type); @@ -1866,12 +1843,10 @@ g_ir_node_build_typelib (GIrNode *node, members = g_list_copy (boxed->members); g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, - module, modules, strings, - types, data, offset, offset2); + build, offset, offset2); g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, - module, modules, strings, - types, data, offset, offset2); + build, offset, offset2); g_ir_node_check_unhandled_members (&members, node->type); @@ -1916,8 +1891,7 @@ g_ir_node_build_typelib (GIrNode *node, *offset += 28; blob->discriminated = TRUE; g_ir_node_build_typelib ((GIrNode *)union_->discriminator_type, - module, modules, strings, types, - data, offset, offset2); + build, offset, offset2); } else { @@ -1929,12 +1903,10 @@ g_ir_node_build_typelib (GIrNode *node, members = g_list_copy (union_->members); g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, - module, modules, strings, - types, data, offset, offset2); + build, offset, offset2); g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_functions, - module, modules, strings, - types, data, offset, offset2); + build, offset, offset2); g_ir_node_check_unhandled_members (&members, node->type); @@ -1946,8 +1918,7 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNode *member = (GIrNode *)l->data; - g_ir_node_build_typelib (member, module, modules, strings, - types, data, offset, offset2); + g_ir_node_build_typelib (member, build, offset, offset2); } } } @@ -1991,8 +1962,7 @@ g_ir_node_build_typelib (GIrNode *node, GIrNode *value = (GIrNode *)l->data; blob->n_values++; - g_ir_node_build_typelib (value, module, modules, strings, types, - data, offset, offset2); + g_ir_node_build_typelib (value, build, offset, offset2); } } break; @@ -2039,33 +2009,27 @@ g_ir_node_build_typelib (GIrNode *node, *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, - module, modules, strings, - types, data, offset, offset2); + build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties, - module, modules, strings, - types, data, offset, offset2); + build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, - module, modules, strings, - types, data, offset, offset2); + build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals, - module, modules, strings, - types, data, offset, offset2); + build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs, - module, modules, strings, - types, data, offset, offset2); + build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants, - module, modules, strings, - types, data, offset, offset2); + build, offset, offset2); g_ir_node_check_unhandled_members (&members, node->type); @@ -2104,28 +2068,23 @@ g_ir_node_build_typelib (GIrNode *node, *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties, - module, modules, strings, - types, data, offset, offset2); + build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, - module, modules, strings, - types, data, offset, offset2); + build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals, - module, modules, strings, - types, data, offset, offset2); + build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs, - module, modules, strings, - types, data, offset, offset2); + build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants, - module, modules, strings, - types, data, offset, offset2); + build, offset, offset2); g_ir_node_check_unhandled_members (&members, node->type); @@ -2251,8 +2210,7 @@ g_ir_node_build_typelib (GIrNode *node, } *offset2 += ALIGN_VALUE (blob->size, 4); - g_ir_node_build_typelib ((GIrNode *)constant->type, module, modules, - strings, types, data, &pos, offset2); + g_ir_node_build_typelib ((GIrNode *)constant->type, build, &pos, offset2); } break; default: diff --git a/girnode.h b/girnode.h index fad679911..33848db6f 100644 --- a/girnode.h +++ b/girnode.h @@ -27,6 +27,7 @@ G_BEGIN_DECLS +typedef struct _GIrTypelibBuild GIrTypelibBuild; typedef struct _GIrNode GIrNode; typedef struct _GIrNodeFunction GIrNodeFunction; typedef struct _GIrNodeParam GIrNodeParam; @@ -45,6 +46,14 @@ typedef struct _GIrNodeErrorDomain GIrNodeErrorDomain; typedef struct _GIrNodeXRef GIrNodeXRef; typedef struct _GIrNodeUnion GIrNodeUnion; +struct _GIrTypelibBuild { + GIrModule *module; + GList *modules; + GHashTable *strings; + GHashTable *types; + guchar *data; +}; + typedef enum { G_IR_NODE_INVALID = 0, @@ -340,14 +349,10 @@ GIrNode * g_ir_node_new (GIrNodeTypeId type); void g_ir_node_free (GIrNode *node); guint32 g_ir_node_get_size (GIrNode *node); guint32 g_ir_node_get_full_size (GIrNode *node); -void g_ir_node_build_typelib (GIrNode *node, - GIrModule *module, - GList *modules, - GHashTable *strings, - GHashTable *types, - guchar *data, - guint32 *offset, - guint32 *offset2); +void g_ir_node_build_typelib (GIrNode *node, + GIrTypelibBuild *build, + guint32 *offset, + guint32 *offset2); int g_ir_node_cmp (GIrNode *node, GIrNode *other); gboolean g_ir_node_can_have_member (GIrNode *node); From f13354f9ea07092686f14ac1daf59175adaf8f2c Mon Sep 17 00:00:00 2001 From: Johan Bilien Date: Tue, 24 Feb 2009 15:19:07 +0000 Subject: [PATCH 218/692] =?UTF-8?q?Bug=20572965=20=E2=80=93=20Allow=20gene?= =?UTF-8?q?ric=20marshaller=20to=20be=20called=20without=20parameters?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit girepository/ginvoke.c: handle the case where n_param_values == 0. tests/invoke/genericmarshaller.c: add a test case for this. --- ginvoke.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/ginvoke.c b/ginvoke.c index e83a8200a..70d81f8e9 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -407,18 +407,26 @@ gi_cclosure_marshal_generic (GClosure *closure, atypes = g_alloca (sizeof (ffi_type *) * n_args); args = g_alloca (sizeof (gpointer) * n_args); - if (G_CCLOSURE_SWAP_DATA (closure)) + if (n_param_values > 0) { - atypes[n_args-1] = value_to_ffi_type (param_values + 0, - &args[n_args-1]); - atypes[0] = &ffi_type_pointer; - args[0] = &closure->data; + if (G_CCLOSURE_SWAP_DATA (closure)) + { + atypes[n_args-1] = value_to_ffi_type (param_values + 0, + &args[n_args-1]); + atypes[0] = &ffi_type_pointer; + args[0] = &closure->data; + } + else + { + atypes[0] = value_to_ffi_type (param_values + 0, &args[0]); + atypes[n_args-1] = &ffi_type_pointer; + args[n_args-1] = &closure->data; + } } else { - atypes[0] = value_to_ffi_type (param_values + 0, &args[0]); - atypes[n_args-1] = &ffi_type_pointer; - args[n_args-1] = &closure->data; + atypes[0] = &ffi_type_pointer; + args[0] = &closure->data; } for (i = 1; i < n_args - 1; i++) From 9dbb0bf80fffdba8f72c9f708f17e8505b52e98b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 20 Feb 2009 17:34:20 -0500 Subject: [PATCH 219/692] Bug 572434 - Associate interfaces with their C structures Similar to GObject class structs, we pair up GInterfaces with their C structures. Also, move some GLib-specific things into glibast.py, and make the naming more generic. --- ginfo.c | 40 +++++++++++++++++++++++++++++----------- girepository.h | 4 +++- girnode.c | 19 ++++++++++++------- girnode.h | 4 ++-- girparser.c | 15 +++++++++------ gtypelib.c | 6 +++--- gtypelib.h | 9 ++++++--- 7 files changed, 64 insertions(+), 33 deletions(-) diff --git a/ginfo.c b/ginfo.c index 7ecfe6337..1c34ee2bd 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1182,22 +1182,22 @@ g_struct_info_get_alignment (GIStructInfo *info) } /** - * g_struct_info_is_class_struct: + * g_struct_info_is_gtype_struct: * @info: GIStructInfo * * Return true if this structure represents the "class structure" for some - * GObject. This function is mainly useful to hide this kind of structure - * from public APIs. + * #GObject or #GInterface. This function is mainly useful to hide this kind of structure + * from generated public APIs. * - * Returns: TRUE if it's a class struct, otherwise FALSE + * Returns: %TRUE if this is a class struct, %FALSE otherwise */ gboolean -g_struct_info_is_class_struct (GIStructInfo *info) +g_struct_info_is_gtype_struct (GIStructInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset]; - return blob->is_class_struct; + return blob->is_gtype_struct; } gint @@ -1495,10 +1495,10 @@ g_object_info_get_constant (GIObjectInfo *info, * g_object_info_get_class_struct: * @info: A #GIObjectInfo to query * - * Every GObject has two structures; an instance structure and a class + * Every #GObject has two structures; an instance structure and a class * structure. This function returns the metadata for the class structure. * - * Returns: a GIStrucTInfo for the class struct or NULL if none found. + * Returns: a #GIStructInfo for the class struct or %NULL if none found. */ GIStructInfo * g_object_info_get_class_struct (GIObjectInfo *info) @@ -1506,9 +1506,9 @@ g_object_info_get_class_struct (GIObjectInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; - if (blob->class_struct) + if (blob->gtype_struct) return (GIStructInfo *) g_info_from_entry (base->repository, - base->typelib, blob->class_struct); + base->typelib, blob->gtype_struct); else return NULL; } @@ -1691,8 +1691,26 @@ g_interface_info_get_constant (GIInterfaceInfo *info, base->typelib, offset); } +/** + * g_interface_info_get_iface_struct: + * @info: A #GIInterfaceInfo to query + * + * Returns the layout C structure associated with this #GInterface. + * + * Returns: A #GIStructInfo for the class struct or %NULL if none found. + */ +GIStructInfo * +g_interface_info_get_iface_struct (GIInterfaceInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; - + if (blob->gtype_struct) + return (GIStructInfo *) g_info_from_entry (base->repository, + base->typelib, blob->gtype_struct); + else + return NULL; +} /* GIPropertyInfo functions */ GParamFlags diff --git a/girepository.h b/girepository.h index 3508f4ddb..61a911624 100644 --- a/girepository.h +++ b/girepository.h @@ -417,7 +417,7 @@ GIFunctionInfo * g_struct_info_find_method (GIStructInfo *info, const gchar *name); gsize g_struct_info_get_size (GIStructInfo *info); gsize g_struct_info_get_alignment (GIStructInfo *info); -gboolean g_struct_info_is_class_struct (GIStructInfo *info); +gboolean g_struct_info_is_gtype_struct (GIStructInfo *info); /* GIRegisteredTypeInfo */ @@ -487,6 +487,8 @@ gint g_interface_info_get_n_constants (GIInterfaceInfo *in GIConstantInfo * g_interface_info_get_constant (GIInterfaceInfo *info, gint n); +GIStructInfo * g_interface_info_get_iface_struct (GIInterfaceInfo *info); + /* GIPropertyInfo */ diff --git a/girnode.c b/girnode.c index 0aafa44de..7863c2548 100644 --- a/girnode.c +++ b/girnode.c @@ -286,7 +286,8 @@ g_ir_node_free (GIrNode *node) g_free (iface->gtype_name); g_free (iface->gtype_init); - g_free (iface->class_struct); + + g_free (iface->glib_type_struct); g_free (iface->parent); for (l = iface->interfaces; l; l = l->next) @@ -652,8 +653,8 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size = sizeof(ObjectBlob); if (iface->parent) size += ALIGN_VALUE (strlen (iface->parent) + 1, 4); - if (iface->class_struct) - size += ALIGN_VALUE (strlen (iface->class_struct) + 1, 4); + if (iface->glib_type_struct) + size += ALIGN_VALUE (strlen (iface->glib_type_struct) + 1, 4); size += ALIGN_VALUE (strlen (node->name) + 1, 4); size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4); if (iface->gtype_init) @@ -1781,7 +1782,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->blob_type = BLOB_TYPE_STRUCT; blob->deprecated = struct_->deprecated; - blob->is_class_struct = struct_->is_gclass_struct; + blob->is_gtype_struct = struct_->is_gtype_struct; blob->reserved = 0; blob->name = write_string (node->name, strings, data, offset2); blob->alignment = struct_->alignment; @@ -1984,10 +1985,10 @@ g_ir_node_build_typelib (GIrNode *node, blob->parent = find_entry (module, modules, object->parent); else blob->parent = 0; - if (object->class_struct) - blob->class_struct = find_entry (module, modules, object->class_struct); + if (object->glib_type_struct) + blob->gtype_struct = find_entry (module, modules, object->glib_type_struct); else - blob->class_struct = 0; + blob->gtype_struct = 0; blob->n_interfaces = 0; blob->n_fields = 0; @@ -2049,6 +2050,10 @@ g_ir_node_build_typelib (GIrNode *node, 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); + if (iface->glib_type_struct) + blob->gtype_struct = find_entry (module, modules, iface->glib_type_struct); + else + blob->gtype_struct = 0; blob->n_prerequisites = 0; blob->n_properties = 0; blob->n_methods = 0; diff --git a/girnode.h b/girnode.h index 33848db6f..7ea8a32a5 100644 --- a/girnode.h +++ b/girnode.h @@ -237,7 +237,7 @@ struct _GIrNodeInterface gchar *gtype_init; gchar *parent; - gchar *class_struct; /* Only applies to classes */ + gchar *glib_type_struct; GList *interfaces; GList *prerequisites; @@ -302,7 +302,7 @@ struct _GIrNodeStruct gboolean deprecated; gboolean disguised; - gboolean is_gclass_struct; + gboolean is_gtype_struct; gchar *gtype_name; gchar *gtype_init; diff --git a/girparser.c b/girparser.c index 795658e8a..e08b3fcd0 100644 --- a/girparser.c +++ b/girparser.c @@ -1482,10 +1482,12 @@ start_interface (GMarkupParseContext *context, const gchar *typename; const gchar *typeinit; const gchar *deprecated; + const gchar *glib_type_struct; name = find_attribute ("name", attribute_names, attribute_values); typename = find_attribute ("glib:type-name", attribute_names, attribute_values); typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); if (name == NULL) @@ -1502,6 +1504,7 @@ start_interface (GMarkupParseContext *context, ((GIrNode *)iface)->name = g_strdup (name); iface->gtype_name = g_strdup (typename); iface->gtype_init = g_strdup (typeinit); + iface->glib_type_struct = g_strdup (glib_type_struct); if (deprecated) iface->deprecated = TRUE; else @@ -1533,7 +1536,7 @@ start_class (GMarkupParseContext *context, { const gchar *name; const gchar *parent; - const gchar *class_struct; + const gchar *glib_type_struct; const gchar *typename; const gchar *typeinit; const gchar *deprecated; @@ -1541,7 +1544,7 @@ start_class (GMarkupParseContext *context, name = find_attribute ("name", attribute_names, attribute_values); parent = find_attribute ("parent", attribute_names, attribute_values); - class_struct = find_attribute ("glib:class-struct", attribute_names, attribute_values); + glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values); typename = find_attribute ("glib:type-name", attribute_names, attribute_values); typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); @@ -1562,7 +1565,7 @@ start_class (GMarkupParseContext *context, iface->gtype_name = g_strdup (typename); iface->gtype_init = g_strdup (typeinit); iface->parent = g_strdup (parent); - iface->class_struct = g_strdup (class_struct); + iface->glib_type_struct = g_strdup (glib_type_struct); if (deprecated) iface->deprecated = TRUE; else @@ -2128,7 +2131,7 @@ start_struct (GMarkupParseContext *context, const gchar *disguised; const gchar *gtype_name; const gchar *gtype_init; - const gchar *gclass_struct; + const gchar *gtype_struct; GIrNodeStruct *struct_; name = find_attribute ("name", attribute_names, attribute_values); @@ -2136,7 +2139,7 @@ start_struct (GMarkupParseContext *context, disguised = find_attribute ("disguised", attribute_names, attribute_values); gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values); gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values); - gclass_struct = find_attribute ("glib:is-class-struct-for", attribute_names, attribute_values); + gtype_struct = find_attribute ("glib:is-gtype-struct-for", attribute_names, attribute_values); if (name == NULL && ctx->node_stack == NULL) { @@ -2165,7 +2168,7 @@ start_struct (GMarkupParseContext *context, if (disguised && strcmp (disguised, "1") == 0) struct_->disguised = TRUE; - struct_->is_gclass_struct = gclass_struct != NULL; + struct_->is_gtype_struct = gtype_struct != NULL; struct_->gtype_name = g_strdup (gtype_name); struct_->gtype_init = g_strdup (gtype_init); diff --git a/gtypelib.c b/gtypelib.c index 673436a04..6ff00bfbf 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -183,7 +183,7 @@ g_typelib_check_sanity (void) CHECK_SIZE (SignalBlob, 16); CHECK_SIZE (VFuncBlob, 20); CHECK_SIZE (ObjectBlob, 44); - CHECK_SIZE (InterfaceBlob, 36); + CHECK_SIZE (InterfaceBlob, 40); CHECK_SIZE (ConstantBlob, 24); CHECK_SIZE (AnnotationBlob, 12); CHECK_SIZE (UnionBlob, 40); @@ -1458,11 +1458,11 @@ validate_object_blob (ValidateContext *ctx, } } - if (blob->class_struct != 0) + if (blob->gtype_struct != 0) { DirEntry *entry; - entry = get_dir_entry_checked (typelib, blob->class_struct, error); + entry = get_dir_entry_checked (typelib, blob->gtype_struct, error); if (!entry) return FALSE; if (entry->blob_type != BLOB_TYPE_STRUCT && entry->local) diff --git a/gtypelib.h b/gtypelib.h index 9a78873e7..7a2838f18 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -72,6 +72,7 @@ G_BEGIN_DECLS TYPELIB HISTORY ----- Version 1.0 +- Rename class_struct to gtype_struct, add to interfaces Changes since 0.9: - Add padding to structures @@ -651,7 +652,7 @@ typedef struct { * @deprecated: Whether this structure is deprecated * @unregistered: If this is set, the type is not registered with GType. * @alignment: The byte boundary that the struct is aligned to in memory - * @is_class_struct: Whether this structure is the "class structure" for a GObject + * @is_gtype_struct: Whether this structure is the class or interface layout for a GObject * @size: The size of the struct in bytes. * @gtype_name: String name of the associated #GType * @gtype_init: String naming the symbol which gets the runtime #GType @@ -666,7 +667,7 @@ typedef struct { guint16 deprecated : 1; guint16 unregistered : 1; - guint16 is_class_struct : 1; + guint16 is_gtype_struct : 1; guint16 alignment : 6; guint16 reserved : 7; @@ -900,7 +901,7 @@ typedef struct { guint32 gtype_init; guint16 parent; - guint16 class_struct; + guint16 gtype_struct; guint16 n_interfaces; guint16 n_fields; @@ -929,6 +930,7 @@ typedef struct { /** * InterfaceBlob: + * @gtype_struct: Name of the interface "class" C structure * @n_prerequisites: Number of prerequisites * @n_properties: Number of properties * @n_methods: Number of methods @@ -952,6 +954,7 @@ typedef struct { guint32 gtype_name; guint32 gtype_init; + guint16 gtype_struct; guint16 n_prerequisites; guint16 n_properties; From 86587133cdfd728ad013673e5989f7911cc08aa9 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 27 Feb 2009 19:11:26 -0500 Subject: [PATCH 220/692] Add a parent parmeter to g_ir_node_build_typelib This will be useful for later changes which need to inspect the parent. --- girmodule.c | 2 +- girnode.c | 76 +++++++++++++++++++++++++++-------------------------- girnode.h | 1 + 3 files changed, 41 insertions(+), 38 deletions(-) diff --git a/girmodule.c b/girmodule.c index 107b21bb0..5abd31f82 100644 --- a/girmodule.c +++ b/girmodule.c @@ -283,7 +283,7 @@ g_ir_module_build_typelib (GIrModule *module, build.strings = strings; build.types = types; build.data = data; - g_ir_node_build_typelib (node, &build, &offset, &offset2); + g_ir_node_build_typelib (node, NULL, &build, &offset, &offset2); if (offset2 > old_offset + g_ir_node_get_full_size (node)) g_error ("left a hole of %d bytes\n", offset2 - old_offset - g_ir_node_get_full_size (node)); diff --git a/girnode.c b/girnode.c index 7863c2548..fb96d8ddc 100644 --- a/girnode.c +++ b/girnode.c @@ -1288,6 +1288,7 @@ static void g_ir_node_build_members (GList **members, GIrNodeTypeId type, guint16 *count, + GIrNode *parent, GIrTypelibBuild *build, guint32 *offset, guint32 *offset2) @@ -1302,7 +1303,7 @@ g_ir_node_build_members (GList **members, if (member->type == type) { (*count)++; - g_ir_node_build_typelib (member, build, offset, offset2); + g_ir_node_build_typelib (member, parent, build, offset, offset2); *members = g_list_delete_link (*members, l); } l = next; @@ -1340,6 +1341,7 @@ g_ir_node_check_unhandled_members (GList **members, void g_ir_node_build_typelib (GIrNode *node, + GIrNode *parent, GIrTypelibBuild *build, guint32 *offset, guint32 *offset2) @@ -1428,8 +1430,8 @@ g_ir_node_build_typelib (GIrNode *node, pos = *offset2 + G_STRUCT_OFFSET (ArrayTypeBlob, type); *offset2 += sizeof (ArrayTypeBlob); - g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, - build, &pos, offset2); + g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, + node, build, &pos, offset2); } break; @@ -1463,7 +1465,7 @@ g_ir_node_build_typelib (GIrNode *node, *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob); g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, - build, &pos, offset2); + node, build, &pos, offset2); } break; @@ -1482,9 +1484,9 @@ g_ir_node_build_typelib (GIrNode *node, *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob)*2; g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, - build, &pos, offset2); + node, build, &pos, offset2); g_ir_node_build_typelib ((GIrNode *)type->parameter_type2, - build, &pos, offset2); + node, build, &pos, offset2); } break; @@ -1538,7 +1540,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->struct_offset = 0xFFFF; /* mark as unknown */ g_ir_node_build_typelib ((GIrNode *)field->type, - build, offset, offset2); + node, build, offset, offset2); } break; @@ -1558,7 +1560,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->reserved = 0; g_ir_node_build_typelib ((GIrNode *)prop->type, - build, offset, offset2); + node, build, offset, offset2); } break; @@ -1592,7 +1594,7 @@ g_ir_node_build_typelib (GIrNode *node, g_debug ("building function '%s'", function->symbol); g_ir_node_build_typelib ((GIrNode *)function->result->type, - build, &signature, offset2); + node, build, &signature, offset2); blob2->may_return_null = function->result->allow_none; blob2->caller_owns_return_value = function->result->transfer; @@ -1606,7 +1608,7 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - g_ir_node_build_typelib (param, build, &signature, offset2); + g_ir_node_build_typelib (param, node, build, &signature, offset2); } } @@ -1633,7 +1635,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->signature = signature; g_ir_node_build_typelib ((GIrNode *)function->result->type, - build, &signature, offset2); + node, build, &signature, offset2); blob2->may_return_null = function->result->allow_none; blob2->caller_owns_return_value = function->result->transfer; @@ -1647,7 +1649,7 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - g_ir_node_build_typelib (param, build, &signature, offset2); + g_ir_node_build_typelib (param, node, build, &signature, offset2); } } break; @@ -1682,7 +1684,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->signature = signature; g_ir_node_build_typelib ((GIrNode *)signal->result->type, - build, &signature, offset2); + node, build, &signature, offset2); blob2->may_return_null = signal->result->allow_none; blob2->caller_owns_return_value = signal->result->transfer; @@ -1696,7 +1698,7 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - g_ir_node_build_typelib (param, build, &signature, offset2); + g_ir_node_build_typelib (param, node, build, &signature, offset2); } } break; @@ -1727,7 +1729,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->signature = signature; g_ir_node_build_typelib ((GIrNode *)vfunc->result->type, - build, &signature, offset2); + node, build, &signature, offset2); blob2->may_return_null = vfunc->result->allow_none; blob2->caller_owns_return_value = vfunc->result->transfer; @@ -1741,7 +1743,7 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - g_ir_node_build_typelib (param, build, &signature, offset2); + g_ir_node_build_typelib (param, node, build, &signature, offset2); } } break; @@ -1770,7 +1772,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->closure = param->closure; blob->destroy = param->destroy; - g_ir_node_build_typelib ((GIrNode *)param->type, build, offset, offset2); + g_ir_node_build_typelib ((GIrNode *)param->type, node, build, offset, offset2); } break; @@ -1809,10 +1811,10 @@ g_ir_node_build_typelib (GIrNode *node, members = g_list_copy (struct_->members); g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, - build, offset, offset2); + node, build, offset, offset2); g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, - build, offset, offset2); + node, build, offset, offset2); g_ir_node_check_unhandled_members (&members, node->type); @@ -1844,10 +1846,10 @@ g_ir_node_build_typelib (GIrNode *node, members = g_list_copy (boxed->members); g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, - build, offset, offset2); + node, build, offset, offset2); g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, - build, offset, offset2); + node, build, offset, offset2); g_ir_node_check_unhandled_members (&members, node->type); @@ -1904,10 +1906,10 @@ g_ir_node_build_typelib (GIrNode *node, members = g_list_copy (union_->members); g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, - build, offset, offset2); + node, build, offset, offset2); g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_functions, - build, offset, offset2); + node, build, offset, offset2); g_ir_node_check_unhandled_members (&members, node->type); @@ -1919,7 +1921,7 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNode *member = (GIrNode *)l->data; - g_ir_node_build_typelib (member, build, offset, offset2); + g_ir_node_build_typelib (member, node, build, offset, offset2); } } } @@ -1963,7 +1965,7 @@ g_ir_node_build_typelib (GIrNode *node, GIrNode *value = (GIrNode *)l->data; blob->n_values++; - g_ir_node_build_typelib (value, build, offset, offset2); + g_ir_node_build_typelib (value, node, build, offset, offset2); } } break; @@ -2010,27 +2012,27 @@ g_ir_node_build_typelib (GIrNode *node, *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, - build, offset, offset2); + node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties, - build, offset, offset2); + node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, - build, offset, offset2); + node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals, - build, offset, offset2); + node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs, - build, offset, offset2); + node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants, - build, offset, offset2); + node, build, offset, offset2); g_ir_node_check_unhandled_members (&members, node->type); @@ -2073,23 +2075,23 @@ g_ir_node_build_typelib (GIrNode *node, *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties, - build, offset, offset2); + node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, - build, offset, offset2); + node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals, - build, offset, offset2); + node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs, - build, offset, offset2); + node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants, - build, offset, offset2); + node, build, offset, offset2); g_ir_node_check_unhandled_members (&members, node->type); @@ -2215,7 +2217,7 @@ g_ir_node_build_typelib (GIrNode *node, } *offset2 += ALIGN_VALUE (blob->size, 4); - g_ir_node_build_typelib ((GIrNode *)constant->type, build, &pos, offset2); + g_ir_node_build_typelib ((GIrNode *)constant->type, node, build, &pos, offset2); } break; default: diff --git a/girnode.h b/girnode.h index 7ea8a32a5..45c2bb029 100644 --- a/girnode.h +++ b/girnode.h @@ -350,6 +350,7 @@ void g_ir_node_free (GIrNode *node); guint32 g_ir_node_get_size (GIrNode *node); guint32 g_ir_node_get_full_size (GIrNode *node); void g_ir_node_build_typelib (GIrNode *node, + GIrNode *parent, GIrTypelibBuild *build, guint32 *offset, guint32 *offset2); From cd845500a5f07b62c1dde03a0b0853d2afde3853 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 19 Feb 2009 21:48:51 -0500 Subject: [PATCH 221/692] Bug 571548 - Generic attributes We now support an extensible mechanism where arbitrary key-value pairs may be associated with almost all items, including objects, methods, and properties. These attributes appear in both the .gir and the .typelib. --- ginfo.c | 149 +++++++++++++++++++++++++++++++++++-------------- girepository.h | 14 ++++- girmodule.c | 88 +++++++++++++++++++++++++++-- girnode.c | 38 ++++++++++++- girnode.h | 7 +++ girparser.c | 52 ++++++++++++++++- gtypelib.c | 22 ++++---- gtypelib.h | 31 +++++----- 8 files changed, 327 insertions(+), 74 deletions(-) diff --git a/ginfo.c b/ginfo.c index 1c34ee2bd..fcc5f098f 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1,6 +1,7 @@ /* GObject introspection: Repository implementation * * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -402,65 +403,131 @@ g_base_info_is_deprecated (GIBaseInfo *info) return FALSE; } -static int -cmp_annotation (const void *av, - const void *bv) +/** + * g_base_info_get_attribute: + * @info: A #GIBaseInfo + * @name: A freeform string naming an attribute + * + * Retrieve an arbitrary attribute associated with this node. + * + * Return value: The value of the attribute, or %NULL if no such attribute exists + */ +const gchar * +g_base_info_get_attribute (GIBaseInfo *info, + const gchar *name) { - const AnnotationBlob *a = av; - const AnnotationBlob *b = bv; - - if (b->offset < a->offset) - return -1; + GIAttributeIter iter = { 0, }; + gchar *curname, *curvalue; + while (g_base_info_iterate_attributes (info, &iter, &curname, &curvalue)) + { + if (strcmp (name, curname) == 0) + return (const gchar*) curvalue; + } - if (b->offset > a->offset) - return 1; - - return 0; + return NULL; } -const gchar * -g_base_info_get_annotation (GIBaseInfo *info, - const gchar *name) +static int +cmp_attribute (const void *av, + const void *bv) +{ + const AttributeBlob *a = av; + const AttributeBlob *b = bv; + + if (a->offset < b->offset) + return -1; + else if (a->offset == b->offset) + return 0; + else + return 1; +} + +static AttributeBlob * +find_first_attribute (GIBaseInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; Header *header = (Header *)base->typelib->data; - AnnotationBlob blob, *first, *after, *res, *next; - const gchar *rname; + AttributeBlob blob, *first, *res, *previous; blob.offset = base->offset; - first = (AnnotationBlob *) &base->typelib->data[header->annotations]; - after = (AnnotationBlob *) &base->typelib->data[header->annotations + - header->n_annotations * header->annotation_blob_size]; + first = (AttributeBlob *) &base->typelib->data[header->attributes]; + + res = bsearch (&blob, first, header->n_attributes, + header->attribute_blob_size, cmp_attribute); - res = bsearch (&blob, first, header->n_annotations, - header->annotation_blob_size, cmp_annotation); - if (res == NULL) return NULL; - next = res; - do + previous = res - 1; + while (previous >= first && previous->offset == base->offset) { - res = next; - next = res -= header->annotation_blob_size; + res = previous; + previous = res - 1; } - while (next >= first && next->offset == base->offset); - - next = res; - do - { - res = next; - - rname = g_typelib_get_string (base->typelib, res->name); - if (strcmp (name, rname) == 0) - return g_typelib_get_string (base->typelib, res->value); - next = res += header->annotation_blob_size; - } - while (next < after && next->offset == base->offset); + return res; +} - return NULL; +/** + * g_base_info_iterate_attributes: + * @info: A #GIBaseInfo + * @iter: A #GIAttributeIter structure, must be initialized; see below + * @name: (out) (transfer none): Returned name, must not be freed + * @value: (out) (transfer none): Returned name, must not be freed + * + * Iterate over all attributes associated with this node. The iterator + * structure is typically stack allocated, and must have its first + * member initialized to %NULL. + * + * Both the @name and @value should be treated as constants + * and must not be freed. + * + * + * Iterating over attributes + * + * void + * print_attributes (GIBaseInfo *info) + * { + * GIAttributeIter iter = { 0, }; + * char *name; + * char *value; + * while (g_base_info_iterate_attributes (info, &iter, &name, &value)) + * { + * g_print ("attribute name: %s value: %s", name, value); + * } + * } + * + * + * + * Return value: %TRUE if there are more attributes, %FALSE otherwise + */ +gboolean +g_base_info_iterate_attributes (GIBaseInfo *info, + GIAttributeIter *iter, + gchar **name, + gchar **value) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->typelib->data; + AttributeBlob *next, *after; + + after = (AttributeBlob *) &base->typelib->data[header->attributes + + header->n_attributes * header->attribute_blob_size]; + + if (iter->data != NULL) + next = (AttributeBlob *) iter->data; + else + next = find_first_attribute (info); + + if (next == NULL || next->offset != base->offset || next >= after) + return FALSE; + + *name = (gchar*) g_typelib_get_string (base->typelib, next->name); + *value = (gchar*) g_typelib_get_string (base->typelib, next->value); + iter->data = next + 1; + + return TRUE; } GIBaseInfo * diff --git a/girepository.h b/girepository.h index 61a911624..4059adc0e 100644 --- a/girepository.h +++ b/girepository.h @@ -1,6 +1,7 @@ /* GObject introspection: Repository * * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -179,14 +180,25 @@ typedef enum /* GIBaseInfo */ +typedef struct { + gpointer data; + gpointer data2; + gpointer data3; + gpointer data4; +} GIAttributeIter; + GIBaseInfo * g_base_info_ref (GIBaseInfo *info); void g_base_info_unref (GIBaseInfo *info); GIInfoType g_base_info_get_type (GIBaseInfo *info); const gchar * g_base_info_get_name (GIBaseInfo *info); const gchar * g_base_info_get_namespace (GIBaseInfo *info); gboolean g_base_info_is_deprecated (GIBaseInfo *info); -const gchar * g_base_info_get_annotation (GIBaseInfo *info, +const gchar * g_base_info_get_attribute (GIBaseInfo *info, const gchar *name); +gboolean g_base_info_iterate_attributes (GIBaseInfo *info, + GIAttributeIter *iterator, + char **name, + char **value); GIBaseInfo * g_base_info_get_container (GIBaseInfo *info); GTypelib * g_base_info_get_typelib (GIBaseInfo *info); diff --git a/girmodule.c b/girmodule.c index 5abd31f82..96ee9ce91 100644 --- a/girmodule.c +++ b/girmodule.c @@ -109,6 +109,53 @@ g_ir_module_add_include_module (GIrModule *module, module); } +struct AttributeWriteData +{ + guint count; + guchar *databuf; + GIrNode *node; + GHashTable *strings; + guint32 *offset; + guint32 *offset2; +}; + +static void +write_attribute (gpointer key, gpointer value, gpointer datap) +{ + struct AttributeWriteData *data = datap; + guint32 old_offset = *(data->offset); + AttributeBlob *blob = (AttributeBlob*)&(data->databuf[old_offset]); + + *(data->offset) += sizeof (AttributeBlob); + + blob->offset = data->node->offset; + blob->name = write_string ((const char*) key, data->strings, data->databuf, data->offset2); + blob->value = write_string ((const char*) value, data->strings, data->databuf, data->offset2); + + data->count++; +} + +static guint +write_attributes (GIrModule *module, + GIrNode *node, + GHashTable *strings, + guchar *data, + guint32 *offset, + guint32 *offset2) +{ + struct AttributeWriteData wdata; + wdata.count = 0; + wdata.databuf = data; + wdata.node = node; + wdata.offset = offset; + wdata.offset2 = offset2; + wdata.strings = strings; + + g_hash_table_foreach (node->attributes, write_attribute, &wdata); + + return wdata.count; +} + GTypelib * g_ir_module_build_typelib (GIrModule *module, GList *modules) @@ -126,6 +173,7 @@ g_ir_module_build_typelib (GIrModule *module, guint32 size, offset, offset2, old_offset; GHashTable *strings; GHashTable *types; + GList *offset_ordered_nodes; char *dependencies; guchar *data; @@ -158,6 +206,7 @@ g_ir_module_build_typelib (GIrModule *module, _g_irnode_init_stats (); strings = g_hash_table_new (g_str_hash, g_str_equal); types = g_hash_table_new (g_str_hash, g_str_equal); + offset_ordered_nodes = NULL; n_entries = g_list_length (module->entries); g_message ("%d entries (%d local), %d dependencies\n", n_entries, n_local_entries, @@ -173,6 +222,10 @@ g_ir_module_build_typelib (GIrModule *module, GIrNode *node = e->data; size += g_ir_node_get_full_size (node); + size += g_ir_node_get_attribute_size (node); + + /* Also reset the offset here */ + node->offset = 0; } /* Adjust size for strings allocated in header below specially */ @@ -195,8 +248,8 @@ g_ir_module_build_typelib (GIrModule *module, 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->n_attributes = 0; + header->attributes = 0; /* filled in later */ if (dependencies != NULL) header->dependencies = write_string (dependencies, strings, data, &header_size); else @@ -219,7 +272,7 @@ g_ir_module_build_typelib (GIrModule *module, header->value_blob_size = sizeof (ValueBlob); header->constant_blob_size = sizeof (ConstantBlob); header->error_domain_blob_size = sizeof (ErrorDomainBlob); - header->annotation_blob_size = sizeof (AnnotationBlob); + header->attribute_blob_size = sizeof (AttributeBlob); header->signature_blob_size = sizeof (SignatureBlob); header->enum_blob_size = sizeof (EnumBlob); header->struct_blob_size = sizeof (StructBlob); @@ -245,10 +298,17 @@ g_ir_module_build_typelib (GIrModule *module, /* we picked up implicit xref nodes, start over */ if (i == n_entries) { + GList *link; g_message ("Found implicit cross references, starting over"); g_hash_table_destroy (strings); g_hash_table_destroy (types); + + /* Reset the cached offsets */ + for (link = offset_ordered_nodes; link; link = link->next) + ((GIrNode *) link->data)->offset = 0; + + g_list_free (offset_ordered_nodes); strings = NULL; g_free (data); @@ -282,9 +342,14 @@ g_ir_module_build_typelib (GIrModule *module, build.modules = modules; build.strings = strings; build.types = types; + build.offset_ordered_nodes = offset_ordered_nodes; + build.n_attributes = header->n_attributes; build.data = data; g_ir_node_build_typelib (node, NULL, &build, &offset, &offset2); + offset_ordered_nodes = build.offset_ordered_nodes; + header->n_attributes = build.n_attributes; + if (offset2 > old_offset + g_ir_node_get_full_size (node)) g_error ("left a hole of %d bytes\n", offset2 - old_offset - g_ir_node_get_full_size (node)); } @@ -292,9 +357,23 @@ g_ir_module_build_typelib (GIrModule *module, entry++; } + offset_ordered_nodes = g_list_reverse (offset_ordered_nodes); + + g_message ("header: %d entries, %d attributes", header->n_entries, header->n_attributes); + _g_irnode_dump_stats (); - header->annotations = offset2; + /* Write attributes after the blobs */ + offset = offset2; + header->attributes = offset; + offset2 = offset + header->n_attributes * header->attribute_blob_size; + + for (e = offset_ordered_nodes; e; e = e->next) + { + GIrNode *node = e->data; + + write_attributes (module, node, strings, data, &offset, &offset2); + } g_message ("reallocating to %d bytes", offset2); @@ -305,6 +384,7 @@ g_ir_module_build_typelib (GIrModule *module, g_hash_table_destroy (strings); g_hash_table_destroy (types); + g_list_free (offset_ordered_nodes); return typelib; } diff --git a/girnode.c b/girnode.c index fb96d8ddc..22c0aee01 100644 --- a/girnode.c +++ b/girnode.c @@ -1,6 +1,7 @@ /* GObject introspection: Typelib creation * * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -184,6 +185,9 @@ g_ir_node_new (GIrNodeTypeId type) } node->type = type; + node->offset = 0; + node->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_free); return node; } @@ -400,6 +404,8 @@ g_ir_node_free (GIrNode *node) break; } + g_hash_table_destroy (node->attributes); + g_free (node); } @@ -540,6 +546,18 @@ g_ir_node_get_size (GIrNode *node) return size; } +static void +add_attribute_size (gpointer key, gpointer value, gpointer data) +{ + const gchar *key_str = key; + const gchar *value_str = value; + gint *size_p = data; + + *size_p += sizeof (AttributeBlob); + *size_p += ALIGN_VALUE (strlen (key_str) + 1, 4); + *size_p += ALIGN_VALUE (strlen (value_str) + 1, 4); +} + /* returns the full size of the blob including variable-size parts */ static guint32 g_ir_node_get_full_size_internal (GIrNode *parent, @@ -851,6 +869,14 @@ g_ir_node_get_full_size (GIrNode *node) return g_ir_node_get_full_size_internal (NULL, node); } +guint32 +g_ir_node_get_attribute_size (GIrNode *node) +{ + guint32 size = 0; + g_hash_table_foreach (node->attributes, add_attribute_size, &size); + return size; +} + int g_ir_node_cmp (GIrNode *node, GIrNode *other) @@ -1364,6 +1390,15 @@ g_ir_node_build_typelib (GIrNode *node, g_ir_node_compute_offsets (node, module, modules); + /* We should only be building each node once. If we do a typelib expansion, we also + * reset the offset in girmodule.c. + */ + g_assert (node->offset == 0); + node->offset = *offset; + build->offset_ordered_nodes = g_list_prepend (build->offset_ordered_nodes, node); + + build->n_attributes += g_hash_table_size (node->attributes); + switch (node->type) { case G_IR_NODE_TYPE: @@ -2232,7 +2267,8 @@ g_ir_node_build_typelib (GIrNode *node, old_offset, *offset, old_offset2, *offset2); if (*offset2 - old_offset2 + *offset - old_offset > g_ir_node_get_full_size (node)) - g_error ("exceeding space reservation !!"); + g_error ("exceeding space reservation; offset: %d (prev %d) offset2: %d (prev %d) nodesize: %d", + *offset, old_offset, *offset2, old_offset2, g_ir_node_get_full_size (node)); } /* if str is already in the pool, return previous location, otherwise write str diff --git a/girnode.h b/girnode.h index 45c2bb029..2a1f6b237 100644 --- a/girnode.h +++ b/girnode.h @@ -51,6 +51,8 @@ struct _GIrTypelibBuild { GList *modules; GHashTable *strings; GHashTable *types; + GList *offset_ordered_nodes; + guint32 n_attributes; guchar *data; }; @@ -82,6 +84,10 @@ struct _GIrNode { GIrNodeTypeId type; gchar *name; + + guint32 offset; /* Assigned as we build the typelib */ + + GHashTable *attributes; }; struct _GIrNodeXRef @@ -349,6 +355,7 @@ GIrNode * g_ir_node_new (GIrNodeTypeId type); void g_ir_node_free (GIrNode *node); guint32 g_ir_node_get_size (GIrNode *node); guint32 g_ir_node_get_full_size (GIrNode *node); +guint32 g_ir_node_get_attribute_size (GIrNode *node); void g_ir_node_build_typelib (GIrNode *node, GIrNode *parent, GIrTypelibBuild *build, diff --git a/girparser.c b/girparser.c index e08b3fcd0..006ed3b71 100644 --- a/girparser.c +++ b/girparser.c @@ -68,6 +68,7 @@ typedef enum STATE_INTERFACE_CONSTANT, STATE_ALIAS, STATE_TYPE, + STATE_ATTRIBUTE, STATE_UNKNOWN } ParseState; @@ -1864,6 +1865,44 @@ end_type (ParseContext *ctx) } } +static gboolean +start_attribute (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + const gchar *name; + const gchar *value; + GIrNode *curnode; + + if (strcmp (element_name, "attribute") != 0 || ctx->node_stack == NULL) + return FALSE; + + name = find_attribute ("name", attribute_names, attribute_values); + value = find_attribute ("value", attribute_names, attribute_values); + + if (name == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; + } + if (value == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "value"); + return FALSE; + } + + state_switch (ctx, STATE_ATTRIBUTE); + + curnode = CURRENT_NODE (ctx); + + g_hash_table_insert (curnode->attributes, g_strdup (name), g_strdup (value)); + + return TRUE; +} + static gboolean start_return_value (GMarkupParseContext *context, const gchar *element_name, @@ -2383,6 +2422,10 @@ start_element_handler (GMarkupParseContext *context, attribute_names, attribute_values, ctx, error)) goto out; + else if (start_attribute (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; break; case 'b': if (start_enum (context, element_name, @@ -2662,7 +2705,7 @@ start_element_handler (GMarkupParseContext *context, ctx->unknown_depth += 1; } - out: ; + out: if (*error) { g_markup_parse_context_get_position (context, &line_number, &char_number); @@ -3027,6 +3070,13 @@ end_element_handler (GMarkupParseContext *context, end_type (ctx); break; } + case STATE_ATTRIBUTE: + if (strcmp ("attribute", element_name) == 0) + { + state_switch (ctx, ctx->prev_state); + } + break; + case STATE_UNKNOWN: ctx->unknown_depth -= 1; if (ctx->unknown_depth == 0) diff --git a/gtypelib.c b/gtypelib.c index 6ff00bfbf..a578c67d7 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -185,7 +185,7 @@ g_typelib_check_sanity (void) CHECK_SIZE (ObjectBlob, 44); CHECK_SIZE (InterfaceBlob, 40); CHECK_SIZE (ConstantBlob, 24); - CHECK_SIZE (AnnotationBlob, 12); + CHECK_SIZE (AttributeBlob, 12); CHECK_SIZE (UnionBlob, 40); #undef CHECK_SIZE @@ -334,7 +334,7 @@ validate_header (ValidateContext *ctx, header->value_blob_size != sizeof (ValueBlob) || header->constant_blob_size != sizeof (ConstantBlob) || header->error_domain_blob_size != sizeof (ErrorDomainBlob) || - header->annotation_blob_size != sizeof (AnnotationBlob) || + header->attribute_blob_size != sizeof (AttributeBlob) || header->signature_blob_size != sizeof (SignatureBlob) || header->enum_blob_size != sizeof (EnumBlob) || header->struct_blob_size != sizeof (StructBlob) || @@ -358,21 +358,21 @@ validate_header (ValidateContext *ctx, return FALSE; } - if (!is_aligned (header->annotations)) + if (!is_aligned (header->attributes)) { g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_HEADER, - "Misaligned annotations"); + "Misaligned attributes"); return FALSE; } - if (header->annotations == 0 && header->n_annotations > 0) + if (header->attributes == 0 && header->n_attributes > 0) { g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_HEADER, - "Wrong number of annotations"); + "Wrong number of attributes"); return FALSE; } @@ -1860,13 +1860,13 @@ validate_directory (ValidateContext *ctx, } static gboolean -validate_annotations (ValidateContext *ctx, - GError **error) +validate_attributes (ValidateContext *ctx, + GError **error) { GTypelib *typelib = ctx->typelib; Header *header = (Header *)typelib->data; - if (header->size < header->annotations + header->n_annotations * sizeof (AnnotationBlob)) + if (header->size < header->attributes + header->n_attributes * sizeof (AttributeBlob)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1926,9 +1926,9 @@ g_typelib_validate (GTypelib *typelib, return FALSE; } - if (!validate_annotations (&ctx, error)) + if (!validate_attributes (&ctx, error)) { - prefix_with_context (error, "annotations", &ctx); + prefix_with_context (error, "attributes", &ctx); return FALSE; } diff --git a/gtypelib.h b/gtypelib.h index 7a2838f18..db5fe1170 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -52,14 +52,15 @@ G_BEGIN_DECLS * * The typelib has the following general format. * - * typelib ::= header, directory, blobs, annotations + * typelib ::= header, directory, blobs, attributes, attributedata * * directory ::= list of entries * * entry ::= blob type, name, namespace, offset * blob ::= function|callback|struct|boxed|enum|flags|object|interface|constant|errordomain|union - * annotations ::= list of annotations, sorted by offset - * annotation ::= offset, key, value + * attributes ::= list of attributes, sorted by offset + * attribute ::= offset, key, value + * attributedata ::= string data for attributes * * Details * @@ -189,8 +190,8 @@ typedef enum { * @n_local_entries: The number of entries referring to blobs in this typelib. The * local entries must occur before the unresolved entries. * @directory: Offset of the directory in the typelib. - * @n_annotations: Number of annotation blocks - * @annotations: Offset of the list of annotations in the typelib. + * @n_attributes: Number of attribute blocks + * @attributes: Offset of the list of attributes in the typelib. * @dependencies: Offset of a single string, which is the list of * dependencies, separated by the '|' character. The * dependencies are required in order to avoid having programs @@ -212,7 +213,7 @@ typedef enum { * @property_blob_size: See above. * @field_blob_size: See above. * @value_blob_size: See above. - * @annotation_blob_size: See above. + * @attribute_blob_size: See above. * @constant_blob_size: See above. * @object_blob_size: See above. * @union_blob_size: See above. @@ -237,8 +238,8 @@ typedef struct { guint16 n_entries; guint16 n_local_entries; guint32 directory; - guint32 n_annotations; - guint32 annotations; + guint32 n_attributes; + guint32 attributes; guint32 dependencies; @@ -256,7 +257,7 @@ typedef struct { guint16 property_blob_size; guint16 field_blob_size; guint16 value_blob_size; - guint16 annotation_blob_size; + guint16 attribute_blob_size; guint16 constant_blob_size; guint16 error_domain_blob_size; @@ -1000,18 +1001,18 @@ typedef struct { } ConstantBlob; /** - * AnnotationBlob: - * @offset: The offset of the typelib entry to which this annotation refers. - * Annotations are kept sorted by offset, so that the annotations + * AttributeBlob: + * @offset: The offset of the typelib entry to which this attribute refers. + * Attributes are kept sorted by offset, so that the attributes * of an entry can be found by a binary search. - * @name: The name of the annotation, a string. - * @value: The value of the annotation (also a string) + * @name: The name of the attribute, a string. + * @value: The value of the attribute (also a string) */ typedef struct { guint32 offset; guint32 name; guint32 value; -} AnnotationBlob; +} AttributeBlob; struct _GTypelib { guchar *data; From 7299c89fc9ecd47ade3b993156de6a428a0f93a8 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 27 Feb 2009 19:02:48 -0500 Subject: [PATCH 222/692] Bug 557383 - Virtual method support Broadly speaking, this change adds the concept of to the .gir. The typelib already had most of the infrastructure for virtual functions, though there is one API addition. The scanner assumes that any class callback slot that doesn't match a signal name is a virtual. In the .gir, we write out *both* the wrapper and a . If we can determine an association between them (based on the names matching, or a new Virtual: annotation), then we notate that in the .gir. The typelib gains an association from the vfunc to the function, if it exists. This will be useful for bindings since they already know how to consume FunctionInfo. --- ginfo.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++ girepository.h | 5 +++ girnode.c | 37 ++++++++++++++++ girnode.h | 2 + girparser.c | 6 ++- gtypelib.h | 8 ++-- 6 files changed, 170 insertions(+), 4 deletions(-) diff --git a/ginfo.c b/ginfo.c index fcc5f098f..d522a5653 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1527,6 +1527,63 @@ g_object_info_get_vfunc (GIObjectInfo *info, base->typelib, offset); } +static GIVFuncInfo * +find_vfunc (GIBaseInfo *base, + guint32 offset, + gint n_vfuncs, + const gchar *name) +{ + /* FIXME hash */ + Header *header = (Header *)base->typelib->data; + gint i; + + for (i = 0; i < n_vfuncs; i++) + { + VFuncBlob *fblob = (VFuncBlob *)&base->typelib->data[offset]; + const gchar *fname = (const gchar *)&base->typelib->data[fblob->name]; + + if (strcmp (name, fname) == 0) + return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, base, + base->typelib, offset); + + offset += header->vfunc_blob_size; + } + + return NULL; +} + +/** + * g_object_info_find_vfunc: + * @info: An #GIObjectInfo + * @name: The name of a virtual function to find. + * + * Locate a virtual function slot with name @name. Note that the namespace + * for virtuals is distinct from that of methods; there may or may not be + * a concrete method associated for a virtual. If there is one, it may + * be retrieved using #g_vfunc_info_get_invoker. See the documentation for + * that function for more information on invoking virtuals. + * + * Return value: (transfer full): A #GIVFuncInfo, or %NULL if none with name @name. + */ +GIVFuncInfo * +g_object_info_find_vfunc (GIObjectInfo *info, + const gchar *name) +{ + gint offset; + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + + offset = base->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + + blob->n_signals * header->signal_blob_size; + + return find_vfunc (base, offset, blob->n_vfuncs, name); +} + gint g_object_info_get_n_constants (GIObjectInfo *info) { @@ -1728,6 +1785,34 @@ g_interface_info_get_vfunc (GIInterfaceInfo *info, base->typelib, offset); } +/** + * g_interface_info_find_vfunc: + * @info: An #GIObjectInfo + * @name: The name of a virtual function to find. + * + * Locate a virtual function slot with name @name. See the documentation + * for #g_object_info_find_vfunc for more information on virtuals. + * + * Return value: (transfer full): A #GIVFuncInfo, or %NULL if none with name @name. + */ +GIVFuncInfo * +g_interface_info_find_vfunc (GIInterfaceInfo *info, + const gchar *name) +{ + gint offset; + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; + + offset = base->offset + header->interface_blob_size + + (blob->n_prerequisites + blob->n_prerequisites % 2) * 2 + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + + blob->n_signals * header->signal_blob_size; + + return find_vfunc (base, offset, blob->n_vfuncs, name); +} + gint g_interface_info_get_n_constants (GIInterfaceInfo *info) { @@ -1913,6 +1998,37 @@ g_vfunc_info_get_signal (GIVFuncInfo *info) return NULL; } +/** + * g_vfunc_info_get_invoker: + * @info: A #GIVFuncInfo + * + * If this virtual function has an associated invoker method, this + * method will return it. An invoker method is a C entry point. + * + * Not all virtuals will have invokers. + * + * Return value: (transfer full): An invoker function, or %NULL if none known + */ +GIFunctionInfo * +g_vfunc_info_get_invoker (GIVFuncInfo *info) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + VFuncBlob *blob = (VFuncBlob *)&base->typelib->data[base->offset]; + GIBaseInfo *container = base->container; + GIInfoType parent_type; + + /* 1023 = 0x3ff is the maximum of the 10 bits for invoker index */ + if (blob->invoker == 1023) + return NULL; + + parent_type = g_base_info_get_type (container); + if (parent_type == GI_INFO_TYPE_OBJECT) + return g_object_info_get_method ((GIObjectInfo*)container, blob->invoker); + else if (parent_type == GI_INFO_TYPE_INTERFACE) + return g_interface_info_get_method ((GIInterfaceInfo*)container, blob->invoker); + else + g_assert_not_reached (); +} /* GIConstantInfo functions */ GITypeInfo * diff --git a/girepository.h b/girepository.h index 4059adc0e..1058570f4 100644 --- a/girepository.h +++ b/girepository.h @@ -470,6 +470,8 @@ GISignalInfo * g_object_info_get_signal (GIObjectInfo *in gint g_object_info_get_n_vfuncs (GIObjectInfo *info); GIVFuncInfo * g_object_info_get_vfunc (GIObjectInfo *info, gint n); +GIVFuncInfo * g_object_info_find_vfunc (GIObjectInfo *info, + const gchar *name); gint g_object_info_get_n_constants (GIObjectInfo *info); GIConstantInfo * g_object_info_get_constant (GIObjectInfo *info, gint n); @@ -495,6 +497,8 @@ GISignalInfo * g_interface_info_get_signal (GIInterfaceInfo *in gint g_interface_info_get_n_vfuncs (GIInterfaceInfo *info); GIVFuncInfo * g_interface_info_get_vfunc (GIInterfaceInfo *info, gint n); +GIVFuncInfo * g_interface_info_find_vfunc (GIInterfaceInfo *info, + const gchar *name); gint g_interface_info_get_n_constants (GIInterfaceInfo *info); GIConstantInfo * g_interface_info_get_constant (GIInterfaceInfo *info, gint n); @@ -527,6 +531,7 @@ typedef enum GIVFuncInfoFlags g_vfunc_info_get_flags (GIVFuncInfo *info); gint g_vfunc_info_get_offset (GIVFuncInfo *info); GISignalInfo * g_vfunc_info_get_signal (GIVFuncInfo *info); +GIFunctionInfo * g_vfunc_info_get_invoker (GIVFuncInfo *info); /* GIConstantInfo */ diff --git a/girnode.c b/girnode.c index 22c0aee01..01e83ace7 100644 --- a/girnode.c +++ b/girnode.c @@ -265,6 +265,7 @@ g_ir_node_free (GIrNode *node) GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node; g_free (node->name); + g_free (vfunc->invoker); for (l = vfunc->parameters; l; l = l->next) g_ir_node_free ((GIrNode *)l->data); g_list_free (vfunc->parameters); @@ -1186,6 +1187,30 @@ g_ir_find_node (GIrModule *module, return node != NULL; } +static int +get_index_of_member_type (GIrNodeInterface *node, + GIrNodeTypeId type, + const char *name) +{ + guint index = -1; + GList *l; + + for (l = node->members; l; l = l->next) + { + GIrNode *node = l->data; + + if (node->type != type) + continue; + + index++; + + if (strcmp (node->name, name) == 0) + break; + } + + return index; +} + static void serialize_type (GIrModule *module, GList *modules, @@ -1759,6 +1784,18 @@ g_ir_node_build_typelib (GIrNode *node, blob->class_closure = 0; /* FIXME */ blob->reserved = 0; + if (vfunc->invoker) + { + int index = get_index_of_member_type ((GIrNodeInterface*)parent, G_IR_NODE_FUNCTION, vfunc->invoker); + if (index == -1) + { + g_error ("Unknown member function %s for vfunc %s", vfunc->invoker, node->name); + } + blob->invoker = (guint) index; + } + else + blob->invoker = 0x3ff; /* max of 10 bits */ + blob->struct_offset = vfunc->offset; blob->reserved2 = 0; blob->signature = signature; diff --git a/girnode.h b/girnode.h index 2a1f6b237..238593aee 100644 --- a/girnode.h +++ b/girnode.h @@ -214,6 +214,8 @@ struct _GIrNodeVFunc gboolean must_not_be_implemented; gboolean is_class_closure; + char *invoker; + GList *parameters; GIrNodeParam *result; diff --git a/girparser.c b/girparser.c index 006ed3b71..9afd8585c 100644 --- a/girparser.c +++ b/girparser.c @@ -2080,7 +2080,7 @@ start_vfunc (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "vfunc") == 0 && + if (strcmp (element_name, "virtual-method") == 0 && (ctx->state == STATE_CLASS || ctx->state == STATE_INTERFACE)) { @@ -2089,12 +2089,14 @@ start_vfunc (GMarkupParseContext *context, const gchar *override; const gchar *is_class_closure; const gchar *offset; + const gchar *invoker; name = find_attribute ("name", attribute_names, attribute_values); must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values); override = find_attribute ("override", attribute_names, attribute_values); is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values); offset = find_attribute ("offset", attribute_names, attribute_values); + invoker = find_attribute ("invoker", attribute_names, attribute_values); if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); @@ -2138,6 +2140,8 @@ start_vfunc (GMarkupParseContext *context, else vfunc->offset = 0; + vfunc->invoker = g_strdup (invoker); + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); iface->members = g_list_append (iface->members, vfunc); diff --git a/gtypelib.h b/gtypelib.h index db5fe1170..f6ad8c977 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -843,9 +843,10 @@ typedef struct { * @class_closure: Set if this virtual function is the class closure of a signal. * @signal: The index of the signal in the list of signals of the object or * interface to which this virtual function belongs. - * @struct_offset: - * The offset of the function pointer in the class struct. The value + * @struct_offset: The offset of the function pointer in the class struct. The value * 0xFFFF indicates that the struct offset is unknown. + * @invoker: If a method invoker for this virtual exists, this is the offset in the + * class structure of the method. If no method is known, this value will be 0x3ff. * @signature: * Offset of the SignatureBlob describing the parameter types and the * return value type. @@ -861,7 +862,8 @@ typedef struct { guint16 signal; guint16 struct_offset; - guint16 reserved2; + guint16 invoker : 10; /* Number of bits matches @index in FunctionBlob */ + guint16 reserved2 : 6; guint32 reserved3; guint32 signature; From 2898d23962b9470383ca294b038f80ebd09714cb Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 12 Feb 2009 18:42:47 -0500 Subject: [PATCH 223/692] Bug 564016 - Include c:prefix in typelib, use it to optimize find_by_gtype Parse the c:prefix from the .gir, include it in the header. Armed with this information, we can now optimize lookups of GTypes because we have the requirement that GTypes must start with the c:prefix. We do fall back though if a lookup fails. --- girepository.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++--- girepository.h | 2 ++ girmodule.c | 19 ++++++++++--- girmodule.h | 4 ++- girparser.c | 6 ++-- gtypelib.c | 2 +- gtypelib.h | 1 + 7 files changed, 98 insertions(+), 12 deletions(-) diff --git a/girepository.c b/girepository.c index 06ea13c5e..a2a8504dd 100644 --- a/girepository.c +++ b/girepository.c @@ -517,6 +517,7 @@ typedef struct GIRepository *repo; gint index; const gchar *name; + gboolean type_firstpass; const gchar *type; GIBaseInfo *iface; } IfaceData; @@ -528,6 +529,7 @@ find_interface (gpointer key, { gint i; GTypelib *typelib = (GTypelib *)value; + Header *header = (Header *) typelib->data; IfaceData *iface_data = (IfaceData *)data; gint index; gint n_entries; @@ -553,6 +555,28 @@ find_interface (gpointer key, } else if (iface_data->type) { + const char *c_prefix; + /* Inside each typelib, we include the "C prefix" which acts as + * a namespace mechanism. For GtkTreeView, the C prefix is Gtk. + * Given the assumption that GTypes for a library also use the + * C prefix, we know we can skip examining a typelib if our + * target type does not have this typelib's C prefix. + * + * However, not every class library necessarily conforms to this, + * e.g. Clutter has Cogl inside it. So, we split this into two + * passes. First we try a lookup, skipping things which don't + * have the prefix. If that fails then we try a global lookup, + * ignoring the prefix. + * + * See http://bugzilla.gnome.org/show_bug.cgi?id=564016 + */ + c_prefix = g_typelib_get_string (typelib, header->c_prefix); + if (iface_data->type_firstpass && c_prefix != NULL) + { + if (g_ascii_strncasecmp (c_prefix, iface_data->type, strlen (c_prefix)) != 0) + return; + } + for (i = 1; i <= n_entries; i++) { RegisteredTypeBlob *blob; @@ -638,8 +662,8 @@ g_irepository_get_info (GIRepository *repository, * in order to locate the metadata, the namespace corresponding to * the type must first have been loaded. There is currently no * mechanism for determining the namespace which corresponds to an - * arbitrary GType - thus, this function will function most reliably - * when you have expect the GType to be from a known namespace. + * arbitrary GType - thus, this function will operate most reliably + * when you know the GType to originate from be from a loaded namespace. * * Returns: #GIBaseInfo representing metadata about @type, or %NULL */ @@ -659,6 +683,7 @@ g_irepository_find_by_gtype (GIRepository *repository, data.repo = repository; data.name = NULL; + data.type_firstpass = TRUE; data.type = g_type_name (gtype); data.index = -1; data.iface = NULL; @@ -666,12 +691,19 @@ g_irepository_find_by_gtype (GIRepository *repository, g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data); + /* We do two passes; see comment in find_interface */ + if (!data.iface) + { + data.type_firstpass = FALSE; + g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); + g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data); + } + if (data.iface) g_hash_table_insert (repository->priv->info_by_gtype, (gpointer) gtype, g_base_info_ref (data.iface)); - return data.iface; } @@ -824,7 +856,43 @@ g_irepository_get_shared_library (GIRepository *repository, } /** - * g_irepository_get_typelib_path: + * g_irepository_get_c_prefix + * @repository: A #GIRepository, may be %NULL for the default + * @namespace: Namespace to inspect + * + * This function returns the "C prefix", or the C level namespace + * associated with the given introspection namespace. Each C symbol + * starts with this prefix, as well each #GType in the library. + * + * Note: The namespace must have already been loaded using a function + * such as #g_irepository_require before calling this function. + * + * Returns: C namespace prefix, or %NULL if none associated + */ +const gchar * +g_irepository_get_c_prefix (GIRepository *repository, + const gchar *namespace_) +{ + GTypelib *typelib; + Header *header; + + g_return_val_if_fail (namespace_ != NULL, NULL); + + repository = get_repository (repository); + + typelib = get_registered (repository, namespace_, NULL); + + g_return_val_if_fail (typelib != NULL, NULL); + + header = (Header *) typelib->data; + if (header->shared_library) + return g_typelib_get_string (typelib, header->c_prefix); + else + return NULL; +} + +/** + * g_irepository_get_typelib_path * @repository: Repository, may be %NULL for the default * @namespace_: GI namespace to use, e.g. "Gtk" * diff --git a/girepository.h b/girepository.h index 1058570f4..efc6aca02 100644 --- a/girepository.h +++ b/girepository.h @@ -108,6 +108,8 @@ const gchar * g_irepository_get_typelib_path (GIRepository *repository, const gchar *namespace_); const gchar * g_irepository_get_shared_library (GIRepository *repository, const gchar *namespace_); +const gchar * g_irepository_get_c_prefix (GIRepository *repository, + const gchar *namespace_); const gchar * g_irepository_get_version (GIRepository *repository, const gchar *namespace_); diff --git a/girmodule.c b/girmodule.c index 96ee9ce91..bf1e856bb 100644 --- a/girmodule.c +++ b/girmodule.c @@ -31,7 +31,8 @@ GIrModule * g_ir_module_new (const gchar *name, const gchar *version, - const gchar *shared_library) + const gchar *shared_library, + const gchar *c_prefix) { GIrModule *module; @@ -43,6 +44,7 @@ g_ir_module_new (const gchar *name, module->shared_library = g_strdup (shared_library); else module->shared_library = NULL; + module->c_prefix = g_strdup (c_prefix); module->dependencies = NULL; module->entries = NULL; @@ -229,11 +231,13 @@ g_ir_module_build_typelib (GIrModule *module, } /* Adjust size for strings allocated in header below specially */ - size += strlen (module->name); + size += ALIGN_VALUE (strlen (module->name) + 1, 4); if (module->shared_library) - size += strlen (module->shared_library); + size += ALIGN_VALUE (strlen (module->shared_library) + 1, 4); if (dependencies != NULL) - size += strlen (dependencies); + size += ALIGN_VALUE (strlen (dependencies) + 1, 4); + if (module->c_prefix != NULL) + size += ALIGN_VALUE (strlen (module->c_prefix) + 1, 4); g_message ("allocating %d bytes (%d header, %d directory, %d entries)\n", size, header_size, dir_size, size - header_size - dir_size); @@ -250,6 +254,9 @@ g_ir_module_build_typelib (GIrModule *module, header->n_local_entries = n_local_entries; header->n_attributes = 0; header->attributes = 0; /* filled in later */ + /* NOTE: When writing strings to the typelib here, you should also update + * the size calculations above. + */ if (dependencies != NULL) header->dependencies = write_string (dependencies, strings, data, &header_size); else @@ -260,6 +267,10 @@ g_ir_module_build_typelib (GIrModule *module, header->shared_library = (module->shared_library? write_string (module->shared_library, strings, data, &header_size) : 0); + if (module->c_prefix != NULL) + header->c_prefix = write_string (module->c_prefix, strings, data, &header_size); + else + header->c_prefix = 0; header->directory = ALIGN_VALUE (header_size, 4); header->entry_blob_size = sizeof (DirEntry); header->function_blob_size = sizeof (FunctionBlob); diff --git a/girmodule.h b/girmodule.h index c658e179b..5a558c359 100644 --- a/girmodule.h +++ b/girmodule.h @@ -34,6 +34,7 @@ struct _GIrModule gchar *name; gchar *version; gchar *shared_library; + gchar *c_prefix; GList *dependencies; GList *entries; @@ -50,7 +51,8 @@ struct _GIrModule GIrModule *g_ir_module_new (const gchar *name, const gchar *nsversion, - const gchar *module_filename); + const gchar *module_filename, + const gchar *c_prefix); void g_ir_module_free (GIrModule *module); void g_ir_module_add_include_module (GIrModule *module, diff --git a/girparser.c b/girparser.c index 9afd8585c..7727d230b 100644 --- a/girparser.c +++ b/girparser.c @@ -88,6 +88,7 @@ struct _ParseContext GHashTable *disguised_structures; const char *namespace; + const char *c_prefix; GIrModule *current_module; GSList *node_stack; GIrNode *current_typed; @@ -2547,7 +2548,7 @@ start_element_handler (GMarkupParseContext *context, case 'n': if (strcmp (element_name, "namespace") == 0 && ctx->state == STATE_REPOSITORY) { - const gchar *name, *version, *shared_library; + const gchar *name, *version, *shared_library, *cprefix; if (ctx->current_module != NULL) { @@ -2561,6 +2562,7 @@ start_element_handler (GMarkupParseContext *context, name = find_attribute ("name", attribute_names, attribute_values); version = find_attribute ("version", attribute_names, attribute_values); shared_library = find_attribute ("shared-library", attribute_names, attribute_values); + cprefix = find_attribute ("c:prefix", attribute_names, attribute_values); if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); @@ -2577,7 +2579,7 @@ start_element_handler (GMarkupParseContext *context, " name element '%s' doesn't match file name '%s'", name, ctx->namespace); - ctx->current_module = g_ir_module_new (name, version, shared_library); + ctx->current_module = g_ir_module_new (name, version, shared_library, cprefix); ctx->current_module->aliases = ctx->aliases; ctx->aliases = NULL; diff --git a/gtypelib.c b/gtypelib.c index a578c67d7..64138aa0a 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -161,7 +161,7 @@ g_typelib_check_sanity (void) * Everything else in the code however should be using sizeof(). */ - CHECK_SIZE (Header, 108); + CHECK_SIZE (Header, 112); CHECK_SIZE (DirEntry, 12); CHECK_SIZE (SimpleTypeBlob, 4); CHECK_SIZE (ArgBlob, 16); diff --git a/gtypelib.h b/gtypelib.h index f6ad8c977..d4afa8901 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -247,6 +247,7 @@ typedef struct { guint32 namespace; guint32 nsversion; guint32 shared_library; + guint32 c_prefix; guint16 entry_blob_size; guint16 function_blob_size; From a515ab13b05fb1a1dd1f36d952010607b94c9379 Mon Sep 17 00:00:00 2001 From: Didier 'Ptitjes Date: Sun, 22 Mar 2009 21:50:40 +0100 Subject: [PATCH 224/692] Bug 576323 - Fix inner constant parsing Signed-off-by: Didier 'Ptitjes Signed-off-by: Colin Walters --- girparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index 7727d230b..02fa03724 100644 --- a/girparser.c +++ b/girparser.c @@ -3051,10 +3051,10 @@ end_element_handler (GMarkupParseContext *context, break; if (require_end_element (context, ctx, "constant", element_name, error)) { - pop_node (ctx); switch (ctx->state) { case STATE_NAMESPACE_CONSTANT: + pop_node (ctx); state_switch (ctx, STATE_NAMESPACE); break; case STATE_CLASS_CONSTANT: From 7937dd000e0d8018c8cba998ddf7c7a09b156e60 Mon Sep 17 00:00:00 2001 From: Andreas Rottmann Date: Fri, 27 Mar 2009 19:31:55 +0100 Subject: [PATCH 225/692] Bug 576605 - Get rid of GI_SCOPE_TYPE_OBJECT Remove support for (scope object) as it lacks a real use case. --- girepository.h | 2 -- girparser.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/girepository.h b/girepository.h index efc6aca02..a01c3ec3c 100644 --- a/girepository.h +++ b/girepository.h @@ -296,8 +296,6 @@ typedef enum { GI_SCOPE_TYPE_INVALID, /* The argument is not of callback type */ GI_SCOPE_TYPE_CALL, /* The callback and associated user_data is only used during the call to this function */ - GI_SCOPE_TYPE_OBJECT, /* The callback and associated user_data is used until - the object containing this method is destroyed */ GI_SCOPE_TYPE_ASYNC, /* The callback and associated user_data is only used until the callback is invoked, and the callback is invoked always exactly once. */ diff --git a/girparser.c b/girparser.c index 02fa03724..519c43c7a 100644 --- a/girparser.c +++ b/girparser.c @@ -934,8 +934,6 @@ start_parameter (GMarkupParseContext *context, if (scope && strcmp (scope, "call") == 0) param->scope = GI_SCOPE_TYPE_CALL; - else if (scope && strcmp (scope, "object") == 0) - param->scope = GI_SCOPE_TYPE_OBJECT; else if (scope && strcmp (scope, "async") == 0) param->scope = GI_SCOPE_TYPE_ASYNC; else if (scope && strcmp (scope, "notified") == 0) From c5930c73c55d2df4e92ddf122a57908fde461c03 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Sat, 28 Mar 2009 08:34:36 -0400 Subject: [PATCH 226/692] Fix 'Could not find GIR file ...' error to use right filename. Also plug a leak; girname was previously only freed on error. --- girparser.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/girparser.c b/girparser.c index 519c43c7a..2e8890eae 100644 --- a/girparser.c +++ b/girparser.c @@ -224,18 +224,14 @@ static GMarkupParser firstpass_parser = static char * locate_gir (GIrParser *parser, - const char *name, - const char *version) + const char *girname) { const gchar *const *datadirs; const gchar *const *dir; - char *girname; char *path = NULL; datadirs = g_get_system_data_dirs (); - girname = g_strdup_printf ("%s-%s.gir", name, version); - if (parser->includes != NULL) { for (dir = (const gchar *const *)parser->includes; *dir; dir++) @@ -255,7 +251,6 @@ locate_gir (GIrParser *parser, g_free (path); path = NULL; } - g_free (girname); return path; } @@ -2321,7 +2316,7 @@ parse_include (GMarkupParseContext *context, { gchar *buffer; gsize length; - char *girpath; + gchar *girpath, *girname; gboolean success = FALSE; GList *modules; GList *l; @@ -2350,17 +2345,20 @@ parse_include (GMarkupParseContext *context, } } - girpath = locate_gir (ctx->parser, name, version); + girname = g_strdup_printf ("%s-%s.gir", name, version); + girpath = locate_gir (ctx->parser, girname); if (girpath == NULL) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, - "Could not find GIR file '%s.gir'; check XDG_DATA_DIRS or use --includedir", - name); + "Could not find GIR file '%s'; check XDG_DATA_DIRS or use --includedir", + girname); + g_free (girname); return FALSE; } + g_free (girname); g_debug ("Parsing include %s", girpath); From 7f29f620a4a6e9f75cfb9584a501dcfde660d2ec Mon Sep 17 00:00:00 2001 From: "C. Scott Ananian" Date: Tue, 5 May 2009 13:06:37 -0400 Subject: [PATCH 227/692] Update doc comments. The enumeration values cited here were out of date. Rewrite to eliminate the explicit mention of the enumeration value, to prevent it from drifting out of date again in the future. --- gtypelib.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gtypelib.h b/gtypelib.h index d4afa8901..aff53d93a 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -492,7 +492,6 @@ typedef struct { * @tag: A #GITypeTag * @interface: Index of the directory entry for the interface. * - * Types which are described by an entry in the typelib have a tag value of 21. * If the interface is an enum of flags type, is_pointer is 0, otherwise it is 1. */ typedef struct { @@ -516,8 +515,7 @@ typedef struct { * direction as this one. * @type: The type of the array elements. * - * Arrays have a tag value of 20. They are passed by reference, thus is_pointer - * is always 1. + * Arrays are passed by reference, thus is_pointer is always 1. */ typedef struct { guint16 pointer :1; From 5917b5ba4204bf65f3448ef61ec40b7f4de35212 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 1 Jun 2009 09:18:43 +0200 Subject: [PATCH 228/692] Make g-ir-compiler find files installed by make install When ./configure --prefix $HOME/some/where is used gobject-introspection will happily install the files into $HOME/some/where/data/gir-1.0 but it will refuse to find them. Apply the same trick as in girepository/girepository.c:init_globals to find the gir files. Unifiy the name gir-1.0 in GIR_SUFFIX and use it throughout the project, introduce GIR_DIR which holds the path to the gir files and update girparser and transformer.py to look into this path. --- girparser.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/girparser.c b/girparser.c index 2e8890eae..0a06aa089 100644 --- a/girparser.c +++ b/girparser.c @@ -27,6 +27,7 @@ #include "girmodule.h" #include "girnode.h" #include "gtypelib.h" +#include "config.h" struct _GIrParser { @@ -245,13 +246,18 @@ locate_gir (GIrParser *parser, } for (dir = datadirs; *dir; dir++) { - path = g_build_filename (*dir, "gir-1.0", girname, NULL); + path = g_build_filename (*dir, GIR_SUFFIX, girname, NULL); if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) return path; g_free (path); path = NULL; } - return path; + + path = g_build_filename (GIR_DIR, girname, NULL); + if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) + return path; + g_free (path); + return NULL; } #define MISSING_ATTRIBUTE(ctx,error,element,attribute) \ From 1a256fd7bd2fb88cc342bbfe01dd3ef7d0788b02 Mon Sep 17 00:00:00 2001 From: "C. Scott Ananian" Date: Fri, 12 Jun 2009 11:52:56 -0400 Subject: [PATCH 229/692] Bug 585584: Fix warnings in girparser backtrace functionality and compiler.c --- girparser.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/girparser.c b/girparser.c index 0a06aa089..0ab6259e1 100644 --- a/girparser.c +++ b/girparser.c @@ -29,6 +29,10 @@ #include "gtypelib.h" #include "config.h" +#if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS) +# include +#endif + struct _GIrParser { gchar **includes; @@ -276,9 +280,8 @@ backtrace_stderr (void) { #if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS) void *array[50]; - int size; + int size, i; char **strings; - size_t i; size = backtrace (array, 50); strings = (char**) backtrace_symbols (array, size); @@ -288,7 +291,7 @@ backtrace_stderr (void) for (i = 0; i < size; i++) fprintf (stderr, "%s\n", strings[i]); - fprintf (stderr, "--- END BACKTRACE ---\n", size); + fprintf (stderr, "--- END BACKTRACE ---\n"); free (strings); #endif From 0a046b7aa048e7a44725fc320ab4554722a243e3 Mon Sep 17 00:00:00 2001 From: Simon van der Linden Date: Wed, 17 Jun 2009 17:30:19 -0400 Subject: [PATCH 230/692] Bug 585328 - Only set zero_terminated flag for types we know are Rationalize our setting of the zero_terminated flag; we shouldn't set it if the gir doesn't say to. --- girparser.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/girparser.c b/girparser.c index 0ab6259e1..e5f5e75af 100644 --- a/girparser.c +++ b/girparser.c @@ -1710,6 +1710,12 @@ start_type (GMarkupParseContext *context, typenode->has_size = size != NULL; typenode->size = typenode->has_size ? atoi (size) : -1; + + if (zero) + typenode->zero_terminated = strcmp(zero, "1") == 0; + else + /* If neither zero-terminated nor length nor fixed-size is given, assume zero-terminated. */ + typenode->zero_terminated = !(typenode->has_length || typenode->has_size); } else { From 378350f3a9f82528fa123a14e9479acde3c43adc Mon Sep 17 00:00:00 2001 From: Mark Lee Date: Fri, 19 Jun 2009 16:53:03 -0700 Subject: [PATCH 231/692] =?UTF-8?q?Bug=20584423=20=E2=80=93=20Add=20short/?= =?UTF-8?q?ushort=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add type tags for short and ushort, plus all of the requisite code needed to utilize them in libgirepository. Add support in the scanner's AST files. Add test functions to the everything library and the expected gir file. gtypelib.c constant validation fixed by Colin Walters --- gfield.c | 8 ++++++++ ginfo.c | 6 ++++++ girepository.c | 4 ++++ girepository.h | 40 ++++++++++++++++++++++------------------ girffi.c | 4 ++++ girnode.c | 8 ++++++++ girparser.c | 2 ++ gtypelib.c | 2 ++ 8 files changed, 56 insertions(+), 18 deletions(-) diff --git a/gfield.c b/gfield.c index 4515bcf5b..2fa982275 100644 --- a/gfield.c +++ b/gfield.c @@ -55,6 +55,8 @@ g_field_info_get_field (GIFieldInfo *field_info, break; case GI_TYPE_TAG_INT16: case GI_TYPE_TAG_UINT16: + case GI_TYPE_TAG_SHORT: + case GI_TYPE_TAG_USHORT: value->v_uint16 = G_STRUCT_MEMBER(guint16, mem, offset); result = TRUE; break; @@ -138,6 +140,8 @@ g_field_info_get_field (GIFieldInfo *field_info, break; case GI_TYPE_TAG_INT16: case GI_TYPE_TAG_UINT16: + case GI_TYPE_TAG_SHORT: + case GI_TYPE_TAG_USHORT: value->v_int = (gint)G_STRUCT_MEMBER(guint16, mem, offset); result = TRUE; break; @@ -251,6 +255,8 @@ g_field_info_set_field (GIFieldInfo *field_info, break; case GI_TYPE_TAG_INT16: case GI_TYPE_TAG_UINT16: + case GI_TYPE_TAG_SHORT: + case GI_TYPE_TAG_USHORT: G_STRUCT_MEMBER(guint16, mem, offset) = value->v_uint16; result = TRUE; break; @@ -329,6 +335,8 @@ g_field_info_set_field (GIFieldInfo *field_info, break; case GI_TYPE_TAG_INT16: case GI_TYPE_TAG_UINT16: + case GI_TYPE_TAG_SHORT: + case GI_TYPE_TAG_USHORT: G_STRUCT_MEMBER(guint16, mem, offset) = (guint16)value->v_int; result = TRUE; break; diff --git a/ginfo.c b/ginfo.c index d522a5653..6fbd464f7 100644 --- a/ginfo.c +++ b/ginfo.c @@ -2091,6 +2091,12 @@ g_constant_info_get_value (GIConstantInfo *info, case GI_TYPE_TAG_TIME_T: value->v_long = *(long*)&base->typelib->data[blob->offset]; break; + case GI_TYPE_TAG_SHORT: + value->v_short = *(gshort*)&base->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_USHORT: + value->v_ushort = *(gushort*)&base->typelib->data[blob->offset]; + break; case GI_TYPE_TAG_INT: value->v_int = *(gint*)&base->typelib->data[blob->offset]; break; diff --git a/girepository.c b/girepository.c index a2a8504dd..3e0d08d87 100644 --- a/girepository.c +++ b/girepository.c @@ -1321,6 +1321,10 @@ g_type_tag_to_string (GITypeTag type) return "int64"; case GI_TYPE_TAG_UINT64: return "uint64"; + case GI_TYPE_TAG_SHORT: + return "short"; + case GI_TYPE_TAG_USHORT: + return "ushort"; case GI_TYPE_TAG_INT: return "int"; case GI_TYPE_TAG_UINT: diff --git a/girepository.h b/girepository.h index a01c3ec3c..559be1ee3 100644 --- a/girepository.h +++ b/girepository.h @@ -240,6 +240,8 @@ typedef union guint64 v_uint64; gfloat v_float; gdouble v_double; + gshort v_short; + gushort v_ushort; gint v_int; guint v_uint; glong v_long; @@ -329,25 +331,27 @@ typedef enum { GI_TYPE_TAG_UINT32 = 7, GI_TYPE_TAG_INT64 = 8, GI_TYPE_TAG_UINT64 = 9, - GI_TYPE_TAG_INT = 10, - GI_TYPE_TAG_UINT = 11, - GI_TYPE_TAG_LONG = 12, - GI_TYPE_TAG_ULONG = 13, - GI_TYPE_TAG_SSIZE = 14, - GI_TYPE_TAG_SIZE = 15, - GI_TYPE_TAG_FLOAT = 16, - GI_TYPE_TAG_DOUBLE = 17, - GI_TYPE_TAG_TIME_T = 18, - GI_TYPE_TAG_GTYPE = 19, - GI_TYPE_TAG_UTF8 = 20, - GI_TYPE_TAG_FILENAME = 21, + GI_TYPE_TAG_SHORT = 10, + GI_TYPE_TAG_USHORT = 11, + GI_TYPE_TAG_INT = 12, + GI_TYPE_TAG_UINT = 13, + GI_TYPE_TAG_LONG = 14, + GI_TYPE_TAG_ULONG = 15, + GI_TYPE_TAG_SSIZE = 16, + GI_TYPE_TAG_SIZE = 17, + GI_TYPE_TAG_FLOAT = 18, + GI_TYPE_TAG_DOUBLE = 19, + GI_TYPE_TAG_TIME_T = 20, + GI_TYPE_TAG_GTYPE = 21, + GI_TYPE_TAG_UTF8 = 22, + GI_TYPE_TAG_FILENAME = 23, /* Non-basic types */ - GI_TYPE_TAG_ARRAY = 22, - GI_TYPE_TAG_INTERFACE = 23, - GI_TYPE_TAG_GLIST = 24, - GI_TYPE_TAG_GSLIST = 25, - GI_TYPE_TAG_GHASH = 26, - GI_TYPE_TAG_ERROR = 27 + GI_TYPE_TAG_ARRAY = 24, + GI_TYPE_TAG_INTERFACE = 25, + GI_TYPE_TAG_GLIST = 26, + GI_TYPE_TAG_GSLIST = 27, + GI_TYPE_TAG_GHASH = 28, + GI_TYPE_TAG_ERROR = 29 /* Note - there is only room currently for 32 tags. * See docs/typelib-format.txt SimpleTypeBlob definition */ } GITypeTag; diff --git a/girffi.c b/girffi.c index 4611a6303..a001b7d78 100644 --- a/girffi.c +++ b/girffi.c @@ -51,6 +51,10 @@ g_ir_ffi_get_ffi_type (GITypeTag tag) return &ffi_type_sint64; case GI_TYPE_TAG_UINT64: return &ffi_type_uint64; + case GI_TYPE_TAG_SHORT: + return &ffi_type_sshort; + case GI_TYPE_TAG_USHORT: + return &ffi_type_ushort; case GI_TYPE_TAG_INT: return &ffi_type_sint; case GI_TYPE_TAG_UINT: diff --git a/girnode.c b/girnode.c index 01e83ace7..e4f889a70 100644 --- a/girnode.c +++ b/girnode.c @@ -2254,6 +2254,14 @@ g_ir_node_build_typelib (GIrNode *node, blob->size = 8; *(guint64*)&data[blob->offset] = (guint64) parse_uint_value (constant->value); break; + case GI_TYPE_TAG_SHORT: + blob->size = sizeof (gshort); + *(gshort*)&data[blob->offset] = (gshort) parse_int_value (constant->value); + break; + case GI_TYPE_TAG_USHORT: + blob->size = sizeof (gushort); + *(gushort*)&data[blob->offset] = (gushort) parse_uint_value (constant->value); + break; case GI_TYPE_TAG_INT: blob->size = sizeof (gint); *(gint*)&data[blob->offset] = (gint) parse_int_value (constant->value); diff --git a/girparser.c b/girparser.c index e5f5e75af..9387d2529 100644 --- a/girparser.c +++ b/girparser.c @@ -364,6 +364,8 @@ static BasicTypeInfo basic_types[] = { { "uint32", GI_TYPE_TAG_UINT32, 0 }, { "int64", GI_TYPE_TAG_INT64, 0 }, { "uint64", GI_TYPE_TAG_UINT64, 0 }, + { "short", GI_TYPE_TAG_SHORT, 0 }, + { "ushort", GI_TYPE_TAG_USHORT, 0 }, { "int", GI_TYPE_TAG_INT, 0 }, { "uint", GI_TYPE_TAG_UINT, 0 }, { "long", GI_TYPE_TAG_LONG, 0 }, diff --git a/gtypelib.c b/gtypelib.c index 64138aa0a..4e26f1e43 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -904,6 +904,8 @@ validate_constant_blob (GTypelib *typelib, 4, /* UINT32 */ 8, /* INT64 */ 8, /* UINT64 */ + sizeof (gshort), + sizeof (gushort), sizeof (gint), sizeof (guint), sizeof (glong), From 65e241fab82358500903cf9cc9db8d3bec8b191f Mon Sep 17 00:00:00 2001 From: Tobias Mueller Date: Wed, 24 Jun 2009 23:52:05 +0200 Subject: [PATCH 232/692] Name unions to enable compilation on Solaris Patch by Brian Cameron . Fixes bug 578199. --- ginfo.c | 34 +++++++++++++++++----------------- girnode.c | 16 ++++++++-------- gtypelib.c | 24 ++++++++++++------------ gtypelib.h | 4 ++-- 4 files changed, 39 insertions(+), 39 deletions(-) diff --git a/ginfo.c b/ginfo.c index 6fbd464f7..e7b0b8bd7 100644 --- a/ginfo.c +++ b/ginfo.c @@ -637,7 +637,7 @@ g_type_info_new (GIBaseInfo *container, SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset]; return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, typelib, - (type->reserved == 0 && type->reserved2 == 0) ? offset : type->offset); + (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset); } /** @@ -852,8 +852,8 @@ g_type_info_is_pointer (GITypeInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (type->reserved == 0 && type->reserved2 == 0) - return type->pointer; + if (type->flags.reserved == 0 && type->flags.reserved2 == 0) + return type->flags.pointer; else { InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->typelib->data[base->offset]; @@ -868,8 +868,8 @@ g_type_info_get_tag (GITypeInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (type->reserved == 0 && type->reserved2 == 0) - return type->tag; + if (type->flags.reserved == 0 && type->flags.reserved2 == 0) + return type->flags.tag; else { InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->typelib->data[base->offset]; @@ -885,7 +885,7 @@ g_type_info_get_param_type (GITypeInfo *info, GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (!(type->reserved == 0 && type->reserved2 == 0)) + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { ParamTypeBlob *param = (ParamTypeBlob *)&base->typelib->data[base->offset]; @@ -913,7 +913,7 @@ g_type_info_get_interface (GITypeInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (!(type->reserved == 0 && type->reserved2 == 0)) + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->typelib->data[base->offset]; @@ -930,14 +930,14 @@ g_type_info_get_array_length (GITypeInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (!(type->reserved == 0 && type->reserved2 == 0)) + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset]; if (blob->tag == GI_TYPE_TAG_ARRAY) { if (blob->has_length) - return blob->length; + return blob->dimensions.length; } } @@ -950,14 +950,14 @@ g_type_info_get_array_fixed_size (GITypeInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (!(type->reserved == 0 && type->reserved2 == 0)) + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset]; if (blob->tag == GI_TYPE_TAG_ARRAY) { if (blob->has_size) - return blob->size; + return blob->dimensions.size; } } @@ -970,7 +970,7 @@ g_type_info_is_zero_terminated (GITypeInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (!(type->reserved == 0 && type->reserved2 == 0)) + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset]; @@ -987,7 +987,7 @@ g_type_info_get_n_error_domains (GITypeInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (!(type->reserved == 0 && type->reserved2 == 0)) + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->typelib->data[base->offset]; @@ -1005,7 +1005,7 @@ g_type_info_get_error_domain (GITypeInfo *info, GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (!(type->reserved == 0 && type->reserved2 == 0)) + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->typelib->data[base->offset]; @@ -2047,13 +2047,13 @@ g_constant_info_get_value (GIConstantInfo *info, ConstantBlob *blob = (ConstantBlob *)&base->typelib->data[base->offset]; /* FIXME non-basic types ? */ - if (blob->type.reserved == 0 && blob->type.reserved2 == 0) + if (blob->type.flags.reserved == 0 && blob->type.flags.reserved2 == 0) { - if (blob->type.pointer) + if (blob->type.flags.pointer) value->v_pointer = g_memdup (&base->typelib->data[blob->offset], blob->size); else { - switch (blob->type.tag) + switch (blob->type.flags.tag) { case GI_TYPE_TAG_BOOLEAN: value->v_boolean = *(gboolean*)&base->typelib->data[blob->offset]; diff --git a/girnode.c b/girnode.c index e4f889a70..bd9be6824 100644 --- a/girnode.c +++ b/girnode.c @@ -1437,11 +1437,11 @@ g_ir_node_build_typelib (GIrNode *node, type->tag == GI_TYPE_TAG_UTF8 || type->tag == GI_TYPE_TAG_FILENAME) { - blob->reserved = 0; - blob->reserved2 = 0; - blob->pointer = type->is_pointer; - blob->reserved3 = 0; - blob->tag = type->tag; + blob->flags.reserved = 0; + blob->flags.reserved2 = 0; + blob->flags.pointer = type->is_pointer; + blob->flags.reserved3 = 0; + blob->flags.tag = type->tag; } else { @@ -1481,11 +1481,11 @@ g_ir_node_build_typelib (GIrNode *node, array->has_size = type->has_size; array->reserved2 = 0; if (array->has_length) - array->length = type->length; + array->dimensions.length = type->length; else if (array->has_size) - array->size = type->size; + array->dimensions.size = type->size; else - array->length = -1; + array->dimensions.length = -1; pos = *offset2 + G_STRUCT_OFFSET (ArrayTypeBlob, type); *offset2 += sizeof (ArrayTypeBlob); diff --git a/gtypelib.c b/gtypelib.c index 4e26f1e43..92df53933 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -116,13 +116,13 @@ get_type_blob (GTypelib *typelib, return FALSE; } - if (simple->reserved == 0 && simple->reserved2 == 0) + if (simple->flags.reserved == 0 && simple->flags.reserved2 == 0) { g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID, "Expected non-basic type but got %d", - simple->tag); + simple->flags.tag); return FALSE; } @@ -547,10 +547,10 @@ validate_type_blob (GTypelib *typelib, simple = (SimpleTypeBlob *)&typelib->data[offset]; - if (simple->reserved == 0 && - simple->reserved2 == 0) + if (simple->flags.reserved == 0 && + simple->flags.reserved2 == 0) { - if (simple->tag >= GI_TYPE_TAG_ARRAY) + if (simple->flags.tag >= GI_TYPE_TAG_ARRAY) { g_set_error (error, G_TYPELIB_ERROR, @@ -559,13 +559,13 @@ validate_type_blob (GTypelib *typelib, return FALSE; } - if (simple->tag >= GI_TYPE_TAG_UTF8 && - !simple->pointer) + if (simple->flags.tag >= GI_TYPE_TAG_UTF8 && + !simple->flags.pointer) { g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", simple->tag); + "Pointer type exected for tag %d", simple->flags.tag); return FALSE; } @@ -965,9 +965,9 @@ validate_constant_blob (GTypelib *typelib, } type = (SimpleTypeBlob *)&typelib->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)]; - if (type->reserved == 0 && type->reserved2 == 0) + if (type->flags.reserved == 0 && type->flags.reserved2 == 0) { - if (type->tag == 0) + if (type->flags.tag == 0) { g_set_error (error, G_TYPELIB_ERROR, @@ -976,8 +976,8 @@ validate_constant_blob (GTypelib *typelib, return FALSE; } - if (value_size[type->tag] != 0 && - blob->size != value_size[type->tag]) + if (value_size[type->flags.tag] != 0 && + blob->size != value_size[type->flags.tag]) { g_set_error (error, G_TYPELIB_ERROR, diff --git a/gtypelib.h b/gtypelib.h index aff53d93a..2827543a0 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -313,7 +313,7 @@ typedef union guint pointer : 1; guint reserved3 : 2; guint tag : 5; - }; + } flags; guint32 offset; } SimpleTypeBlob; @@ -530,7 +530,7 @@ typedef struct { union { guint16 length; guint16 size; - }; + } dimensions; SimpleTypeBlob type; } ArrayTypeBlob; From 933fcbc88cd61d47eeea86ad7df8f3dcadefdacf Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Mon, 6 Jul 2009 11:17:40 -0400 Subject: [PATCH 233/692] Sync the basic types array in girnode.c:serialize_type with GITypeTag Fixes a crash compiling GIRepository-2.0.gir. http://bugzilla.gnome.org/show_bug.cgi?id=587823 --- girnode.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/girnode.c b/girnode.c index bd9be6824..22e821e01 100644 --- a/girnode.c +++ b/girnode.c @@ -1229,6 +1229,8 @@ serialize_type (GIrModule *module, "uint32", "int64", "uint64", + "short", + "ushort", "int", "uint", "long", @@ -1237,11 +1239,10 @@ serialize_type (GIrModule *module, "size", "float", "double", + "time_t", + "GType", "utf8", "filename", - "string", - "sequence", - "any" }; if (node->tag < GI_TYPE_TAG_ARRAY) From 46d5a2392d7568bd9c42222f60e1069a4aaba977 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Tue, 21 Apr 2009 10:57:50 -0400 Subject: [PATCH 234/692] Fix checks in gfield.c When checking if the readable/writable flags are missing for the fields we are trying to read and write, use (a & flag) == 0, not (!a & flag). http://bugzilla.gnome.org/show_bug.cgi?id=579727 --- gfield.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gfield.c b/gfield.c index 2fa982275..94c2fb597 100644 --- a/gfield.c +++ b/gfield.c @@ -25,7 +25,7 @@ g_field_info_get_field (GIFieldInfo *field_info, GITypeInfo *type_info; gboolean result = FALSE; - if (!g_field_info_get_flags (field_info) & GI_FIELD_IS_READABLE) + if ((g_field_info_get_flags (field_info) & GI_FIELD_IS_READABLE) == 0) return FALSE; offset = g_field_info_get_offset (field_info); @@ -219,7 +219,7 @@ g_field_info_get_field (GIFieldInfo *field_info, * to write fields where memory management would by required. A field * with a type such as 'char *' must be set with a setter function. * - * Returns: %TRUE if reading the field succeeded, otherwise %FALSE + * Returns: %TRUE if writing the field succeeded, otherwise %FALSE */ gboolean g_field_info_set_field (GIFieldInfo *field_info, @@ -230,7 +230,7 @@ g_field_info_set_field (GIFieldInfo *field_info, GITypeInfo *type_info; gboolean result = FALSE; - if (!g_field_info_get_flags (field_info) & GI_FIELD_IS_WRITABLE) + if ((g_field_info_get_flags (field_info) & GI_FIELD_IS_WRITABLE) == 0) return FALSE; offset = g_field_info_get_offset (field_info); From 90de854ee50d16f3e0a506de0dd34a7ce2a02039 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Thu, 13 Aug 2009 15:14:49 -0400 Subject: [PATCH 235/692] Don't open shared libraries twice If loading a referenced shared library succeeds, don't try loading it again. http://bugzilla.gnome.org/show_bug.cgi?id=591737 --- gtypelib.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gtypelib.c b/gtypelib.c index 92df53933..a801f2be3 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1997,8 +1997,10 @@ _g_typelib_init (GTypelib *typelib) g_string_append (shlib_full, ".la"); module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); if (module == NULL) - g_string_overwrite (shlib_full, strlen (shlib_full->str)-2, SHLIB_SUFFIX); - module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); + { + g_string_overwrite (shlib_full, strlen (shlib_full->str)-2, SHLIB_SUFFIX); + module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); + } g_string_free (shlib_full, TRUE); } From 1735ebde9a0544169d422e00d6e121a712e7b2a0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 18 Aug 2009 10:23:09 -0400 Subject: [PATCH 236/692] [typelib] Clean up dlopen handling It's was busted that g_typelib_new_* does the dlopen() since that caused g-ir-compiler to load the modules even though it wasn't going to do anything with them. Instead, change things so that g_module_symbol does the dlopen on-demand. Remove the extra dlopen(NULL) inside girepository.c, we had another already in gtypelib.c. Thanks to Owen Taylor for suggesting this approach. --- girepository.c | 3 - gtypelib.c | 169 ++++++++++++++++++++++++++----------------------- gtypelib.h | 1 + 3 files changed, 91 insertions(+), 82 deletions(-) diff --git a/girepository.c b/girepository.c index 3e0d08d87..e68182988 100644 --- a/girepository.c +++ b/girepository.c @@ -363,9 +363,6 @@ register_internal (GIRepository *repository, g_hash_table_insert (repository->priv->typelibs, key, (void *)typelib); } - if (typelib->modules == NULL) - typelib->modules = g_list_append(typelib->modules, g_module_open (NULL, 0)); - return namespace; } diff --git a/gtypelib.c b/gtypelib.c index a801f2be3..e7572ea51 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1946,86 +1946,99 @@ g_typelib_error_quark (void) return quark; } -static inline void -_g_typelib_init (GTypelib *typelib) +static void +_g_typelib_do_dlopen (GTypelib *typelib) { Header *header; - + const char *shlib_str; + header = (Header *) typelib->data; + /* note that NULL shlib means to open the main app, which is allowed */ if (header->shared_library) + shlib_str = g_typelib_get_string (typelib, header->shared_library); + else + shlib_str = NULL; + + if (shlib_str != NULL && shlib_str[0] != '\0') { - const gchar *shlib_str; - GModule *app_module = NULL; + gchar **shlibs; + gint i; - shlib_str = g_typelib_get_string (typelib, header->shared_library); - /* note that NULL shlib means to open the main app, which is allowed */ + /* shared-library is a comma-separated list of libraries */ + shlibs = g_strsplit (shlib_str, ",", 0); - if (shlib_str != NULL) + /* We load all passed libs unconditionally as if the same library is loaded + * again with dlopen(), the same file handle will be returned. See bug: + * http://bugzilla.gnome.org/show_bug.cgi?id=555294 + */ + for (i = 0; shlibs[i]; i++) { - gchar **shlibs; - gint i; + GModule *module; - /* shared-library is a comma-separated list of libraries */ - shlibs = g_strsplit (shlib_str, ",", 0); - - /* We load all passed libs unconditionally as if the same library is loaded - * again with dlopen(), the same file handle will be returned. See bug: - * http://bugzilla.gnome.org/show_bug.cgi?id=555294 + /* Glade's autoconnect feature and OpenGL's extension mechanism + * as used by Clutter rely on dlopen(NULL) to work as a means of + * accessing the app's symbols. This keeps us from using + * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well; + * in general libraries are not expecting multiple copies of + * themselves and are not expecting to be unloaded. So we just + * load modules globally for now. */ - for (i = 0; shlibs[i]; i++) + + module = g_module_open (shlibs[i], G_MODULE_BIND_LAZY); + + if (module == NULL) { - GModule *module; + GString *shlib_full = g_string_new (shlibs[i]); - /* Glade's autoconnect feature and OpenGL's extension mechanism - * as used by Clutter rely on dlopen(NULL) to work as a means of - * accessing the app's symbols. This keeps us from using - * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well; - * in general libraries are not expecting multiple copies of - * themselves and are not expecting to be unloaded. So we just - * load modules globally for now. - */ - - module = g_module_open (shlibs[i], G_MODULE_BIND_LAZY); - - if (module == NULL) - { - GString *shlib_full = g_string_new (shlibs[i]); - - /* Prefix with "lib", try both .la and .so */ - if (!g_str_has_prefix (shlib_full->str, "lib")) - g_string_prepend (shlib_full, "lib"); - g_string_append (shlib_full, ".la"); - module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); - if (module == NULL) - { - g_string_overwrite (shlib_full, strlen (shlib_full->str)-2, SHLIB_SUFFIX); - module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); - } - - g_string_free (shlib_full, TRUE); - } - - if (module == NULL) + /* Prefix with "lib", try both .la and .so */ + if (!g_str_has_prefix (shlib_full->str, "lib")) + g_string_prepend (shlib_full, "lib"); + g_string_append (shlib_full, ".la"); + module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); + if (module == NULL) { - g_warning ("Failed to load shared library '%s' referenced by the typelib: %s", - shlibs[i], g_module_error ()); + g_string_overwrite (shlib_full, strlen (shlib_full->str)-2, SHLIB_SUFFIX); + module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); } - else - { - typelib->modules = g_list_append (typelib->modules, module); - } - } - g_strfreev (shlibs); - } + g_string_free (shlib_full, TRUE); + } - /* we should make sure the app_module in the end of list so that - * it's last symbol source when loading any symbols from modules. - * See comments in g_typelib_symbol */ - app_module = g_module_open (NULL, G_MODULE_BIND_LAZY); - if (app_module) - typelib->modules = g_list_append (typelib->modules, app_module); + if (module == NULL) + { + g_warning ("Failed to load shared library '%s' referenced by the typelib: %s", + shlibs[i], g_module_error ()); + } + else + { + typelib->modules = g_list_append (typelib->modules, module); + } + } + + g_strfreev (shlibs); } + else + { + /* If there's no shared-library entry for this module, assume that + * the module is for the application. Some of the hand-written .gir files + * in gobject-introspection don't have shared-library entries, but no one + * is really going to be calling g_module_symbol on them either. + */ + GModule *module = g_module_open (NULL, 0); + if (module == NULL) + g_warning ("gtypelib.c: Failed to g_module_open (NULL): %s", g_module_error ()); + else + typelib->modules = g_list_prepend (typelib->modules, module); + } +} + +static inline void +_g_typelib_ensure_open (GTypelib *typelib) +{ + if (typelib->open_attempted) + return; + typelib->open_attempted = TRUE; + _g_typelib_do_dlopen (typelib); } /** @@ -2049,7 +2062,7 @@ g_typelib_new_from_memory (guchar *memory, gsize len) meta->len = len; meta->owns_memory = TRUE; meta->modules = NULL; - _g_typelib_init (meta); + return meta; } @@ -2072,7 +2085,7 @@ g_typelib_new_from_const_memory (const guchar *memory, gsize len) meta->len = len; meta->owns_memory = FALSE; meta->modules = NULL; - _g_typelib_init (meta); + return meta; } @@ -2094,7 +2107,7 @@ g_typelib_new_from_mapped_file (GMappedFile *mfile) meta->owns_memory = FALSE; meta->data = (guchar *) g_mapped_file_get_contents (mfile); meta->len = g_mapped_file_get_length (mfile); - _g_typelib_init (meta); + return meta; } @@ -2140,21 +2153,19 @@ gboolean g_typelib_symbol (GTypelib *typelib, const char *symbol_name, gpointer *symbol) { GList *l; + + _g_typelib_ensure_open (typelib); /* - * We want to be able to add symbols to an app or an auxiliary - * library to fill in gaps in an introspected library. However, - * normally we would only look for symbols in the main library - * (the first items in typelib->modules). - * - * A more elaborate solution is probably possible, but as a - * simple approach for now, if we fail to find a symbol we look - * for it in the global module (the last item in type->modules). - * - * This would not be very efficient if it happened often, since - * we always do the failed lookup above first, but very few - * symbols should be outside of the main libraries in - * typelib->modules so it doesn't matter. + * The reason for having multiple modules dates from gir-repository + * when it was desired to inject code (accessors, etc.) into an + * existing library. In that situation, the first module listed + * will be the custom one, which overrides the main one. A bit + * inefficient, but the problem will go away when gir-repository + * does. + * + * For modules with no shared library, we dlopen'd the current + * process above. */ for (l = typelib->modules; l; l = l->next) { diff --git a/gtypelib.h b/gtypelib.h index 2827543a0..488c1b33b 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -1021,6 +1021,7 @@ struct _GTypelib { gboolean owns_memory; GMappedFile *mfile; GList *modules; + gboolean open_attempted; }; DirEntry *g_typelib_get_dir_entry (GTypelib *typelib, From 5f6b975d8765f33eee5504be029f5b00d84cb09c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 4 Sep 2009 16:52:35 -0400 Subject: [PATCH 237/692] Bug 593322 - Fix unref of GIUnresolvedInfo instances We are treating GIUnresolvedInfo as a GIBaseInfo, but the structures had drifted out of sync. Add a repository pointer and bring them back into sync. Based on a report and patch from Jan Hudec --- ginfo.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ginfo.c b/ginfo.c index e7b0b8bd7..19723dd18 100644 --- a/ginfo.c +++ b/ginfo.c @@ -30,21 +30,28 @@ struct _GIBaseInfo { + /* Keep this part in sync with GIUnresolvedInfo below */ gint type; gint ref_count; GIRepository *repository; GIBaseInfo *container; + /* Resolved specific */ + GTypelib *typelib; guint32 offset; }; struct _GIUnresolvedInfo { + /* Keep this part in sync with GIBaseInfo above */ gint type; gint ref_count; + GIRepository *repository; GIBaseInfo *container; + /* Unresolved specific */ + const gchar *name; const gchar *namespace; }; @@ -196,6 +203,7 @@ g_info_from_entry (GIRepository *repository, unresolved->type = GI_INFO_TYPE_UNRESOLVED; unresolved->ref_count = 1; + unresolved->repository = repository; unresolved->container = NULL; unresolved->name = name; unresolved->namespace = namespace; From 7e7f7599b9299493a34589aad75d258e57cf9035 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 4 Sep 2009 17:02:14 -0400 Subject: [PATCH 238/692] Correctly ref repository in GIUnresolvedInfo Followup to previous patch. --- ginfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ginfo.c b/ginfo.c index 19723dd18..eef3cd6e7 100644 --- a/ginfo.c +++ b/ginfo.c @@ -203,7 +203,7 @@ g_info_from_entry (GIRepository *repository, unresolved->type = GI_INFO_TYPE_UNRESOLVED; unresolved->ref_count = 1; - unresolved->repository = repository; + unresolved->repository = g_object_ref (repository); unresolved->container = NULL; unresolved->name = name; unresolved->namespace = namespace; From 6b5a358371cc23386d1e74b4a374d8422a8a1125 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 19 Oct 2009 18:18:14 -0400 Subject: [PATCH 239/692] Use best known derived parent In the case where a known class derives from a hidden one, we want to use the most-derived parent class, rather than simply falling back to GObject. Example: ShellEmbedWidget in gnome-shell derives from ClutterGLXTexturePixmap from clutter, which is a hidden class. ClutterGLXTexturePixmap's parent itself is ClutterX11TexturePixmap, which is also hidden. But its parent is ClutterTexture, which we do know. Use that. https://bugzilla.gnome.org/show_bug.cgi?id=598993 --- gdump.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/gdump.c b/gdump.c index 519672aa7..b4a3e8eb9 100644 --- a/gdump.c +++ b/gdump.c @@ -154,7 +154,27 @@ dump_object_type (GType type, const char *symbol, GOutputStream *out) escaped_printf (out, " str); + + g_string_free (parent_str, TRUE); + } if (G_TYPE_IS_ABSTRACT (type)) escaped_printf (out, " abstract=\"1\""); From 8ba5a13d175ce0868bd03083f0862cb340feaca1 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 4 Nov 2009 11:43:13 -0500 Subject: [PATCH 240/692] [gtypelib.h] Document SimpleTypeBlob more --- gtypelib.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gtypelib.h b/gtypelib.h index 488c1b33b..015682e20 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -303,6 +303,20 @@ typedef struct { * @offset: Offset relative to header->types that points to a TypeBlob. * Unlike other offsets, this is in words (ie 32bit units) rather * than bytes. + * + * The SimpleTypeBlob is the general purpose "reference to a type" construct, used + * in method parameters, returns, callback definitions, fields, constants, etc. + * It's actually just a 32 bit integer which you can see from the union definition. + * This is for efficiency reasons, since there are so many references to types. + * + * SimpleTypeBlob is divided into two cases; first, if "reserved" and "reserved2", the + * type tag for a basic type is embedded in the "tag" bits. This allows e.g. + * GI_TYPE_TAG_UTF8, GI_TYPE_TAG_INT and the like to be embedded directly without + * taking up extra space. + * + * References to "interfaces" (objects, interfaces) are more complicated; In this case, + * the integer is actually an offset into the directory (see above). Because the header + * is larger than 2^8=256 bits, all offsets will have one of the upper 24 bits set. */ typedef union { From 03dc6a590bb7b435e54b265ba67abaa61f4c2dc6 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 9 Nov 2009 19:17:23 +0100 Subject: [PATCH 241/692] Implement callbacks as part of struct fields. Fixes #557383 gir: embed inside typelib: if a field contains a callback, store it just after the FieldBlob girepository API: no additions --- ginfo.c | 67 +++++++++++++++++++++++++++++++++++++++++--------- girepository.h | 6 ++--- girnode.c | 34 ++++++++++++++++++++----- girnode.h | 1 + giroffsets.c | 9 ++++++- girparser.c | 20 ++++++++++++++- gtypelib.c | 35 +++++++++++++++++--------- gtypelib.h | 4 ++- 8 files changed, 142 insertions(+), 34 deletions(-) diff --git a/ginfo.c b/ginfo.c index eef3cd6e7..1f14cb6f3 100644 --- a/ginfo.c +++ b/ginfo.c @@ -134,6 +134,7 @@ struct _GIArgInfo struct _GITypeInfo { GIBaseInfo base; + gboolean is_embedded; }; struct _GIUnionInfo @@ -154,7 +155,10 @@ g_info_new_full (GIInfoType type, g_return_val_if_fail (container != NULL || repository != NULL, NULL); - info = g_new0 (GIBaseInfo, 1); + if (type == GI_INFO_TYPE_TYPE) + info = (GIBaseInfo *)g_new0 (GITypeInfo, 1); + else + info = g_new0 (GIBaseInfo, 1); info->ref_count = 1; info->type = type; @@ -643,9 +647,13 @@ g_type_info_new (GIBaseInfo *container, guint32 offset) { SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset]; + GITypeInfo *type_info; - return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, typelib, + type_info = (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, typelib, (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset); + type_info->is_embedded = FALSE; + + return type_info; } /** @@ -876,7 +884,9 @@ g_type_info_get_tag (GITypeInfo *info) GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - if (type->flags.reserved == 0 && type->flags.reserved2 == 0) + if (info->is_embedded) + return GI_TYPE_TAG_INTERFACE; + else if (type->flags.reserved == 0 && type->flags.reserved2 == 0) return type->flags.tag; else { @@ -920,7 +930,11 @@ g_type_info_get_interface (GITypeInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; - + + if (info->is_embedded) + return (GIBaseInfo *) g_info_new (type->offset, base, base->typelib, + base->offset); + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->typelib->data[base->offset]; @@ -1100,8 +1114,21 @@ GITypeInfo * g_field_info_get_type (GIFieldInfo *info) { GIBaseInfo *base = (GIBaseInfo *)info; - - return g_type_info_new (base, base->typelib, base->offset + G_STRUCT_OFFSET (FieldBlob, type)); + Header *header = (Header *)base->typelib->data; + FieldBlob *blob = (FieldBlob *)&base->typelib->data[base->offset]; + GITypeInfo *type_info; + + if (blob->has_embedded_type) + { + type_info = (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, + (GIBaseInfo*)info, base->typelib, + base->offset + header->field_blob_size); + type_info->is_embedded = TRUE; + } + else + return g_type_info_new (base, base->typelib, base->offset + G_STRUCT_OFFSET (FieldBlob, type)); + + return type_info; } /* GIRegisteredTypeInfo functions */ @@ -1161,16 +1188,35 @@ g_struct_info_get_n_fields (GIStructInfo *info) return blob->n_fields; } +static gint32 +g_struct_get_field_offset (GIStructInfo *info, + gint n) +{ + GIBaseInfo *base = (GIBaseInfo *)info; + Header *header = (Header *)base->typelib->data; + guint32 offset = base->offset + header->struct_blob_size; + gint i; + FieldBlob *field_blob; + + for (i = 0; i < n; i++) + { + field_blob = (FieldBlob *)&base->typelib->data[offset]; + offset += header->field_blob_size; + if (field_blob->has_embedded_type) + offset += header->callback_blob_size; + } + + return offset; +} + GIFieldInfo * g_struct_info_get_field (GIStructInfo *info, gint n) { GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->typelib, - base->offset + header->struct_blob_size + - n * header->field_blob_size); + g_struct_get_field_offset (info, n)); } gint @@ -1191,8 +1237,7 @@ g_struct_info_get_method (GIStructInfo *info, Header *header = (Header *)base->typelib->data; gint offset; - offset = base->offset + header->struct_blob_size - + blob->n_fields * header->field_blob_size + offset = g_struct_get_field_offset (info, blob->n_fields) + n * header->function_blob_size; return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, base->typelib, offset); diff --git a/girepository.h b/girepository.h index 559be1ee3..c881c8bbb 100644 --- a/girepository.h +++ b/girepository.h @@ -162,17 +162,17 @@ typedef enum GI_INFO_TYPE_CALLBACK, GI_INFO_TYPE_STRUCT, GI_INFO_TYPE_BOXED, - GI_INFO_TYPE_ENUM, + GI_INFO_TYPE_ENUM, /* 5 */ GI_INFO_TYPE_FLAGS, GI_INFO_TYPE_OBJECT, GI_INFO_TYPE_INTERFACE, GI_INFO_TYPE_CONSTANT, - GI_INFO_TYPE_ERROR_DOMAIN, + GI_INFO_TYPE_ERROR_DOMAIN, /* 10 */ GI_INFO_TYPE_UNION, GI_INFO_TYPE_VALUE, GI_INFO_TYPE_SIGNAL, GI_INFO_TYPE_VFUNC, - GI_INFO_TYPE_PROPERTY, + GI_INFO_TYPE_PROPERTY, /* 15 */ GI_INFO_TYPE_FIELD, GI_INFO_TYPE_ARG, GI_INFO_TYPE_TYPE, diff --git a/girnode.c b/girnode.c index 22e821e01..9f6234532 100644 --- a/girnode.c +++ b/girnode.c @@ -279,6 +279,7 @@ g_ir_node_free (GIrNode *node) g_free (node->name); g_ir_node_free ((GIrNode *)field->type); + g_ir_node_free ((GIrNode *)field->callback); } break; @@ -508,7 +509,13 @@ g_ir_node_get_size (GIrNode *node) break; case G_IR_NODE_FIELD: - size = sizeof (FieldBlob); + { + GIrNodeField *field = (GIrNodeField *)node; + + size = sizeof (FieldBlob); + if (field->callback) + size += g_ir_node_get_size ((GIrNode *)field->callback); + } break; case G_IR_NODE_CONSTANT: @@ -797,7 +804,10 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size = sizeof (FieldBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); - size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->type); + if (field->callback) + size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->callback); + else + size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->type); } break; @@ -1587,8 +1597,6 @@ g_ir_node_build_typelib (GIrNode *node, FieldBlob *blob; blob = (FieldBlob *)&data[*offset]; - /* We handle the size member specially below, so subtract it */ - *offset += sizeof (FieldBlob) - sizeof (SimpleTypeBlob); blob->name = write_string (node->name, strings, data, offset2); blob->readable = field->readable; @@ -1600,8 +1608,22 @@ g_ir_node_build_typelib (GIrNode *node, else blob->struct_offset = 0xFFFF; /* mark as unknown */ - g_ir_node_build_typelib ((GIrNode *)field->type, - node, build, offset, offset2); + if (field->callback) + { + blob->has_embedded_type = TRUE; + blob->type.offset = GI_INFO_TYPE_CALLBACK; + *offset += sizeof (FieldBlob); + g_ir_node_build_typelib ((GIrNode *)field->callback, + node, build, offset, offset2); + } + else + { + blob->has_embedded_type = FALSE; + /* We handle the size member specially below, so subtract it */ + *offset += sizeof (FieldBlob) - sizeof (SimpleTypeBlob); + g_ir_node_build_typelib ((GIrNode *)field->type, + node, build, offset, offset2); + } } break; diff --git a/girnode.h b/girnode.h index 238593aee..c1b2369cf 100644 --- a/girnode.h +++ b/girnode.h @@ -230,6 +230,7 @@ struct _GIrNodeField gboolean writable; gint bits; gint offset; + GIrNodeFunction *callback; GIrNodeType *type; }; diff --git a/giroffsets.c b/giroffsets.c index d83474646..8354bc51b 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -303,7 +303,14 @@ get_field_size_alignment (GIrNodeField *field, who = g_strdup_printf ("field %s.%s.%s", module->name, parent_node->name, ((GIrNode *)field)->name); - success = get_type_size_alignment (field->type, module, modules, size, alignment, who); + if (field->callback) + { + *size = ffi_type_pointer.size; + *alignment = ffi_type_pointer.alignment; + success = TRUE; + } + else + success = get_type_size_alignment (field->type, module, modules, size, alignment, who); g_free (who); return success; diff --git a/girparser.c b/girparser.c index 9387d2529..1bbe59fd8 100644 --- a/girparser.c +++ b/girparser.c @@ -101,6 +101,7 @@ struct _ParseContext GList *type_stack; GList *type_parameters; int type_depth; + gboolean in_embedded_type; }; #define CURRENT_NODE(ctx) ((GIrNode *)((ctx)->node_stack->data)) @@ -719,6 +720,10 @@ start_function (GMarkupParseContext *context, strcmp (element_name, "method") == 0 || strcmp (element_name, "callback") == 0); break; + case STATE_STRUCT_FIELD: + ctx->in_embedded_type = TRUE; + found = (found || strcmp (element_name, "callback") == 0); + break; default: break; } @@ -782,6 +787,13 @@ start_function (GMarkupParseContext *context, ctx->current_module->entries = g_list_append (ctx->current_module->entries, function); } + else if (ctx->current_typed) + { + GIrNodeField *field; + + field = (GIrNodeField *)ctx->current_typed; + field->callback = function; + } else switch (CURRENT_NODE (ctx)->type) { @@ -2902,7 +2914,13 @@ end_element_handler (GMarkupParseContext *context, } else { - if (CURRENT_NODE (ctx)->type == G_IR_NODE_INTERFACE) + g_debug("case STATE_FUNCTION %d", CURRENT_NODE (ctx)->type); + if (ctx->in_embedded_type) + { + ctx->in_embedded_type = FALSE; + state_switch (ctx, STATE_STRUCT_FIELD); + } + else if (CURRENT_NODE (ctx)->type == G_IR_NODE_INTERFACE) state_switch (ctx, STATE_INTERFACE); else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT) state_switch (ctx, STATE_CLASS); diff --git a/gtypelib.c b/gtypelib.c index e7572ea51..30f796174 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1016,10 +1016,12 @@ validate_value_blob (GTypelib *typelib, } static gboolean -validate_field_blob (GTypelib *typelib, +validate_field_blob (ValidateContext *ctx, guint32 offset, GError **error) { + GTypelib *typelib = ctx->typelib; + Header *header = (Header *)typelib->data; FieldBlob *blob; if (typelib->len < offset + sizeof (FieldBlob)) @@ -1035,10 +1037,15 @@ validate_field_blob (GTypelib *typelib, if (!validate_name (typelib, "field", typelib->data, blob->name, error)) return FALSE; - - if (!validate_type_blob (typelib, - offset + G_STRUCT_OFFSET (FieldBlob, type), - 0, FALSE, error)) + + if (blob->has_embedded_type) + { + if (!validate_callback_blob (ctx, offset + header->field_blob_size, error)) + return FALSE; + } + else if (!validate_type_blob (typelib, + offset + G_STRUCT_OFFSET (FieldBlob, type), + 0, FALSE, error)) return FALSE; return TRUE; @@ -1209,6 +1216,7 @@ validate_struct_blob (ValidateContext *ctx, GTypelib *typelib = ctx->typelib; StructBlob *blob; gint i; + guint32 field_offset; if (typelib->len < offset + sizeof (StructBlob)) { @@ -1266,20 +1274,25 @@ validate_struct_blob (ValidateContext *ctx, return FALSE; } + field_offset = offset + sizeof (StructBlob); for (i = 0; i < blob->n_fields; i++) { - if (!validate_field_blob (typelib, - offset + sizeof (StructBlob) + - i * sizeof (FieldBlob), + FieldBlob *blob = (FieldBlob*) &typelib->data[field_offset]; + + if (!validate_field_blob (ctx, + field_offset, error)) return FALSE; + + field_offset += sizeof (FieldBlob); + if (blob->has_embedded_type) + field_offset += sizeof (CallbackBlob); } for (i = 0; i < blob->n_methods; i++) { if (!validate_function_blob (ctx, - offset + sizeof (StructBlob) + - blob->n_fields * sizeof (FieldBlob) + + field_offset + i * sizeof (FunctionBlob), blob_type, error)) @@ -1532,7 +1545,7 @@ validate_object_blob (ValidateContext *ctx, for (i = 0; i < blob->n_fields; i++, offset2 += sizeof (FieldBlob)) { - if (!validate_field_blob (typelib, offset2, error)) + if (!validate_field_blob (ctx, offset2, error)) return FALSE; } diff --git a/gtypelib.h b/gtypelib.h index 015682e20..26486afc5 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -622,6 +622,7 @@ typedef struct { * @name: The name of the field. * @readable: * @writable: How the field may be accessed. + * @has_embedded_type: An anonymous type follows the FieldBlob. * @bits: If this field is part of a bitfield, the number of bits which it * uses, otherwise 0. * @struct_offset: @@ -634,7 +635,8 @@ typedef struct { guint8 readable :1; guint8 writable :1; - guint8 reserved :6; + guint8 has_embedded_type :1; + guint8 reserved :5; guint8 bits; guint16 struct_offset; From 43f1c2db178373c0bfd62feec441c8c72c5e7ff2 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Tue, 20 Oct 2009 20:33:33 +0100 Subject: [PATCH 242/692] Add g_ir_ffi_convert_arguments --- girffi.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ girffi.h | 2 + 2 files changed, 114 insertions(+) diff --git a/girffi.c b/girffi.c index a001b7d78..b6c35c7c7 100644 --- a/girffi.c +++ b/girffi.c @@ -108,6 +108,118 @@ g_ir_ffi_get_ffi_type (GITypeTag tag) return NULL; } +GArgument * +g_ir_ffi_convert_arguments(GICallableInfo *callable_info, void **args) +{ + gint num_args, i; + GIArgInfo *arg_info; + GITypeInfo *arg_type; + GITypeTag tag; + GArgument *g_args; + + num_args = g_callable_info_get_n_args (callable_info); + g_args = g_new0 (GArgument, num_args); + + for (i = 0; i < num_args; i++) + { + arg_info = g_callable_info_get_arg (callable_info, i); + arg_type = g_arg_info_get_type (arg_info); + tag = g_type_info_get_tag (arg_type); + + switch (tag) + { + case GI_TYPE_TAG_BOOLEAN: + g_args[i].v_boolean = *(gboolean *) args[i]; + break; + case GI_TYPE_TAG_INT8: + g_args[i].v_int8 = *(gint8 *) args[i]; + break; + case GI_TYPE_TAG_UINT8: + g_args[i].v_uint8 = *(guint8 *) args[i]; + break; + case GI_TYPE_TAG_INT16: + g_args[i].v_int16 = *(gint16 *) args[i]; + break; + case GI_TYPE_TAG_UINT16: + g_args[i].v_uint16 = *(guint16 *) args[i]; + break; + case GI_TYPE_TAG_INT32: + g_args[i].v_int32 = *(gint32 *) args[i]; + break; + case GI_TYPE_TAG_UINT32: + g_args[i].v_uint32 = *(guint32 *) args[i]; + break; + case GI_TYPE_TAG_LONG: + case GI_TYPE_TAG_INT64: + g_args[i].v_int64 = *(glong *) args[i]; + break; + case GI_TYPE_TAG_ULONG: + case GI_TYPE_TAG_UINT64: + g_args[i].v_uint64 = *(glong *) args[i]; + break; + case GI_TYPE_TAG_INT: + case GI_TYPE_TAG_SSIZE: + case GI_TYPE_TAG_SIZE: + g_args[i].v_int32 = *(gint *) args[i]; + break; + case GI_TYPE_TAG_UINT: + g_args[i].v_uint32 = *(guint *) args[i]; + break; + case GI_TYPE_TAG_FLOAT: + g_args[i].v_float = *(gfloat *) args[i]; + break; + case GI_TYPE_TAG_DOUBLE: + g_args[i].v_double = *(gdouble *) args[i]; + break; + case GI_TYPE_TAG_UTF8: + g_args[i].v_string = *(gchar **) args[i]; + break; + case GI_TYPE_TAG_INTERFACE: + { + GIBaseInfo *interface; + GIInfoType interface_type; + + interface = g_type_info_get_interface (arg_type); + interface_type = g_base_info_get_type (interface); + + if (interface_type == GI_INFO_TYPE_OBJECT || + interface_type == GI_INFO_TYPE_INTERFACE) + { + g_args[i].v_pointer = *(gpointer *) args[i]; + g_base_info_unref (interface); + break; + } + + else if (interface_type == GI_INFO_TYPE_ENUM || + interface_type == GI_INFO_TYPE_FLAGS) + { + g_args[i].v_double = *(double *) args[i]; + g_base_info_unref (interface); + break; + } + else if (interface_type == GI_INFO_TYPE_STRUCT) + { + g_args[i].v_pointer = *(gpointer *) args[i]; + g_base_info_unref (interface); + break; + } + + g_base_info_unref (interface); + } + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: + g_args[i].v_pointer = *(gpointer *) args[i]; + break; + default: + g_args[i].v_pointer = 0; + } + + g_base_info_unref ((GIBaseInfo *) arg_info); + g_base_info_unref ((GIBaseInfo *) arg_type); + } + return g_args; +} + /** * g_callable_info_get_ffi_arg_types: * @callable_info: a callable info from a typelib diff --git a/girffi.h b/girffi.h index a7d28766a..e931cfbf3 100644 --- a/girffi.h +++ b/girffi.h @@ -32,6 +32,8 @@ typedef void (*GIFFIClosureCallback) (ffi_cif *, void *); ffi_type * g_ir_ffi_get_ffi_type (GITypeTag tag); +GArgument * g_ir_ffi_convert_arguments (GICallableInfo *callable_info, + void **args); ffi_type ** g_callable_info_get_ffi_arg_types (GICallableInfo *callable_info); ffi_type * g_callable_info_get_ffi_return_type (GICallableInfo *callable_info); ffi_closure * g_callable_info_prepare_closure (GICallableInfo *callable_info, From 46e36632afc7944ee96165758424cb02cdf5967c Mon Sep 17 00:00:00 2001 From: Simon van der Linden Date: Fri, 20 Nov 2009 10:38:36 +0100 Subject: [PATCH 243/692] Add a method to compare infos Add g_base_info_equal. --- ginfo.c | 20 ++++++++++++++++++++ girepository.h | 2 ++ 2 files changed, 22 insertions(+) diff --git a/ginfo.c b/ginfo.c index 1f14cb6f3..2aacb7630 100644 --- a/ginfo.c +++ b/ginfo.c @@ -554,6 +554,26 @@ g_base_info_get_typelib (GIBaseInfo *info) return info->typelib; } +/* + * g_base_info_equal: + * @info1: A #GIBaseInfo + * @info2: A #GIBaseInfo + * + * Compare two #GIBaseInfo. + * + * Using pointer comparison is not practical since many functions return + * different instances of #GIBaseInfo that refers to the same part of the + * TypeLib; use this function instead to do #GIBaseInfo comparisons. + * + * Return value: TRUE if and only if @info1 equals @info2. + */ +gboolean +g_base_info_equal (GIBaseInfo *info1, GIBaseInfo *info2) +{ + /* Compare the TypeLib pointers, which are mmapped. */ + return info1->typelib->data + info1->offset == info2->typelib->data + info2->offset; +} + /* GIFunctionInfo functions */ const gchar * g_function_info_get_symbol (GIFunctionInfo *info) diff --git a/girepository.h b/girepository.h index c881c8bbb..c30418a80 100644 --- a/girepository.h +++ b/girepository.h @@ -203,6 +203,8 @@ gboolean g_base_info_iterate_attributes (GIBaseInfo *info, char **value); GIBaseInfo * g_base_info_get_container (GIBaseInfo *info); GTypelib * g_base_info_get_typelib (GIBaseInfo *info); +gboolean g_base_info_equal (GIBaseInfo *info1, + GIBaseInfo *info2); GIBaseInfo * g_info_new (GIInfoType type, GIBaseInfo *container, From a668ac5303e62cf1fc7ed176acb57d001ca61dc2 Mon Sep 17 00:00:00 2001 From: Maxim Ermilov Date: Wed, 2 Dec 2009 10:18:24 -0200 Subject: [PATCH 244/692] Plug a leak in g_callable_info_get_ffi_return_type https://bugzilla.gnome.org/show_bug.cgi?id=603526 --- girffi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/girffi.c b/girffi.c index b6c35c7c7..b06399c2b 100644 --- a/girffi.c +++ b/girffi.c @@ -271,6 +271,9 @@ g_callable_info_get_ffi_return_type (GICallableInfo *callable_info) return_type = g_callable_info_get_return_type (callable_info); type_tag = g_type_info_get_tag (return_type); + + g_base_info_unref((GIBaseInfo*)return_type); + return g_ir_ffi_get_ffi_type (type_tag); } From 4b796371aeb3ef9f3ad6af711a9fc1b3855fa421 Mon Sep 17 00:00:00 2001 From: Maxim Ermilov Date: Fri, 27 Nov 2009 18:49:51 +0300 Subject: [PATCH 245/692] GI_TYPE_TAG_VOID != ffi_type_void https://bugzilla.gnome.org/show_bug.cgi?id=603157 --- girffi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/girffi.c b/girffi.c index b06399c2b..83e654274 100644 --- a/girffi.c +++ b/girffi.c @@ -31,8 +31,6 @@ g_ir_ffi_get_ffi_type (GITypeTag tag) { switch (tag) { - case GI_TYPE_TAG_VOID: - return &ffi_type_void; case GI_TYPE_TAG_BOOLEAN: return &ffi_type_uint; case GI_TYPE_TAG_INT8: @@ -100,6 +98,7 @@ g_ir_ffi_get_ffi_type (GITypeTag tag) case GI_TYPE_TAG_GSLIST: case GI_TYPE_TAG_GHASH: case GI_TYPE_TAG_ERROR: + case GI_TYPE_TAG_VOID: return &ffi_type_pointer; } From a7c04b69de03cd9ff441658e732c4a138849b03a Mon Sep 17 00:00:00 2001 From: Jasper Lievisse Adriaanse Date: Wed, 2 Dec 2009 10:38:58 -0200 Subject: [PATCH 246/692] Fix build on OpenBSD Due to a missing header, gobject-introspection fails to compile on OpenBSD. And only due to headers-including-headers practice this doesn't blow up on many other platforms. https://bugzilla.gnome.org/show_bug.cgi?id=596226 --- girffi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/girffi.c b/girffi.c index 83e654274..d7c52f696 100644 --- a/girffi.c +++ b/girffi.c @@ -18,10 +18,13 @@ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ + +#include +#include + #include #include #include -#include #include #include "girffi.h" #include "girepository.h" From c22f11f1b85c6cac8282a78d4839c987a5383fcf Mon Sep 17 00:00:00 2001 From: Iain Nicol Date: Mon, 23 Nov 2009 18:52:40 +0000 Subject: [PATCH 247/692] Remove some unportable integral type size assumptions https://bugzilla.gnome.org/show_bug.cgi?id=602762 --- gfield.c | 17 +++++++++++++++-- girffi.c | 16 ++++++++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/gfield.c b/gfield.c index 94c2fb597..486211fa9 100644 --- a/gfield.c +++ b/gfield.c @@ -2,6 +2,7 @@ #include "girepository.h" #include "girffi.h" +#include "config.h" /** * g_field_info_get_field: @@ -92,7 +93,13 @@ g_field_info_get_field (GIFieldInfo *field_info, result = TRUE; break; case GI_TYPE_TAG_TIME_T: - value->v_long = G_STRUCT_MEMBER(time_t, mem, offset); +#if SIZEOF_TIME_T == 4 + value->v_int32 = G_STRUCT_MEMBER(time_t, mem, offset); +#elif SIZEOF_TIME_T == 8 + value->v_int64 = G_STRUCT_MEMBER(time_t, mem, offset); +#else +# error "Unexpected size for time_t: not 4 or 8" +#endif result = TRUE; break; case GI_TYPE_TAG_UTF8: @@ -292,7 +299,13 @@ g_field_info_set_field (GIFieldInfo *field_info, result = TRUE; break; case GI_TYPE_TAG_TIME_T: - G_STRUCT_MEMBER(time_t, mem, offset) = value->v_long; +#if SIZEOF_TIME_T == 4 + G_STRUCT_MEMBER(time_t, mem, offset) = value->v_int32; +#elif SIZEOF_TIME_T == 8 + G_STRUCT_MEMBER(time_t, mem, offset) = value->v_int64; +#else +# error "Unexpected size for time_t: not 4 or 8" +#endif result = TRUE; break; case GI_TYPE_TAG_UTF8: diff --git a/girffi.c b/girffi.c index d7c52f696..d67cbf65c 100644 --- a/girffi.c +++ b/girffi.c @@ -152,20 +152,28 @@ g_ir_ffi_convert_arguments(GICallableInfo *callable_info, void **args) g_args[i].v_uint32 = *(guint32 *) args[i]; break; case GI_TYPE_TAG_LONG: + g_args[i].v_long = *(glong *) args[i]; + break; case GI_TYPE_TAG_INT64: - g_args[i].v_int64 = *(glong *) args[i]; + g_args[i].v_int64 = *(gint64 *) args[i]; break; case GI_TYPE_TAG_ULONG: + g_args[i].v_ulong = *(gulong *) args[i]; + break; case GI_TYPE_TAG_UINT64: - g_args[i].v_uint64 = *(glong *) args[i]; + g_args[i].v_uint64 = *(guint64 *) args[i]; break; case GI_TYPE_TAG_INT: + g_args[i].v_int = *(gint *) args[i]; + break; case GI_TYPE_TAG_SSIZE: + g_args[i].v_ssize = *(gssize *) args[i]; + break; case GI_TYPE_TAG_SIZE: - g_args[i].v_int32 = *(gint *) args[i]; + g_args[i].v_size = *(gsize *) args[i]; break; case GI_TYPE_TAG_UINT: - g_args[i].v_uint32 = *(guint *) args[i]; + g_args[i].v_uint = *(guint *) args[i]; break; case GI_TYPE_TAG_FLOAT: g_args[i].v_float = *(gfloat *) args[i]; From e3cd97d492737bc10407ecf727017b228ed99962 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 9 Dec 2009 11:21:30 +0000 Subject: [PATCH 248/692] Make error more verbose in parser By printing the function when arguments are missing https://bugzilla.gnome.org/show_bug.cgi?id=604161 --- girparser.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/girparser.c b/girparser.c index 1bbe59fd8..77416177d 100644 --- a/girparser.c +++ b/girparser.c @@ -840,11 +840,14 @@ start_function (GMarkupParseContext *context, } static void -parse_param_transfer (GIrNodeParam *param, const gchar *transfer) +parse_param_transfer (GIrNodeParam *param, const gchar *transfer, const gchar *name) { if (transfer == NULL) { - g_warning ("required attribute 'transfer-ownership' missing"); + if (!name) + g_warning ("required attribute 'transfer-ownership' missing"); + else + g_warning ("required attribute 'transfer-ownership' for function '%s'", name); } else if (strcmp (transfer, "none") == 0) { @@ -948,7 +951,7 @@ start_parameter (GMarkupParseContext *context, else param->allow_none = FALSE; - parse_param_transfer (param, transfer); + parse_param_transfer (param, transfer, name); if (scope && strcmp (scope, "call") == 0) param->scope = GI_SCOPE_TYPE_CALL; @@ -1950,7 +1953,7 @@ start_return_value (GMarkupParseContext *context, state_switch (ctx, STATE_FUNCTION_RETURN); transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); - parse_param_transfer (param, transfer); + parse_param_transfer (param, transfer, NULL); switch (CURRENT_NODE (ctx)->type) { From 91459565ef2a9d93be8aeb3f3bfe75899f61dddd Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Wed, 9 Dec 2009 16:39:31 -0200 Subject: [PATCH 249/692] Improve the error message --- gtypelib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtypelib.c b/gtypelib.c index 30f796174..bc9896d2b 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -251,7 +251,7 @@ validate_name (GTypelib *typelib, g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID, - "The %s is contains invalid characters: %s", + "The %s contains invalid characters: '%s'", msg, name); return FALSE; } From 954312db601ef8c9fa454270ab0ab1cf01414351 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 15 Dec 2009 11:00:52 -0200 Subject: [PATCH 250/692] Revert "GI_TYPE_TAG_VOID != ffi_type_void" This reverts commit 28cccba737ec2214da66b0d74059278162cf5fd0. --- girffi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/girffi.c b/girffi.c index d67cbf65c..c057afaf7 100644 --- a/girffi.c +++ b/girffi.c @@ -34,6 +34,8 @@ g_ir_ffi_get_ffi_type (GITypeTag tag) { switch (tag) { + case GI_TYPE_TAG_VOID: + return &ffi_type_void; case GI_TYPE_TAG_BOOLEAN: return &ffi_type_uint; case GI_TYPE_TAG_INT8: @@ -101,7 +103,6 @@ g_ir_ffi_get_ffi_type (GITypeTag tag) case GI_TYPE_TAG_GSLIST: case GI_TYPE_TAG_GHASH: case GI_TYPE_TAG_ERROR: - case GI_TYPE_TAG_VOID: return &ffi_type_pointer; } From b50974235bfc7b6593cd5b8ee5f4101be33d4601 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Sun, 13 Dec 2009 11:53:04 -0800 Subject: [PATCH 251/692] protect on null retval ffi_call does not protect against retval being NULL, resulting in a segfault. https://bugzilla.gnome.org/show_bug.cgi?id=604472 --- ginvoke.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ginvoke.c b/ginvoke.c index 70d81f8e9..136860c90 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -247,6 +247,7 @@ g_function_info_invoke (GIFunctionInfo *info, if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_invoke_args, rtype, atypes) != FFI_OK) goto out; + g_return_val_if_fail (return_value, FALSE); ffi_call (&cif, func, return_value, args); if (local_error) @@ -435,6 +436,7 @@ gi_cclosure_marshal_generic (GClosure *closure, if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, rtype, atypes) != FFI_OK) return; + g_return_val_if_fail (rvalue, FALSE); ffi_call (&cif, marshal_data ? marshal_data : cc->callback, rvalue, args); if (return_gvalue && G_VALUE_TYPE (return_gvalue)) From e568b5f9fdea933c031b6a5f50622b5489e9f805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Thu, 3 Dec 2009 21:35:23 +0100 Subject: [PATCH 252/692] Substitute deprecated Glib symbol: g_mapped_file_free glib-compat.h file created to use g_mapped_file_unref only if glib >= 2.22 is available https://bugzilla.gnome.org/show_bug.cgi?id=603727 --- Makefile.am | 19 ++++++++++--------- girepository.c | 3 ++- glib-compat.h | 24 ++++++++++++++++++++++++ gtypelib.c | 3 ++- 4 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 glib-compat.h diff --git a/Makefile.am b/Makefile.am index 1a449b2a4..1279f07a5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,16 +9,17 @@ lib_LTLIBRARIES = libgirepository-1.0.la noinst_LTLIBRARIES = libgirepository-parser.la libgirepository_1_0_la_SOURCES = \ - girepository.c \ - gtypelib.h \ - gtypelib.c \ - gfield.c \ - ginfo.h \ - ginfo.c \ - girffi.c \ - girffi.h \ gdump.c \ - ginvoke.c + gfield.c \ + ginfo.c \ + ginfo.h \ + ginvoke.c \ + girepository.c \ + girffi.c \ + girffi.h \ + glib-compat.h \ + gtypelib.c \ + gtypelib.h libgirepository_1_0_la_CPPFLAGS = $(GIREPO_CFLAGS) libgirepository_1_0_la_LIBADD = $(GIREPO_LIBS) diff --git a/girepository.c b/girepository.c index e68182988..e590616da 100644 --- a/girepository.c +++ b/girepository.c @@ -31,6 +31,7 @@ #include "girepository.h" #include "gtypelib.h" #include "ginfo.h" +#include "glib-compat.h" #include "config.h" @@ -1039,7 +1040,7 @@ compare_candidate_reverse (struct NamespaceVersionCandidadate *c1, static void free_candidate (struct NamespaceVersionCandidadate *candidate) { - g_mapped_file_free (candidate->mfile); + g_mapped_file_unref (candidate->mfile); g_free (candidate->path); g_free (candidate->version); g_free (candidate); diff --git a/glib-compat.h b/glib-compat.h new file mode 100644 index 000000000..a4d3e4994 --- /dev/null +++ b/glib-compat.h @@ -0,0 +1,24 @@ +/* GObject introspection: Compatibility definitions + * + * Copyright (C) 2009 Javier Jardón + * + * 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. + */ + + +#if !GLIB_CHECK_VERSION(2,22,0) +#define g_mapped_file_unref(x) g_mapped_file_free(x) +#endif diff --git a/gtypelib.c b/gtypelib.c index bc9896d2b..a34ca32f0 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -26,6 +26,7 @@ #include "config.h" #include "gtypelib.h" +#include "glib-compat.h" typedef struct { GTypelib *typelib; @@ -2134,7 +2135,7 @@ void g_typelib_free (GTypelib *typelib) { if (typelib->mfile) - g_mapped_file_free (typelib->mfile); + g_mapped_file_unref (typelib->mfile); else if (typelib->owns_memory) g_free (typelib->data); From 3bff396653f62a44d3760b385256d34572c767af Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 16 Dec 2009 18:16:31 -0500 Subject: [PATCH 253/692] Fix compilation warning in ginvoke.c --- ginvoke.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ginvoke.c b/ginvoke.c index 136860c90..bf89d6ce3 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -436,7 +436,7 @@ gi_cclosure_marshal_generic (GClosure *closure, if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, rtype, atypes) != FFI_OK) return; - g_return_val_if_fail (rvalue, FALSE); + g_return_if_fail (rvalue != NULL); ffi_call (&cif, marshal_data ? marshal_data : cc->callback, rvalue, args); if (return_gvalue && G_VALUE_TYPE (return_gvalue)) From f2f0625622fec0653e5e98858468962248d0a3c6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 7 Dec 2009 11:54:18 -0500 Subject: [PATCH 254/692] [girffi] Clean up API, add g_function_info_prep_invoker Rather than having bindings use g_function_info_invoke, which is basically a toy/demo API, export a convenience utility function which takes the introspection information and sets up things we need to pass to libffi. Then invocation can be done directly to libffi by a binding. As part of this work, remove some (unused by gjs) public functions from the girffi API, and instead export a function to map to libffi which can work semi-correctly. https://bugzilla.gnome.org/show_bug.cgi?id=604074 --- Makefile.am | 1 + ginvoke.c | 15 +-- girffi-private.h | 32 ++++++ girffi.c | 262 ++++++++++++++++++++++++----------------------- girffi.h | 23 ++++- giroffsets.c | 4 +- 6 files changed, 190 insertions(+), 147 deletions(-) create mode 100644 girffi-private.h diff --git a/Makefile.am b/Makefile.am index 1279f07a5..770dceb7f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,6 +17,7 @@ libgirepository_1_0_la_SOURCES = \ girepository.c \ girffi.c \ girffi.h \ + girffi-private.h \ glib-compat.h \ gtypelib.c \ gtypelib.h diff --git a/ginvoke.c b/ginvoke.c index bf89d6ce3..ff0495040 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -37,17 +37,6 @@ g_invoke_error_quark (void) return quark; } -#include "ffi.h" - -static ffi_type * -get_ffi_type (GITypeInfo *info) -{ - if (g_type_info_is_pointer (info)) - return &ffi_type_pointer; - else - return g_ir_ffi_get_ffi_type (g_type_info_get_tag (info)); -} - /** * g_function_info_invoke: * @info: a #GIFunctionInfo describing the function to invoke @@ -116,7 +105,7 @@ g_function_info_invoke (GIFunctionInfo *info, throws = g_function_info_get_flags (info) & GI_FUNCTION_THROWS; tinfo = g_callable_info_get_return_type ((GICallableInfo *)info); - rtype = get_ffi_type (tinfo); + rtype = g_type_info_get_ffi_type (tinfo); g_base_info_unref ((GIBaseInfo *)tinfo); in_pos = 0; @@ -159,7 +148,7 @@ g_function_info_invoke (GIFunctionInfo *info, { case GI_DIRECTION_IN: tinfo = g_arg_info_get_type (ainfo); - atypes[i+offset] = get_ffi_type (tinfo); + atypes[i+offset] = g_type_info_get_ffi_type (tinfo); g_base_info_unref ((GIBaseInfo *)tinfo); if (in_pos >= n_in_args) diff --git a/girffi-private.h b/girffi-private.h new file mode 100644 index 000000000..645335006 --- /dev/null +++ b/girffi-private.h @@ -0,0 +1,32 @@ +/* GObject introspection: Private helper functions for ffi integration + * + * Copyright (C) 2008, 2009 Red Hat, Inc + * + * 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 __GIRFFI_PRIVATE_H__ +#define __GIRFFI_PRIVATE_H__ + +#include "girffi.h" + +G_BEGIN_DECLS + +ffi_type * g_ir_ffi_get_ffi_type (GITypeTag type_tag, gboolean is_pointer); + +G_END_DECLS + +#endif /* __GIRFFI_PRIVATE_H__ */ diff --git a/girffi.c b/girffi.c index c057afaf7..c757eeab4 100644 --- a/girffi.c +++ b/girffi.c @@ -30,12 +30,11 @@ #include "girepository.h" ffi_type * -g_ir_ffi_get_ffi_type (GITypeTag tag) +g_ir_ffi_get_ffi_type (GITypeTag tag, + gboolean is_pointer) { switch (tag) { - case GI_TYPE_TAG_VOID: - return &ffi_type_void; case GI_TYPE_TAG_BOOLEAN: return &ffi_type_uint; case GI_TYPE_TAG_INT8: @@ -104,131 +103,28 @@ g_ir_ffi_get_ffi_type (GITypeTag tag) case GI_TYPE_TAG_GHASH: case GI_TYPE_TAG_ERROR: return &ffi_type_pointer; + case GI_TYPE_TAG_VOID: + if (is_pointer) + return &ffi_type_pointer; + else + return &ffi_type_void; } g_assert_not_reached (); return NULL; -} +} -GArgument * -g_ir_ffi_convert_arguments(GICallableInfo *callable_info, void **args) +/** + * g_type_info_get_ffi_type: + * @info: A #GITypeInfo + * + * Returns: A #ffi_type corresponding to the platform default C ABI for @info. + */ +ffi_type * +g_type_info_get_ffi_type (GITypeInfo *info) { - gint num_args, i; - GIArgInfo *arg_info; - GITypeInfo *arg_type; - GITypeTag tag; - GArgument *g_args; - - num_args = g_callable_info_get_n_args (callable_info); - g_args = g_new0 (GArgument, num_args); - - for (i = 0; i < num_args; i++) - { - arg_info = g_callable_info_get_arg (callable_info, i); - arg_type = g_arg_info_get_type (arg_info); - tag = g_type_info_get_tag (arg_type); - - switch (tag) - { - case GI_TYPE_TAG_BOOLEAN: - g_args[i].v_boolean = *(gboolean *) args[i]; - break; - case GI_TYPE_TAG_INT8: - g_args[i].v_int8 = *(gint8 *) args[i]; - break; - case GI_TYPE_TAG_UINT8: - g_args[i].v_uint8 = *(guint8 *) args[i]; - break; - case GI_TYPE_TAG_INT16: - g_args[i].v_int16 = *(gint16 *) args[i]; - break; - case GI_TYPE_TAG_UINT16: - g_args[i].v_uint16 = *(guint16 *) args[i]; - break; - case GI_TYPE_TAG_INT32: - g_args[i].v_int32 = *(gint32 *) args[i]; - break; - case GI_TYPE_TAG_UINT32: - g_args[i].v_uint32 = *(guint32 *) args[i]; - break; - case GI_TYPE_TAG_LONG: - g_args[i].v_long = *(glong *) args[i]; - break; - case GI_TYPE_TAG_INT64: - g_args[i].v_int64 = *(gint64 *) args[i]; - break; - case GI_TYPE_TAG_ULONG: - g_args[i].v_ulong = *(gulong *) args[i]; - break; - case GI_TYPE_TAG_UINT64: - g_args[i].v_uint64 = *(guint64 *) args[i]; - break; - case GI_TYPE_TAG_INT: - g_args[i].v_int = *(gint *) args[i]; - break; - case GI_TYPE_TAG_SSIZE: - g_args[i].v_ssize = *(gssize *) args[i]; - break; - case GI_TYPE_TAG_SIZE: - g_args[i].v_size = *(gsize *) args[i]; - break; - case GI_TYPE_TAG_UINT: - g_args[i].v_uint = *(guint *) args[i]; - break; - case GI_TYPE_TAG_FLOAT: - g_args[i].v_float = *(gfloat *) args[i]; - break; - case GI_TYPE_TAG_DOUBLE: - g_args[i].v_double = *(gdouble *) args[i]; - break; - case GI_TYPE_TAG_UTF8: - g_args[i].v_string = *(gchar **) args[i]; - break; - case GI_TYPE_TAG_INTERFACE: - { - GIBaseInfo *interface; - GIInfoType interface_type; - - interface = g_type_info_get_interface (arg_type); - interface_type = g_base_info_get_type (interface); - - if (interface_type == GI_INFO_TYPE_OBJECT || - interface_type == GI_INFO_TYPE_INTERFACE) - { - g_args[i].v_pointer = *(gpointer *) args[i]; - g_base_info_unref (interface); - break; - } - - else if (interface_type == GI_INFO_TYPE_ENUM || - interface_type == GI_INFO_TYPE_FLAGS) - { - g_args[i].v_double = *(double *) args[i]; - g_base_info_unref (interface); - break; - } - else if (interface_type == GI_INFO_TYPE_STRUCT) - { - g_args[i].v_pointer = *(gpointer *) args[i]; - g_base_info_unref (interface); - break; - } - - g_base_info_unref (interface); - } - case GI_TYPE_TAG_GLIST: - case GI_TYPE_TAG_GSLIST: - g_args[i].v_pointer = *(gpointer *) args[i]; - break; - default: - g_args[i].v_pointer = 0; - } - - g_base_info_unref ((GIBaseInfo *) arg_info); - g_base_info_unref ((GIBaseInfo *) arg_type); - } - return g_args; + return g_ir_ffi_get_ffi_type (g_type_info_get_tag (info), g_type_info_is_pointer (info)); } /** @@ -238,7 +134,7 @@ g_ir_ffi_convert_arguments(GICallableInfo *callable_info, void **args) * Return value: an array of ffi_type*. The array itself * should be freed using g_free() after use. */ -ffi_type ** +static ffi_type ** g_callable_info_get_ffi_arg_types (GICallableInfo *callable_info) { ffi_type **arg_types; @@ -254,8 +150,7 @@ g_callable_info_get_ffi_arg_types (GICallableInfo *callable_info) { GIArgInfo *arg_info = g_callable_info_get_arg (callable_info, i); GITypeInfo *arg_type = g_arg_info_get_type (arg_info); - GITypeTag type_tag = g_type_info_get_tag (arg_type); - arg_types[i] = g_ir_ffi_get_ffi_type (type_tag); + arg_types[i] = g_type_info_get_ffi_type (arg_type); g_base_info_unref ((GIBaseInfo *)arg_info); g_base_info_unref ((GIBaseInfo *)arg_type); } @@ -272,20 +167,133 @@ g_callable_info_get_ffi_arg_types (GICallableInfo *callable_info) * a #GICallableInfo * Return value: the ffi_type for the return value */ -ffi_type * +static ffi_type * g_callable_info_get_ffi_return_type (GICallableInfo *callable_info) { GITypeInfo *return_type; GITypeTag type_tag; + ffi_type *return_ffi_type; g_return_val_if_fail (callable_info != NULL, NULL); return_type = g_callable_info_get_return_type (callable_info); type_tag = g_type_info_get_tag (return_type); - + return_ffi_type = g_type_info_get_ffi_type (return_type); g_base_info_unref((GIBaseInfo*)return_type); + + return return_ffi_type; +} - return g_ir_ffi_get_ffi_type (type_tag); +/** + * g_function_info_prep_invoker: + * @info: A #GIFunctionInfo + * @invoker: Output invoker structure + * @error: A #GError + * + * Initialize the caller-allocated @invoker structure with a cache + * of information needed to invoke the C function corresponding to + * @info with the platform's default ABI. + * + * A primary intent of this function is that a dynamic structure allocated + * by a language binding could contain a #GIFunctionInvoker structure + * inside the binding's function mapping. + */ +gboolean +g_function_info_prep_invoker (GIFunctionInfo *info, + GIFunctionInvoker *invoker, + GError **error) +{ + const char *symbol; + ffi_type *rtype; + ffi_type **atypes; + GITypeInfo *tinfo; + GIArgInfo *ainfo; + gboolean is_method; + gboolean throws; + gint n_args, n_invoke_args, i; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (invoker != NULL, FALSE); + + symbol = g_function_info_get_symbol ((GIFunctionInfo*) info); + + if (!g_typelib_symbol (g_base_info_get_typelib((GIBaseInfo *) info), + symbol, &(invoker->native_address))) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_SYMBOL_NOT_FOUND, + "Could not locate %s: %s", symbol, g_module_error ()); + + return FALSE; + } + + is_method = (g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0 + && (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR) == 0; + throws = g_function_info_get_flags (info) & GI_FUNCTION_THROWS; + + tinfo = g_callable_info_get_return_type ((GICallableInfo *)info); + rtype = g_type_info_get_ffi_type (tinfo); + g_base_info_unref ((GIBaseInfo *)tinfo); + + n_args = g_callable_info_get_n_args ((GICallableInfo *)info); + if (is_method) + n_invoke_args = n_args+1; + else + n_invoke_args = n_args; + + if (throws) + /* Add an argument for the GError */ + n_invoke_args ++; + + /* TODO: avoid malloc here? */ + atypes = g_malloc0 (sizeof (ffi_type*) * n_invoke_args); + + if (is_method) + { + atypes[0] = &ffi_type_pointer; + } + for (i = 0; i < n_args; i++) + { + int offset = (is_method ? 1 : 0); + ainfo = g_callable_info_get_arg ((GICallableInfo *)info, i); + switch (g_arg_info_get_direction (ainfo)) + { + case GI_DIRECTION_IN: + tinfo = g_arg_info_get_type (ainfo); + atypes[i+offset] = g_type_info_get_ffi_type (tinfo); + g_base_info_unref ((GIBaseInfo *)tinfo); + break; + case GI_DIRECTION_OUT: + case GI_DIRECTION_INOUT: + atypes[i+offset] = &ffi_type_pointer; + break; + default: + g_assert_not_reached (); + } + g_base_info_unref ((GIBaseInfo *)ainfo); + } + + if (throws) + { + atypes[n_invoke_args - 1] = &ffi_type_pointer; + } + + return ffi_prep_cif (&(invoker->cif), FFI_DEFAULT_ABI, n_invoke_args, rtype, atypes) == FFI_OK; +} + +/** + * g_function_info_invoker_destroy: + * @invoker: A #GIFunctionInvoker + * + * Release all resources allocated for the internals of @invoker; callers + * are responsible for freeing any resources allocated for the structure + * itself however. + */ +void +g_function_invoker_destroy (GIFunctionInvoker *invoker) +{ + g_free (invoker->cif.arg_types); } /** diff --git a/girffi.h b/girffi.h index e931cfbf3..7961177ee 100644 --- a/girffi.h +++ b/girffi.h @@ -31,11 +31,24 @@ typedef void (*GIFFIClosureCallback) (ffi_cif *, void **, void *); -ffi_type * g_ir_ffi_get_ffi_type (GITypeTag tag); -GArgument * g_ir_ffi_convert_arguments (GICallableInfo *callable_info, - void **args); -ffi_type ** g_callable_info_get_ffi_arg_types (GICallableInfo *callable_info); -ffi_type * g_callable_info_get_ffi_return_type (GICallableInfo *callable_info); +typedef struct _GIFunctionInvoker GIFunctionInvoker; + +struct _GIFunctionInvoker { + ffi_cif cif; + gpointer native_address; + + gpointer padding[3]; +}; + +ffi_type * g_type_info_get_ffi_type (GITypeInfo *info); + +gboolean g_function_info_prep_invoker (GIFunctionInfo *info, + GIFunctionInvoker *invoker, + GError **error); + +void g_function_invoker_destroy (GIFunctionInvoker *invoker); + + ffi_closure * g_callable_info_prepare_closure (GICallableInfo *callable_info, ffi_cif *cif, GIFFIClosureCallback callback, diff --git a/giroffsets.c b/giroffsets.c index 8354bc51b..96ff57648 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -18,7 +18,7 @@ * Boston, MA 02111-1307, USA. */ -#include "girffi.h" +#include "girffi-private.h" #include "girnode.h" /* The C standard specifies that an enumeration can be any char or any signed @@ -262,7 +262,7 @@ get_type_size_alignment (GIrNodeType *type, } else { - type_ffi = g_ir_ffi_get_ffi_type (type->tag); + type_ffi = g_ir_ffi_get_ffi_type (type->tag, type->is_pointer); if (type_ffi == &ffi_type_void) { From e6ac69fccdf57427b80bec5b2fe3be11bfde91e4 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 7 Dec 2009 18:35:06 -0500 Subject: [PATCH 255/692] Allow stack allocating GIBaseInfo, add stack retrieval variants We don't want to malloc each GIBaseInfo when they can be used in function invocation; instead, allow stack allocation. There were a lot of structure typedefs which were actually just exactly the same as GIBaseInfo, with the one exception of GITypeInfo. Instead, just put the single GITypeInfo boolean inside GIBaseInfo as a bit in a bitfield. GIBaseInfo is still opaque publicly; GIRealInfo is the new internal structure. Using this, add new functions to retrieve arguments and argument types on the stack. https://bugzilla.gnome.org/show_bug.cgi?id=604074 --- ginfo.c | 1237 +++++++++++++++++++++++++----------------------- girepository.h | 71 ++- 2 files changed, 691 insertions(+), 617 deletions(-) diff --git a/ginfo.c b/ginfo.c index 2aacb7630..b11cc8fc2 100644 --- a/ginfo.c +++ b/ginfo.c @@ -28,11 +28,19 @@ #include "gtypelib.h" #include "ginfo.h" -struct _GIBaseInfo +typedef struct _GIRealInfo GIRealInfo; + +/** + * We just use one structure for all of the info object + * types; in general, we should be reading data directly + * from the typelib, and not having computed data in + * per-type structures. + */ +struct _GIRealInfo { /* Keep this part in sync with GIUnresolvedInfo below */ - gint type; - gint ref_count; + gint32 type; + gint32 ref_count; GIRepository *repository; GIBaseInfo *container; @@ -40,13 +48,18 @@ struct _GIBaseInfo GTypelib *typelib; guint32 offset; + + guint32 type_is_embedded : 1; /* Used by GITypeInfo */ + guint32 reserved : 31; + + gpointer reserved2[4]; }; struct _GIUnresolvedInfo { /* Keep this part in sync with GIBaseInfo above */ - gint type; - gint ref_count; + gint32 type; + gint32 ref_count; GIRepository *repository; GIBaseInfo *container; @@ -56,137 +69,68 @@ struct _GIUnresolvedInfo const gchar *namespace; }; -struct _GICallableInfo +static void +g_info_init (GIRealInfo *info, + GIInfoType type, + GIRepository *repository, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset) { - GIBaseInfo base; -}; + memset (info, 0, sizeof (GIRealInfo)); -struct _GIFunctionInfo -{ - GICallableInfo callable; -}; - -struct _GICallbackInfo -{ - GICallableInfo callable; -}; - -struct _GIRegisteredTypeInfo -{ - GIBaseInfo base; -}; - -struct _GIStructInfo -{ - GIRegisteredTypeInfo registered; -}; - -struct _GIEnumInfo -{ - GIRegisteredTypeInfo registered; -}; - -struct _GIObjectInfo -{ - GIRegisteredTypeInfo registered; -}; - -struct _GIInterfaceInfo -{ - GIRegisteredTypeInfo registered; -}; - -struct _GIConstantInfo -{ - GIBaseInfo base; -}; - -struct _GIValueInfo -{ - GIBaseInfo base; -}; - -struct _GISignalInfo -{ - GICallableInfo callable; -}; - -struct _GIVFuncInfo -{ - GICallableInfo callable; -}; - -struct _GIPropertyInfo -{ - GIBaseInfo base; -}; - -struct _GIFieldInfo -{ - GIBaseInfo base; -}; - -struct _GIArgInfo -{ - GIBaseInfo base; -}; - -struct _GITypeInfo -{ - GIBaseInfo base; - gboolean is_embedded; -}; - -struct _GIUnionInfo -{ - GIRegisteredTypeInfo registered; -}; - - -/* info creation */ -GIBaseInfo * -g_info_new_full (GIInfoType type, - GIRepository *repository, - GIBaseInfo *container, - GTypelib *typelib, - guint32 offset) -{ - GIBaseInfo *info; - - g_return_val_if_fail (container != NULL || repository != NULL, NULL); - - if (type == GI_INFO_TYPE_TYPE) - info = (GIBaseInfo *)g_new0 (GITypeInfo, 1); - else - info = g_new0 (GIBaseInfo, 1); - - info->ref_count = 1; + /* Invalid refcount used to flag stack-allocated infos */ + info->ref_count = 0xFFFF; info->type = type; info->typelib = typelib; info->offset = offset; if (container) - info->container = g_base_info_ref (container); + info->container = container; - info->repository = g_object_ref (repository); + g_assert (G_IS_IREPOSITORY (repository)); + info->repository = repository; +} - return info; +/* info creation */ +GIBaseInfo * +g_info_new_full (GIInfoType type, + GIRepository *repository, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset) +{ + GIRealInfo *info; + + g_return_val_if_fail (container != NULL || repository != NULL, NULL); + + info = g_new (GIRealInfo, 1); + + g_info_init (info, type, repository, container, typelib, offset); + info->ref_count = 1; + + if (container && ((GIRealInfo *) container)->ref_count != 0xFFFF) + g_base_info_ref (info->container); + + g_object_ref (info->repository); + + return (GIBaseInfo*)info; } GIBaseInfo * g_info_new (GIInfoType type, - GIBaseInfo *container, - GTypelib *typelib, - guint32 offset) + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset) { - return g_info_new_full (type, container->repository, container, typelib, offset); + return g_info_new_full (type, ((GIRealInfo*)container)->repository, container, typelib, offset); } static GIBaseInfo * g_info_from_entry (GIRepository *repository, - GTypelib *typelib, - guint16 index) + GTypelib *typelib, + guint16 index) { GIBaseInfo *result; DirEntry *entry = g_typelib_get_dir_entry (typelib, index); @@ -200,31 +144,34 @@ g_info_from_entry (GIRepository *repository, result = g_irepository_find_by_name (repository, namespace, name); if (result == NULL) - { - GIUnresolvedInfo *unresolved; + { + GIUnresolvedInfo *unresolved; - unresolved = g_new0 (GIUnresolvedInfo, 1); + unresolved = g_new0 (GIUnresolvedInfo, 1); - unresolved->type = GI_INFO_TYPE_UNRESOLVED; - unresolved->ref_count = 1; - unresolved->repository = g_object_ref (repository); - unresolved->container = NULL; - unresolved->name = name; - unresolved->namespace = namespace; + unresolved->type = GI_INFO_TYPE_UNRESOLVED; + unresolved->ref_count = 1; + unresolved->repository = g_object_ref (repository); + unresolved->container = NULL; + unresolved->name = name; + unresolved->namespace = namespace; - return (GIBaseInfo*)unresolved; - } - return result; + return (GIBaseInfo *)unresolved; + } + return (GIBaseInfo *)result; } - return result; + return (GIBaseInfo *)result; } /* GIBaseInfo functions */ GIBaseInfo * g_base_info_ref (GIBaseInfo *info) { - info->ref_count++; + GIRealInfo *rinfo = (GIRealInfo*)info; + + g_assert (rinfo->ref_count != 0xFFFF); + ((GIRealInfo*)info)->ref_count++; return info; } @@ -232,18 +179,20 @@ g_base_info_ref (GIBaseInfo *info) void g_base_info_unref (GIBaseInfo *info) { - g_assert (info->ref_count > 0); - info->ref_count--; + GIRealInfo *rinfo = (GIRealInfo*)info; - if (!info->ref_count) + g_assert (rinfo->ref_count > 0 && rinfo->ref_count != 0xFFFF); + rinfo->ref_count--; + + if (!rinfo->ref_count) { - if (info->container) - g_base_info_unref (info->container); + if (rinfo->container && ((GIRealInfo *) rinfo->container)->ref_count != 0xFFFF) + g_base_info_unref (rinfo->container); - if (info->repository) - g_object_unref (info->repository); + if (rinfo->repository) + g_object_unref (rinfo->repository); - g_free (info); + g_free (rinfo); } } @@ -251,14 +200,15 @@ GIInfoType g_base_info_get_type (GIBaseInfo *info) { - return info->type; + return ((GIRealInfo*)info)->type; } const gchar * g_base_info_get_name (GIBaseInfo *info) { - g_assert (info->ref_count > 0); - switch (info->type) + GIRealInfo *rinfo = (GIRealInfo*)info; + g_assert (rinfo->ref_count > 0); + switch (rinfo->type) { case GI_INFO_TYPE_FUNCTION: case GI_INFO_TYPE_CALLBACK: @@ -272,64 +222,64 @@ g_base_info_get_name (GIBaseInfo *info) case GI_INFO_TYPE_ERROR_DOMAIN: case GI_INFO_TYPE_UNION: { - CommonBlob *blob = (CommonBlob *)&info->typelib->data[info->offset]; + CommonBlob *blob = (CommonBlob *)&rinfo->typelib->data[rinfo->offset]; - return g_typelib_get_string (info->typelib, blob->name); + return g_typelib_get_string (rinfo->typelib, blob->name); } break; case GI_INFO_TYPE_VALUE: { - ValueBlob *blob = (ValueBlob *)&info->typelib->data[info->offset]; + ValueBlob *blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset]; - return g_typelib_get_string (info->typelib, blob->name); + return g_typelib_get_string (rinfo->typelib, blob->name); } break; case GI_INFO_TYPE_SIGNAL: { - SignalBlob *blob = (SignalBlob *)&info->typelib->data[info->offset]; + SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; - return g_typelib_get_string (info->typelib, blob->name); + return g_typelib_get_string (rinfo->typelib, blob->name); } break; case GI_INFO_TYPE_PROPERTY: { - PropertyBlob *blob = (PropertyBlob *)&info->typelib->data[info->offset]; + PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset]; - return g_typelib_get_string (info->typelib, blob->name); + return g_typelib_get_string (rinfo->typelib, blob->name); } break; case GI_INFO_TYPE_VFUNC: { - VFuncBlob *blob = (VFuncBlob *)&info->typelib->data[info->offset]; + VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; - return g_typelib_get_string (info->typelib, blob->name); + return g_typelib_get_string (rinfo->typelib, blob->name); } break; case GI_INFO_TYPE_FIELD: { - FieldBlob *blob = (FieldBlob *)&info->typelib->data[info->offset]; + FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; - return g_typelib_get_string (info->typelib, blob->name); + return g_typelib_get_string (rinfo->typelib, blob->name); } break; case GI_INFO_TYPE_ARG: { - ArgBlob *blob = (ArgBlob *)&info->typelib->data[info->offset]; + ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - return g_typelib_get_string (info->typelib, blob->name); + return g_typelib_get_string (rinfo->typelib, blob->name); } break; case GI_INFO_TYPE_UNRESOLVED: { - GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info; + GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info; - return unresolved->name; + return unresolved->name; } break; case GI_INFO_TYPE_TYPE: @@ -344,24 +294,26 @@ g_base_info_get_name (GIBaseInfo *info) const gchar * g_base_info_get_namespace (GIBaseInfo *info) { - Header *header = (Header *)info->typelib->data; + GIRealInfo *rinfo = (GIRealInfo*) info; + Header *header = (Header *)rinfo->typelib->data; - g_assert (info->ref_count > 0); + g_assert (rinfo->ref_count > 0); - if (info->type == GI_INFO_TYPE_UNRESOLVED) + if (rinfo->type == GI_INFO_TYPE_UNRESOLVED) { GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info; return unresolved->namespace; } - return g_typelib_get_string (info->typelib, header->namespace); + return g_typelib_get_string (rinfo->typelib, header->namespace); } gboolean g_base_info_is_deprecated (GIBaseInfo *info) { - switch (info->type) + GIRealInfo *rinfo = (GIRealInfo*) info; + switch (rinfo->type) { case GI_INFO_TYPE_FUNCTION: case GI_INFO_TYPE_CALLBACK: @@ -374,33 +326,33 @@ g_base_info_is_deprecated (GIBaseInfo *info) case GI_INFO_TYPE_CONSTANT: case GI_INFO_TYPE_ERROR_DOMAIN: { - CommonBlob *blob = (CommonBlob *)&info->typelib->data[info->offset]; + CommonBlob *blob = (CommonBlob *)&rinfo->typelib->data[rinfo->offset]; - return blob->deprecated; + return blob->deprecated; } break; case GI_INFO_TYPE_VALUE: { - ValueBlob *blob = (ValueBlob *)&info->typelib->data[info->offset]; + ValueBlob *blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset]; - return blob->deprecated; + return blob->deprecated; } break; case GI_INFO_TYPE_SIGNAL: { - SignalBlob *blob = (SignalBlob *)&info->typelib->data[info->offset]; + SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; - return blob->deprecated; + return blob->deprecated; } break; case GI_INFO_TYPE_PROPERTY: { - PropertyBlob *blob = (PropertyBlob *)&info->typelib->data[info->offset]; + PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset]; - return blob->deprecated; + return blob->deprecated; } break; @@ -426,7 +378,7 @@ g_base_info_is_deprecated (GIBaseInfo *info) */ const gchar * g_base_info_get_attribute (GIBaseInfo *info, - const gchar *name) + const gchar *name) { GIAttributeIter iter = { 0, }; gchar *curname, *curvalue; @@ -455,15 +407,14 @@ cmp_attribute (const void *av, } static AttributeBlob * -find_first_attribute (GIBaseInfo *info) +find_first_attribute (GIRealInfo *rinfo) { - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; + Header *header = (Header *)rinfo->typelib->data; AttributeBlob blob, *first, *res, *previous; - blob.offset = base->offset; + blob.offset = rinfo->offset; - first = (AttributeBlob *) &base->typelib->data[header->attributes]; + first = (AttributeBlob *) &rinfo->typelib->data[header->attributes]; res = bsearch (&blob, first, header->n_attributes, header->attribute_blob_size, cmp_attribute); @@ -472,7 +423,7 @@ find_first_attribute (GIBaseInfo *info) return NULL; previous = res - 1; - while (previous >= first && previous->offset == base->offset) + while (previous >= first && previous->offset == rinfo->offset) { res = previous; previous = res - 1; @@ -520,23 +471,23 @@ g_base_info_iterate_attributes (GIBaseInfo *info, gchar **name, gchar **value) { - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; AttributeBlob *next, *after; - after = (AttributeBlob *) &base->typelib->data[header->attributes + + after = (AttributeBlob *) &rinfo->typelib->data[header->attributes + header->n_attributes * header->attribute_blob_size]; if (iter->data != NULL) next = (AttributeBlob *) iter->data; else - next = find_first_attribute (info); + next = find_first_attribute (rinfo); - if (next == NULL || next->offset != base->offset || next >= after) + if (next == NULL || next->offset != rinfo->offset || next >= after) return FALSE; - *name = (gchar*) g_typelib_get_string (base->typelib, next->name); - *value = (gchar*) g_typelib_get_string (base->typelib, next->value); + *name = (gchar*) g_typelib_get_string (rinfo->typelib, next->name); + *value = (gchar*) g_typelib_get_string (rinfo->typelib, next->value); iter->data = next + 1; return TRUE; @@ -545,13 +496,13 @@ g_base_info_iterate_attributes (GIBaseInfo *info, GIBaseInfo * g_base_info_get_container (GIBaseInfo *info) { - return info->container; + return ((GIRealInfo*)info)->container; } GTypelib * g_base_info_get_typelib (GIBaseInfo *info) { - return info->typelib; + return ((GIRealInfo*)info)->typelib; } /* @@ -571,25 +522,27 @@ gboolean g_base_info_equal (GIBaseInfo *info1, GIBaseInfo *info2) { /* Compare the TypeLib pointers, which are mmapped. */ - return info1->typelib->data + info1->offset == info2->typelib->data + info2->offset; + GIRealInfo *rinfo1 = (GIRealInfo*)info1; + GIRealInfo *rinfo2 = (GIRealInfo*)info2; + return rinfo1->typelib->data + rinfo1->offset == rinfo2->typelib->data + rinfo2->offset; } /* GIFunctionInfo functions */ const gchar * g_function_info_get_symbol (GIFunctionInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - FunctionBlob *blob = (FunctionBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; - return g_typelib_get_string (base->typelib, blob->symbol); + return g_typelib_get_string (rinfo->typelib, blob->symbol); } GIFunctionInfoFlags g_function_info_get_flags (GIFunctionInfo *info) { GIFunctionInfoFlags flags; - GIBaseInfo *base = (GIBaseInfo *)info; - FunctionBlob *blob = (FunctionBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; flags = 0; @@ -618,9 +571,9 @@ g_function_info_get_flags (GIFunctionInfo *info) GIPropertyInfo * g_function_info_get_property (GIFunctionInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - FunctionBlob *blob = (FunctionBlob *)&base->typelib->data[base->offset]; - GIInterfaceInfo *container = (GIInterfaceInfo *)base->container; + GIRealInfo *rinfo = (GIRealInfo *)info; + FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; + GIInterfaceInfo *container = (GIInterfaceInfo *)rinfo->container; return g_interface_info_get_property (container, blob->index); } @@ -628,20 +581,21 @@ g_function_info_get_property (GIFunctionInfo *info) GIVFuncInfo * g_function_info_get_vfunc (GIFunctionInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - FunctionBlob *blob = (FunctionBlob *)&base->typelib->data[base->offset]; - GIInterfaceInfo *container = (GIInterfaceInfo *)base->container; + GIRealInfo *rinfo = (GIRealInfo*)info; + FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; + GIInterfaceInfo *container = (GIInterfaceInfo *)rinfo->container; return g_interface_info_get_vfunc (container, blob->index); } - /* GICallableInfo functions */ static guint32 signature_offset (GICallableInfo *info) { + GIRealInfo *rinfo = (GIRealInfo*)info; int sigoff = -1; - switch (info->base.type) + + switch (rinfo->type) { case GI_INFO_TYPE_FUNCTION: sigoff = G_STRUCT_OFFSET (FunctionBlob, signature); @@ -657,23 +611,32 @@ signature_offset (GICallableInfo *info) break; } if (sigoff >= 0) - return *(guint32 *)&info->base.typelib->data[info->base.offset + sigoff]; + return *(guint32 *)&rinfo->typelib->data[rinfo->offset + sigoff]; return 0; } GITypeInfo * g_type_info_new (GIBaseInfo *container, - GTypelib *typelib, - guint32 offset) + GTypelib *typelib, + guint32 offset) { SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset]; - GITypeInfo *type_info; - type_info = (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, typelib, - (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset); - type_info->is_embedded = FALSE; + return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, typelib, + (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset); +} - return type_info; +static void +g_type_info_init (GIBaseInfo *info, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset) +{ + GIRealInfo *rinfo = (GIRealInfo*)container; + SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset]; + + g_info_init ((GIRealInfo*)info, GI_INFO_TYPE_TYPE, rinfo->repository, container, typelib, + (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset); } /** @@ -689,12 +652,36 @@ g_type_info_new (GIBaseInfo *container, GITypeInfo * g_callable_info_get_return_type (GICallableInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; + GIRealInfo *rinfo = (GIRealInfo *)info; guint32 offset; offset = signature_offset (info); - return g_type_info_new (base, base->typelib, offset); + return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, offset); +} + + +/** + * g_callable_info_load_return_type: + * @info: a #GICallableInfo + * @type: (out caller-allocates): Initialized with return type of @info + * + * Get information about a return value of callable; this + * function is a variant of g_callable_info_get_return_type() designed for stack + * allocation. + * + * The initialized @type must not be referenced after @info is deallocated. + */ +void +g_callable_info_load_return_type (GICallableInfo *info, + GITypeInfo *type) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + guint32 offset; + + offset = signature_offset (info); + + g_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, offset); } /** @@ -708,8 +695,8 @@ g_callable_info_get_return_type (GICallableInfo *info) gboolean g_callable_info_may_return_null (GICallableInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - SignatureBlob *blob = (SignatureBlob *)&base->typelib->data[signature_offset (info)]; + GIRealInfo *rinfo = (GIRealInfo *)info; + SignatureBlob *blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)]; return blob->may_return_null; } @@ -726,8 +713,8 @@ g_callable_info_may_return_null (GICallableInfo *info) GITransfer g_callable_info_get_caller_owns (GICallableInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - SignatureBlob *blob = (SignatureBlob *)&base->typelib->data[signature_offset (info)]; + GIRealInfo *rinfo = (GIRealInfo*) info; + SignatureBlob *blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)]; if (blob->caller_owns_return_value) return GI_TRANSFER_EVERYTHING; @@ -748,12 +735,12 @@ g_callable_info_get_caller_owns (GICallableInfo *info) gint g_callable_info_get_n_args (GICallableInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; + GIRealInfo *rinfo = (GIRealInfo *)info; gint offset; SignatureBlob *blob; offset = signature_offset (info); - blob = (SignatureBlob *)&base->typelib->data[offset]; + blob = (SignatureBlob *)&rinfo->typelib->data[offset]; return blob->n_arguments; } @@ -769,24 +756,51 @@ g_callable_info_get_n_args (GICallableInfo *info) */ GIArgInfo * g_callable_info_get_arg (GICallableInfo *info, - gint n) + gint n) { - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; gint offset; offset = signature_offset (info); - return (GIArgInfo *) g_info_new (GI_INFO_TYPE_ARG, base, base->typelib, - offset + header->signature_blob_size + n * header->arg_blob_size); + return (GIArgInfo *) g_info_new (GI_INFO_TYPE_ARG, (GIBaseInfo*)info, rinfo->typelib, + offset + header->signature_blob_size + n * header->arg_blob_size); +} + +/** + * g_callable_info_load_arg: + * @info: a #GICallableInfo + * @n: the argument index to fetch + * @arg: (out caller-allocates): Initialize with argument number @n + * + * Get information about a particular argument of this callable; this + * function is a variant of g_callable_info_get_arg() designed for stack + * allocation. + * + * The initialized @arg must not be referenced after @info is deallocated. + */ +void +g_callable_info_load_arg (GICallableInfo *info, + gint n, + GIArgInfo *arg) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + gint offset; + + offset = signature_offset (info); + + g_info_init ((GIRealInfo*)arg, GI_INFO_TYPE_ARG, rinfo->repository, (GIBaseInfo*)info, rinfo->typelib, + offset + header->signature_blob_size + n * header->arg_blob_size); } /* GIArgInfo function */ GIDirection g_arg_info_get_direction (GIArgInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->in && blob->out) return GI_DIRECTION_INOUT; @@ -799,8 +813,8 @@ g_arg_info_get_direction (GIArgInfo *info) gboolean g_arg_info_is_return_value (GIArgInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->return_value; } @@ -808,8 +822,8 @@ g_arg_info_is_return_value (GIArgInfo *info) gboolean g_arg_info_is_dipper (GIArgInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->dipper; } @@ -817,8 +831,8 @@ g_arg_info_is_dipper (GIArgInfo *info) gboolean g_arg_info_is_optional (GIArgInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->optional; } @@ -826,8 +840,8 @@ g_arg_info_is_optional (GIArgInfo *info) gboolean g_arg_info_may_be_null (GIArgInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->allow_none; } @@ -835,8 +849,8 @@ g_arg_info_may_be_null (GIArgInfo *info) GITransfer g_arg_info_get_ownership_transfer (GIArgInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->transfer_ownership) return GI_TRANSFER_EVERYTHING; @@ -849,8 +863,8 @@ g_arg_info_get_ownership_transfer (GIArgInfo *info) GIScopeType g_arg_info_get_scope (GIArgInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->scope; } @@ -858,8 +872,8 @@ g_arg_info_get_scope (GIArgInfo *info) gint g_arg_info_get_closure (GIArgInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->closure; } @@ -867,32 +881,57 @@ g_arg_info_get_closure (GIArgInfo *info) gint g_arg_info_get_destroy (GIArgInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->destroy; } +/** + * g_arg_info_get_type: + * @info: A #GIArgInfo + * + * Returns: (transfer full): Information about the type of argument @info + */ GITypeInfo * g_arg_info_get_type (GIArgInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; + GIRealInfo *rinfo = (GIRealInfo *)info; - return g_type_info_new (base, base->typelib, base->offset + G_STRUCT_OFFSET (ArgBlob, arg_type)); + return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type)); +} + +/** + * g_arg_info_load_type: + * @info: A #GIArgInfo + * @type: (out caller-allocates): Initialized with information about type of @info + * + * Get information about a the type of given argument @info; this + * function is a variant of g_arg_info_get_type() designed for stack + * allocation. + * + * The initialized @type must not be referenced after @info is deallocated. + */ +void +g_arg_info_load_type (GIArgInfo *info, + GITypeInfo *type) +{ + GIRealInfo *rinfo = (GIRealInfo*) info; + g_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type)); } /* GITypeInfo functions */ gboolean g_type_info_is_pointer (GITypeInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (type->flags.reserved == 0 && type->flags.reserved2 == 0) return type->flags.pointer; else { - InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->typelib->data[base->offset]; + InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset]; return iface->pointer; } @@ -901,16 +940,16 @@ g_type_info_is_pointer (GITypeInfo *info) GITypeTag g_type_info_get_tag (GITypeInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - if (info->is_embedded) + if (rinfo->type_is_embedded) return GI_TYPE_TAG_INTERFACE; else if (type->flags.reserved == 0 && type->flags.reserved2 == 0) return type->flags.tag; else { - InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->typelib->data[base->offset]; + InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset]; return iface->tag; } @@ -918,49 +957,58 @@ g_type_info_get_tag (GITypeInfo *info) GITypeInfo * g_type_info_get_param_type (GITypeInfo *info, - gint n) + gint n) { - GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { - ParamTypeBlob *param = (ParamTypeBlob *)&base->typelib->data[base->offset]; + ParamTypeBlob *param = (ParamTypeBlob *)&rinfo->typelib->data[rinfo->offset]; 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->typelib, - base->offset + sizeof (ParamTypeBlob) - + sizeof (SimpleTypeBlob) * n); - break; - - default: ; - } + { + 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 ((GIBaseInfo*)info, rinfo->typelib, + rinfo->offset + sizeof (ParamTypeBlob) + + sizeof (SimpleTypeBlob) * n); + break; + default: + break; + } } - + return NULL; } +/** + * g_type_info_get_interface: + * @info: A #GITypeInfo + * + * For types which have #GI_TYPE_TAG_INTERFACE such as GObjects and boxed values, + * this function returns full information about the referenced type. You can then + * inspect the type of the returned #GIBaseInfo to further query whether it is + * a concrete GObject, a GInterface, a structure, etc. using g_base_info_get_type(). + */ GIBaseInfo * g_type_info_get_interface (GITypeInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - if (info->is_embedded) - return (GIBaseInfo *) g_info_new (type->offset, base, base->typelib, - base->offset); + if (rinfo->type_is_embedded) + return (GIBaseInfo *) g_info_new (type->offset, (GIBaseInfo*)info, rinfo->typelib, + rinfo->offset); if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { - InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->typelib->data[base->offset]; + InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->tag == GI_TYPE_TAG_INTERFACE) - return g_info_from_entry (base->repository, base->typelib, blob->interface); + return g_info_from_entry (rinfo->repository, rinfo->typelib, blob->interface); } return NULL; @@ -969,12 +1017,12 @@ g_type_info_get_interface (GITypeInfo *info) gint g_type_info_get_array_length (GITypeInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { - ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset]; + ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->tag == GI_TYPE_TAG_ARRAY) { @@ -989,12 +1037,12 @@ g_type_info_get_array_length (GITypeInfo *info) gint g_type_info_get_array_fixed_size (GITypeInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { - ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset]; + ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->tag == GI_TYPE_TAG_ARRAY) { @@ -1009,12 +1057,12 @@ g_type_info_get_array_fixed_size (GITypeInfo *info) gboolean g_type_info_is_zero_terminated (GITypeInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { - ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset]; + ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->tag == GI_TYPE_TAG_ARRAY) return blob->zero_terminated; @@ -1026,12 +1074,12 @@ g_type_info_is_zero_terminated (GITypeInfo *info) gint g_type_info_get_n_error_domains (GITypeInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { - ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->typelib->data[base->offset]; + ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->tag == GI_TYPE_TAG_ERROR) return blob->n_domains; @@ -1042,19 +1090,19 @@ g_type_info_get_n_error_domains (GITypeInfo *info) GIErrorDomainInfo * g_type_info_get_error_domain (GITypeInfo *info, - gint n) + gint n) { - GIBaseInfo *base = (GIBaseInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { - ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->typelib->data[base->offset]; + ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->tag == GI_TYPE_TAG_ERROR) - return (GIErrorDomainInfo *) g_info_from_entry (base->repository, - base->typelib, - blob->domains[n]); + return (GIErrorDomainInfo *) g_info_from_entry (rinfo->repository, + rinfo->typelib, + blob->domains[n]); } return NULL; @@ -1065,20 +1113,20 @@ g_type_info_get_error_domain (GITypeInfo *info, const gchar * g_error_domain_info_get_quark (GIErrorDomainInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ErrorDomainBlob *blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset]; - return g_typelib_get_string (base->typelib, blob->get_quark); + return g_typelib_get_string (rinfo->typelib, blob->get_quark); } GIInterfaceInfo * g_error_domain_info_get_codes (GIErrorDomainInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ErrorDomainBlob *blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset]; - return (GIInterfaceInfo *) g_info_from_entry (base->repository, - base->typelib, blob->error_codes); + return (GIInterfaceInfo *) g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->error_codes); } @@ -1086,8 +1134,8 @@ g_error_domain_info_get_codes (GIErrorDomainInfo *info) glong g_value_info_get_value (GIValueInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ValueBlob *blob = (ValueBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ValueBlob *blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset]; return (glong)blob->value; } @@ -1098,8 +1146,8 @@ g_field_info_get_flags (GIFieldInfo *info) { GIFieldInfoFlags flags; - GIBaseInfo *base = (GIBaseInfo *)info; - FieldBlob *blob = (FieldBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; flags = 0; @@ -1115,8 +1163,8 @@ g_field_info_get_flags (GIFieldInfo *info) gint g_field_info_get_size (GIFieldInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - FieldBlob *blob = (FieldBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->bits; } @@ -1124,8 +1172,8 @@ g_field_info_get_size (GIFieldInfo *info) gint g_field_info_get_offset (GIFieldInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - FieldBlob *blob = (FieldBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->struct_offset; } @@ -1133,33 +1181,33 @@ g_field_info_get_offset (GIFieldInfo *info) GITypeInfo * g_field_info_get_type (GIFieldInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - FieldBlob *blob = (FieldBlob *)&base->typelib->data[base->offset]; - GITypeInfo *type_info; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; + GIRealInfo *type_info; if (blob->has_embedded_type) { - type_info = (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, - (GIBaseInfo*)info, base->typelib, - base->offset + header->field_blob_size); - type_info->is_embedded = TRUE; + type_info = (GIRealInfo *) g_info_new (GI_INFO_TYPE_TYPE, + (GIBaseInfo*)info, rinfo->typelib, + rinfo->offset + header->field_blob_size); + type_info->type_is_embedded = TRUE; } else - return g_type_info_new (base, base->typelib, base->offset + G_STRUCT_OFFSET (FieldBlob, type)); + return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (FieldBlob, type)); - return type_info; + return (GIBaseInfo*)type_info; } /* GIRegisteredTypeInfo functions */ const gchar * g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->gtype_name) - return g_typelib_get_string (base->typelib, blob->gtype_name); + return g_typelib_get_string (rinfo->typelib, blob->gtype_name); return NULL; } @@ -1167,11 +1215,11 @@ g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info) const gchar * g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->gtype_init) - return g_typelib_get_string (base->typelib, blob->gtype_init); + return g_typelib_get_string (rinfo->typelib, blob->gtype_init); return NULL; } @@ -1181,6 +1229,7 @@ g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info) { const char *type_init; GType (* get_type_func) (void); + GIRealInfo *rinfo = (GIRealInfo*)info; type_init = g_registered_type_info_get_type_init (info); @@ -1190,7 +1239,7 @@ g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info) return G_TYPE_OBJECT; get_type_func = NULL; - if (!g_typelib_symbol (((GIBaseInfo*)info)->typelib, + if (!g_typelib_symbol (rinfo->typelib, type_init, (void**) &get_type_func)) return G_TYPE_NONE; @@ -1202,8 +1251,8 @@ g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info) gint g_struct_info_get_n_fields (GIStructInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_fields; } @@ -1212,15 +1261,15 @@ static gint32 g_struct_get_field_offset (GIStructInfo *info, gint n) { - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - guint32 offset = base->offset + header->struct_blob_size; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + guint32 offset = rinfo->offset + header->struct_blob_size; gint i; FieldBlob *field_blob; for (i = 0; i < n; i++) { - field_blob = (FieldBlob *)&base->typelib->data[offset]; + field_blob = (FieldBlob *)&rinfo->typelib->data[offset]; offset += header->field_blob_size; if (field_blob->has_embedded_type) offset += header->callback_blob_size; @@ -1231,19 +1280,19 @@ g_struct_get_field_offset (GIStructInfo *info, GIFieldInfo * g_struct_info_get_field (GIStructInfo *info, - gint n) + gint n) { - GIBaseInfo *base = (GIBaseInfo *)info; + GIRealInfo *rinfo = (GIRealInfo *)info; - return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->typelib, - g_struct_get_field_offset (info, n)); + return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, + g_struct_get_field_offset (info, n)); } gint g_struct_info_get_n_methods (GIStructInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_methods; } @@ -1252,35 +1301,35 @@ GIFunctionInfo * g_struct_info_get_method (GIStructInfo *info, gint n) { - GIBaseInfo *base = (GIBaseInfo *)info; - StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset]; - Header *header = (Header *)base->typelib->data; + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header = (Header *)rinfo->typelib->data; gint offset; - offset = g_struct_get_field_offset (info, blob->n_fields) - + n * header->function_blob_size; - return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, - base->typelib, offset); + offset = g_struct_get_field_offset (info, blob->n_fields) + n * header->function_blob_size; + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, + rinfo->typelib, offset); } static GIFunctionInfo * find_method (GIBaseInfo *base, - guint32 offset, - gint n_methods, - const gchar *name) + guint32 offset, + gint n_methods, + const gchar *name) { /* FIXME hash */ - Header *header = (Header *)base->typelib->data; + GIRealInfo *rinfo = (GIRealInfo*)base; + Header *header = (Header *)rinfo->typelib->data; gint i; for (i = 0; i < n_methods; i++) { - FunctionBlob *fblob = (FunctionBlob *)&base->typelib->data[offset]; - const gchar *fname = (const gchar *)&base->typelib->data[fblob->name]; + FunctionBlob *fblob = (FunctionBlob *)&rinfo->typelib->data[offset]; + const gchar *fname = (const gchar *)&rinfo->typelib->data[fblob->name]; if (strcmp (name, fname) == 0) - return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, - base->typelib, offset); + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, + rinfo->typelib, offset); offset += header->function_blob_size; } @@ -1293,21 +1342,21 @@ g_struct_info_find_method (GIStructInfo *info, const gchar *name) { gint offset; - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = base->offset + header->struct_blob_size + offset = rinfo->offset + header->struct_blob_size + blob->n_fields * header->field_blob_size; - return find_method (base, offset, blob->n_methods, name); + return find_method ((GIBaseInfo*)info, offset, blob->n_methods, name); } gsize g_struct_info_get_size (GIStructInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->size; } @@ -1315,8 +1364,8 @@ g_struct_info_get_size (GIStructInfo *info) gsize g_struct_info_get_alignment (GIStructInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->alignment; } @@ -1334,8 +1383,8 @@ g_struct_info_get_alignment (GIStructInfo *info) gboolean g_struct_info_is_gtype_struct (GIStructInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->is_gtype_struct; } @@ -1343,8 +1392,8 @@ g_struct_info_is_gtype_struct (GIStructInfo *info) gint g_enum_info_get_n_values (GIEnumInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - EnumBlob *blob = (EnumBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + EnumBlob *blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_values; } @@ -1353,13 +1402,13 @@ GIValueInfo * g_enum_info_get_value (GIEnumInfo *info, gint n) { - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; gint offset; - offset = base->offset + header->enum_blob_size + offset = rinfo->offset + header->enum_blob_size + n * header->value_blob_size; - return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, base, base->typelib, offset); + return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, (GIBaseInfo*)info, rinfo->typelib, offset); } /** @@ -1378,8 +1427,8 @@ g_enum_info_get_value (GIEnumInfo *info, GITypeTag g_enum_info_get_storage_type (GIEnumInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - EnumBlob *blob = (EnumBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + EnumBlob *blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->storage_type; } @@ -1388,12 +1437,12 @@ g_enum_info_get_storage_type (GIEnumInfo *info) GIObjectInfo * g_object_info_get_parent (GIObjectInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->parent) - return (GIObjectInfo *) g_info_from_entry (base->repository, - base->typelib, blob->parent); + return (GIObjectInfo *) g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->parent); else return NULL; } @@ -1401,34 +1450,34 @@ g_object_info_get_parent (GIObjectInfo *info) gboolean g_object_info_get_abstract (GIObjectInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->abstract != 0; } const gchar * g_object_info_get_type_name (GIObjectInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - return g_typelib_get_string (base->typelib, blob->gtype_name); + return g_typelib_get_string (rinfo->typelib, blob->gtype_name); } const gchar * g_object_info_get_type_init (GIObjectInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - return g_typelib_get_string (base->typelib, blob->gtype_init); + return g_typelib_get_string (rinfo->typelib, blob->gtype_init); } gint g_object_info_get_n_interfaces (GIObjectInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_interfaces; } @@ -1437,18 +1486,18 @@ GIInterfaceInfo * g_object_info_get_interface (GIObjectInfo *info, gint n) { - GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - return (GIInterfaceInfo *) g_info_from_entry (base->repository, - base->typelib, blob->interfaces[n]); + return (GIInterfaceInfo *) g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->interfaces[n]); } gint g_object_info_get_n_fields (GIObjectInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_fields; } @@ -1458,22 +1507,22 @@ g_object_info_get_field (GIObjectInfo *info, gint n) { gint offset; - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = base->offset + header->object_blob_size + offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + n * header->field_blob_size; - return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->typelib, offset); + return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, offset); } gint g_object_info_get_n_properties (GIObjectInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_properties; } @@ -1483,24 +1532,24 @@ g_object_info_get_property (GIObjectInfo *info, gint n) { gint offset; - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = base->offset + header->object_blob_size + offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + blob->n_fields * header->field_blob_size + n * header->property_blob_size; - return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, base, - base->typelib, offset); + return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info, + rinfo->typelib, offset); } gint g_object_info_get_n_methods (GIObjectInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_methods; } @@ -1510,18 +1559,18 @@ g_object_info_get_method (GIObjectInfo *info, gint n) { gint offset; - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = base->offset + header->object_blob_size + offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + blob->n_fields * header->field_blob_size + blob->n_properties * header->property_blob_size + n * header->function_blob_size; - return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, - base->typelib, offset); + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, + rinfo->typelib, offset); } GIFunctionInfo * @@ -1529,23 +1578,23 @@ g_object_info_find_method (GIObjectInfo *info, const gchar *name) { gint offset; - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = base->offset + header->object_blob_size + offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + blob->n_fields * header->field_blob_size + + blob->n_properties * header->property_blob_size; - return find_method (base, offset, blob->n_methods, name); + return find_method ((GIBaseInfo*)info, offset, blob->n_methods, name); } gint g_object_info_get_n_signals (GIObjectInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_signals; } @@ -1555,26 +1604,26 @@ g_object_info_get_signal (GIObjectInfo *info, gint n) { gint offset; - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = base->offset + header->object_blob_size + offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + blob->n_fields * header->field_blob_size + blob->n_properties * header->property_blob_size + blob->n_methods * header->function_blob_size + n * header->signal_blob_size; - return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, base, - base->typelib, offset); + return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info, + rinfo->typelib, offset); } gint g_object_info_get_n_vfuncs (GIObjectInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_vfuncs; } @@ -1584,11 +1633,11 @@ g_object_info_get_vfunc (GIObjectInfo *info, gint n) { gint offset; - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = base->offset + header->object_blob_size + offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + blob->n_fields * header->field_blob_size + blob->n_properties * header->property_blob_size @@ -1596,28 +1645,28 @@ g_object_info_get_vfunc (GIObjectInfo *info, + blob->n_signals * header->signal_blob_size + n * header->vfunc_blob_size; - return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, base, - base->typelib, offset); + return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info, + rinfo->typelib, offset); } static GIVFuncInfo * -find_vfunc (GIBaseInfo *base, +find_vfunc (GIRealInfo *rinfo, guint32 offset, gint n_vfuncs, const gchar *name) { /* FIXME hash */ - Header *header = (Header *)base->typelib->data; + Header *header = (Header *)rinfo->typelib->data; gint i; for (i = 0; i < n_vfuncs; i++) { - VFuncBlob *fblob = (VFuncBlob *)&base->typelib->data[offset]; - const gchar *fname = (const gchar *)&base->typelib->data[fblob->name]; + VFuncBlob *fblob = (VFuncBlob *)&rinfo->typelib->data[offset]; + const gchar *fname = (const gchar *)&rinfo->typelib->data[fblob->name]; if (strcmp (name, fname) == 0) - return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, base, - base->typelib, offset); + return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*) rinfo, + rinfo->typelib, offset); offset += header->vfunc_blob_size; } @@ -1643,25 +1692,25 @@ g_object_info_find_vfunc (GIObjectInfo *info, const gchar *name) { gint offset; - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = base->offset + header->object_blob_size + offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + blob->n_fields * header->field_blob_size + blob->n_properties * header->property_blob_size + blob->n_methods * header->function_blob_size + blob->n_signals * header->signal_blob_size; - return find_vfunc (base, offset, blob->n_vfuncs, name); + return find_vfunc (rinfo, offset, blob->n_vfuncs, name); } gint g_object_info_get_n_constants (GIObjectInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_constants; } @@ -1671,11 +1720,11 @@ g_object_info_get_constant (GIObjectInfo *info, gint n) { gint offset; - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = base->offset + header->object_blob_size + offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + blob->n_fields * header->field_blob_size + blob->n_properties * header->property_blob_size @@ -1684,8 +1733,8 @@ g_object_info_get_constant (GIObjectInfo *info, + blob->n_vfuncs * header->vfunc_blob_size + n * header->constant_blob_size; - return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, base, - base->typelib, offset); + return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, + rinfo->typelib, offset); } /** @@ -1700,12 +1749,12 @@ g_object_info_get_constant (GIObjectInfo *info, GIStructInfo * g_object_info_get_class_struct (GIObjectInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->gtype_struct) - return (GIStructInfo *) g_info_from_entry (base->repository, - base->typelib, blob->gtype_struct); + return (GIStructInfo *) g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->gtype_struct); else return NULL; } @@ -1714,8 +1763,8 @@ g_object_info_get_class_struct (GIObjectInfo *info) gint g_interface_info_get_n_prerequisites (GIInterfaceInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_prerequisites; } @@ -1724,19 +1773,19 @@ GIBaseInfo * g_interface_info_get_prerequisite (GIInterfaceInfo *info, gint n) { - GIBaseInfo *base = (GIBaseInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - return g_info_from_entry (base->repository, - base->typelib, blob->prerequisites[n]); + return g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->prerequisites[n]); } gint g_interface_info_get_n_properties (GIInterfaceInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_properties; } @@ -1746,23 +1795,23 @@ g_interface_info_get_property (GIInterfaceInfo *info, gint n) { gint offset; - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = base->offset + header->interface_blob_size + offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + n * header->property_blob_size; - return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, base, - base->typelib, offset); + return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info, + rinfo->typelib, offset); } gint g_interface_info_get_n_methods (GIInterfaceInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_methods; } @@ -1772,17 +1821,17 @@ g_interface_info_get_method (GIInterfaceInfo *info, gint n) { gint offset; - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = base->offset + header->interface_blob_size + offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + blob->n_properties * header->property_blob_size + n * header->function_blob_size; - return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, - base->typelib, offset); + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, + rinfo->typelib, offset); } GIFunctionInfo * @@ -1790,22 +1839,22 @@ g_interface_info_find_method (GIInterfaceInfo *info, const gchar *name) { gint offset; - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = base->offset + header->interface_blob_size + offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + blob->n_properties * header->property_blob_size; - return find_method (base, offset, blob->n_methods, name); + return find_method ((GIBaseInfo*)info, offset, blob->n_methods, name); } gint g_interface_info_get_n_signals (GIInterfaceInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_signals; } @@ -1815,25 +1864,25 @@ g_interface_info_get_signal (GIInterfaceInfo *info, gint n) { gint offset; - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = base->offset + header->interface_blob_size + offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + blob->n_properties * header->property_blob_size + blob->n_methods * header->function_blob_size + n * header->signal_blob_size; - return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, base, - base->typelib, offset); + return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info, + rinfo->typelib, offset); } gint g_interface_info_get_n_vfuncs (GIInterfaceInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_vfuncs; } @@ -1843,19 +1892,19 @@ g_interface_info_get_vfunc (GIInterfaceInfo *info, gint n) { gint offset; - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = base->offset + header->interface_blob_size + offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + blob->n_properties * header->property_blob_size + blob->n_methods * header->function_blob_size + blob->n_signals * header->signal_blob_size + n * header->vfunc_blob_size; - return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, base, - base->typelib, offset); + return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info, + rinfo->typelib, offset); } /** @@ -1873,24 +1922,24 @@ g_interface_info_find_vfunc (GIInterfaceInfo *info, const gchar *name) { gint offset; - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = base->offset + header->interface_blob_size + offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + blob->n_prerequisites % 2) * 2 + blob->n_properties * header->property_blob_size + blob->n_methods * header->function_blob_size + blob->n_signals * header->signal_blob_size; - return find_vfunc (base, offset, blob->n_vfuncs, name); + return find_vfunc (rinfo, offset, blob->n_vfuncs, name); } gint g_interface_info_get_n_constants (GIInterfaceInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_constants; } @@ -1900,11 +1949,11 @@ g_interface_info_get_constant (GIInterfaceInfo *info, gint n) { gint offset; - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = base->offset + header->interface_blob_size + offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + blob->n_properties * header->property_blob_size + blob->n_methods * header->function_blob_size @@ -1912,8 +1961,8 @@ g_interface_info_get_constant (GIInterfaceInfo *info, + blob->n_vfuncs * header->vfunc_blob_size + n * header->constant_blob_size; - return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, base, - base->typelib, offset); + return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, + rinfo->typelib, offset); } /** @@ -1927,12 +1976,12 @@ g_interface_info_get_constant (GIInterfaceInfo *info, GIStructInfo * g_interface_info_get_iface_struct (GIInterfaceInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->gtype_struct) - return (GIStructInfo *) g_info_from_entry (base->repository, - base->typelib, blob->gtype_struct); + return (GIStructInfo *) g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->gtype_struct); else return NULL; } @@ -1942,8 +1991,8 @@ GParamFlags g_property_info_get_flags (GIPropertyInfo *info) { GParamFlags flags; - GIBaseInfo *base = (GIBaseInfo *)info; - PropertyBlob *blob = (PropertyBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset]; flags = 0; @@ -1965,9 +2014,9 @@ g_property_info_get_flags (GIPropertyInfo *info) GITypeInfo * g_property_info_get_type (GIPropertyInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; + GIRealInfo *rinfo = (GIRealInfo *)info; - return g_type_info_new (base, base->typelib, base->offset + G_STRUCT_OFFSET (PropertyBlob, type)); + return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (PropertyBlob, type)); } @@ -1977,8 +2026,8 @@ g_signal_info_get_flags (GISignalInfo *info) { GSignalFlags flags; - GIBaseInfo *base = (GIBaseInfo *)info; - SignalBlob *blob = (SignalBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; flags = 0; @@ -2009,11 +2058,11 @@ g_signal_info_get_flags (GISignalInfo *info) GIVFuncInfo * g_signal_info_get_class_closure (GISignalInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - SignalBlob *blob = (SignalBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->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 *)rinfo->container, blob->class_closure); return NULL; } @@ -2021,8 +2070,8 @@ g_signal_info_get_class_closure (GISignalInfo *info) gboolean g_signal_info_true_stops_emit (GISignalInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - SignalBlob *blob = (SignalBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->true_stops_emit; } @@ -2033,8 +2082,8 @@ g_vfunc_info_get_flags (GIVFuncInfo *info) { GIVFuncInfoFlags flags; - GIBaseInfo *base = (GIBaseInfo *)info; - VFuncBlob *blob = (VFuncBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; flags = 0; @@ -2053,8 +2102,8 @@ g_vfunc_info_get_flags (GIVFuncInfo *info) gint g_vfunc_info_get_offset (GIVFuncInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - VFuncBlob *blob = (VFuncBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->struct_offset; } @@ -2062,11 +2111,11 @@ g_vfunc_info_get_offset (GIVFuncInfo *info) GISignalInfo * g_vfunc_info_get_signal (GIVFuncInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - VFuncBlob *blob = (VFuncBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->class_closure) - return g_interface_info_get_signal ((GIInterfaceInfo *)base->container, blob->signal); + return g_interface_info_get_signal ((GIInterfaceInfo *)rinfo->container, blob->signal); return NULL; } @@ -2085,9 +2134,9 @@ g_vfunc_info_get_signal (GIVFuncInfo *info) GIFunctionInfo * g_vfunc_info_get_invoker (GIVFuncInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - VFuncBlob *blob = (VFuncBlob *)&base->typelib->data[base->offset]; - GIBaseInfo *container = base->container; + GIRealInfo *rinfo = (GIRealInfo *)info; + VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; + GIBaseInfo *container = rinfo->container; GIInfoType parent_type; /* 1023 = 0x3ff is the maximum of the 10 bits for invoker index */ @@ -2107,80 +2156,80 @@ g_vfunc_info_get_invoker (GIVFuncInfo *info) GITypeInfo * g_constant_info_get_type (GIConstantInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; + GIRealInfo *rinfo = (GIRealInfo *)info; - return g_type_info_new (base, base->typelib, base->offset + 8); + return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 8); } gint g_constant_info_get_value (GIConstantInfo *info, GArgument *value) { - GIBaseInfo *base = (GIBaseInfo *)info; - ConstantBlob *blob = (ConstantBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + ConstantBlob *blob = (ConstantBlob *)&rinfo->typelib->data[rinfo->offset]; /* FIXME non-basic types ? */ if (blob->type.flags.reserved == 0 && blob->type.flags.reserved2 == 0) { if (blob->type.flags.pointer) - value->v_pointer = g_memdup (&base->typelib->data[blob->offset], blob->size); + value->v_pointer = g_memdup (&rinfo->typelib->data[blob->offset], blob->size); else { switch (blob->type.flags.tag) { case GI_TYPE_TAG_BOOLEAN: - value->v_boolean = *(gboolean*)&base->typelib->data[blob->offset]; + value->v_boolean = *(gboolean*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_INT8: - value->v_int8 = *(gint8*)&base->typelib->data[blob->offset]; + value->v_int8 = *(gint8*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_UINT8: - value->v_uint8 = *(guint8*)&base->typelib->data[blob->offset]; + value->v_uint8 = *(guint8*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_INT16: - value->v_int16 = *(gint16*)&base->typelib->data[blob->offset]; + value->v_int16 = *(gint16*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_UINT16: - value->v_uint16 = *(guint16*)&base->typelib->data[blob->offset]; + value->v_uint16 = *(guint16*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_INT32: - value->v_int32 = *(gint32*)&base->typelib->data[blob->offset]; + value->v_int32 = *(gint32*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_UINT32: - value->v_uint32 = *(guint32*)&base->typelib->data[blob->offset]; + value->v_uint32 = *(guint32*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_INT64: - value->v_int64 = *(gint64*)&base->typelib->data[blob->offset]; + value->v_int64 = *(gint64*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_UINT64: - value->v_uint64 = *(guint64*)&base->typelib->data[blob->offset]; + value->v_uint64 = *(guint64*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_FLOAT: - value->v_float = *(gfloat*)&base->typelib->data[blob->offset]; + value->v_float = *(gfloat*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_DOUBLE: - value->v_double = *(gdouble*)&base->typelib->data[blob->offset]; + value->v_double = *(gdouble*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_TIME_T: - value->v_long = *(long*)&base->typelib->data[blob->offset]; + value->v_long = *(long*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_SHORT: - value->v_short = *(gshort*)&base->typelib->data[blob->offset]; + value->v_short = *(gshort*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_USHORT: - value->v_ushort = *(gushort*)&base->typelib->data[blob->offset]; + value->v_ushort = *(gushort*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_INT: - value->v_int = *(gint*)&base->typelib->data[blob->offset]; + value->v_int = *(gint*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_UINT: - value->v_uint = *(guint*)&base->typelib->data[blob->offset]; + value->v_uint = *(guint*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_LONG: - value->v_long = *(glong*)&base->typelib->data[blob->offset]; + value->v_long = *(glong*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_ULONG: - value->v_ulong = *(gulong*)&base->typelib->data[blob->offset]; + value->v_ulong = *(gulong*)&rinfo->typelib->data[blob->offset]; break; } } @@ -2193,8 +2242,8 @@ g_constant_info_get_value (GIConstantInfo *info, gint g_union_info_get_n_fields (GIUnionInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_fields; } @@ -2203,19 +2252,19 @@ GIFieldInfo * g_union_info_get_field (GIUnionInfo *info, gint n) { - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; - return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->typelib, - base->offset + header->union_blob_size + + return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, + rinfo->offset + header->union_blob_size + n * header->field_blob_size); } gint g_union_info_get_n_methods (GIUnionInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_functions; } @@ -2224,23 +2273,23 @@ GIFunctionInfo * g_union_info_get_method (GIUnionInfo *info, gint n) { - GIBaseInfo *base = (GIBaseInfo *)info; - UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; - Header *header = (Header *)base->typelib->data; + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header = (Header *)rinfo->typelib->data; gint offset; - offset = base->offset + header->union_blob_size + offset = rinfo->offset + header->union_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->typelib, offset); + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, + rinfo->typelib, offset); } gboolean g_union_info_is_discriminated (GIUnionInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->discriminated; } @@ -2248,8 +2297,8 @@ g_union_info_is_discriminated (GIUnionInfo *info) gint g_union_info_get_discriminator_offset (GIUnionInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->discriminator_offset; } @@ -2257,30 +2306,30 @@ g_union_info_get_discriminator_offset (GIUnionInfo *info) GITypeInfo * g_union_info_get_discriminator_type (GIUnionInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; + GIRealInfo *rinfo = (GIRealInfo *)info; - return g_type_info_new (base, base->typelib, base->offset + 24); + return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 24); } GIConstantInfo * g_union_info_get_discriminator (GIUnionInfo *info, gint n) { - GIBaseInfo *base = (GIBaseInfo *)info; - UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->discriminated) { - Header *header = (Header *)base->typelib->data; + Header *header = (Header *)rinfo->typelib->data; gint offset; - offset = base->offset + header->union_blob_size + offset = rinfo->offset + header->union_blob_size + blob->n_fields * header->field_blob_size + blob->n_functions * header->function_blob_size + n * header->constant_blob_size; - return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, base, - base->typelib, offset); + return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, + rinfo->typelib, offset); } return NULL; @@ -2291,21 +2340,21 @@ g_union_info_find_method (GIUnionInfo *info, const gchar *name) { gint offset; - GIBaseInfo *base = (GIBaseInfo *)info; - Header *header = (Header *)base->typelib->data; - UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = base->offset + header->union_blob_size + offset = rinfo->offset + header->union_blob_size + blob->n_fields * header->field_blob_size; - return find_method (base, offset, blob->n_functions, name); + return find_method ((GIBaseInfo*)info, offset, blob->n_functions, name); } gsize g_union_info_get_size (GIUnionInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->size; } @@ -2313,8 +2362,8 @@ g_union_info_get_size (GIUnionInfo *info) gsize g_union_info_get_alignment (GIUnionInfo *info) { - GIBaseInfo *base = (GIBaseInfo *)info; - UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset]; + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->alignment; } diff --git a/girepository.h b/girepository.h index c30418a80..93cf126ac 100644 --- a/girepository.h +++ b/girepository.h @@ -27,37 +27,55 @@ G_BEGIN_DECLS -#define G_TYPE_IREPOSITORY (g_irepository_get_type ()) -#define G_IREPOSITORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_IREPOSITORY, GIRepository)) +#define G_TYPE_IREPOSITORY (g_irepository_get_type ()) +#define G_IREPOSITORY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_IREPOSITORY, GIRepository)) +#define G_IREPOSITORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_IREPOSITORY, GIRepositoryClass)) +#define G_IS_IREPOSITORY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_IREPOSITORY)) +#define G_IS_IREPOSITORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_IREPOSITORY)) +#define G_IREPOSITORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_IREPOSITORY, GIRepositoryClass)) typedef struct _GIRepository GIRepository; typedef struct _GIRepositoryClass GIRepositoryClass; typedef struct _GIRepositoryPrivate GIRepositoryPrivate; -typedef struct _GIBaseInfo GIBaseInfo; -typedef struct _GICallableInfo GICallableInfo; -typedef struct _GIFunctionInfo GIFunctionInfo; -typedef struct _GICallbackInfo GICallbackInfo; -typedef struct _GIRegisteredTypeInfo GIRegisteredTypeInfo; -typedef struct _GIStructInfo GIStructInfo; -typedef struct _GIUnionInfo GIUnionInfo; -typedef struct _GIEnumInfo GIEnumInfo; -typedef struct _GIObjectInfo GIObjectInfo; -typedef struct _GIInterfaceInfo GIInterfaceInfo; -typedef struct _GIConstantInfo GIConstantInfo; -typedef struct _GIValueInfo GIValueInfo; -typedef struct _GISignalInfo GISignalInfo; -typedef struct _GIVFuncInfo GIVFuncInfo; -typedef struct _GIPropertyInfo GIPropertyInfo; -typedef struct _GIFieldInfo GIFieldInfo; -typedef struct _GIArgInfo GIArgInfo; -typedef struct _GITypeInfo GITypeInfo; -typedef struct _GIErrorDomainInfo GIErrorDomainInfo; + +typedef struct _GIBaseInfoStub GIBaseInfo; + +struct _GIBaseInfoStub { + gint32 dummy1; + gint32 dummy2; + gpointer dummy3; + gpointer dummy4; + gpointer dummy5; + guint32 dummy6; + guint32 dummy7; + gpointer padding[4]; +}; + +typedef GIBaseInfo GICallableInfo; +typedef GIBaseInfo GIFunctionInfo; +typedef GIBaseInfo GICallbackInfo; +typedef GIBaseInfo GIRegisteredTypeInfo; +typedef GIBaseInfo GIStructInfo; +typedef GIBaseInfo GIUnionInfo; +typedef GIBaseInfo GIEnumInfo; +typedef GIBaseInfo GIObjectInfo; +typedef GIBaseInfo GIInterfaceInfo; +typedef GIBaseInfo GIConstantInfo; +typedef GIBaseInfo GIValueInfo; +typedef GIBaseInfo GISignalInfo; +typedef GIBaseInfo GIVFuncInfo; +typedef GIBaseInfo GIPropertyInfo; +typedef GIBaseInfo GIFieldInfo; +typedef GIBaseInfo GIArgInfo; +typedef GIBaseInfo GITypeInfo; +typedef GIBaseInfo GIErrorDomainInfo; + typedef struct _GIUnresolvedInfo GIUnresolvedInfo; typedef struct _GTypelib GTypelib; struct _GIRepository { - GObject parent; + GObject parent; /*< private >*/ GIRepositoryPrivate *priv; @@ -282,11 +300,16 @@ typedef enum { } GITransfer; GITypeInfo * g_callable_info_get_return_type (GICallableInfo *info); +void g_callable_info_load_return_type (GICallableInfo *info, + GITypeInfo *type); GITransfer g_callable_info_get_caller_owns (GICallableInfo *info); gboolean g_callable_info_may_return_null (GICallableInfo *info); gint g_callable_info_get_n_args (GICallableInfo *info); GIArgInfo * g_callable_info_get_arg (GICallableInfo *info, - gint n); + gint n); +void g_callable_info_load_arg (GICallableInfo *info, + gint n, + GIArgInfo *arg); /* GIArgInfo */ @@ -317,6 +340,8 @@ GIScopeType g_arg_info_get_scope (GIArgInfo *info); gint g_arg_info_get_closure (GIArgInfo *info); gint g_arg_info_get_destroy (GIArgInfo *info); GITypeInfo * g_arg_info_get_type (GIArgInfo *info); +void g_arg_info_load_type (GIArgInfo *info, + GITypeInfo *type); /* GITypeInfo */ From be1c2991cf98539b49a18876a544e1560bd76fe6 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 31 Dec 2009 15:29:43 +0100 Subject: [PATCH 256/692] Add missing include girffi-private.h --- girffi.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/girffi.h b/girffi.h index 7961177ee..b991b9458 100644 --- a/girffi.h +++ b/girffi.h @@ -21,8 +21,9 @@ #ifndef __GIRFFI_H__ #define __GIRFFI_H__ -#include "girepository.h" #include +#include "girepository.h" +#include "girffi-private.h" G_BEGIN_DECLS From 109159ee05ae94fe46ebe116bede56ff8062ea31 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 31 Dec 2009 17:37:21 +0100 Subject: [PATCH 257/692] The private header should be included in girffi.c Not in the public girffi.h. --- girffi.c | 1 + girffi.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/girffi.c b/girffi.c index c757eeab4..769cd6b01 100644 --- a/girffi.c +++ b/girffi.c @@ -27,6 +27,7 @@ #include #include #include "girffi.h" +#include "girffi-private.h" #include "girepository.h" ffi_type * diff --git a/girffi.h b/girffi.h index b991b9458..10a20a243 100644 --- a/girffi.h +++ b/girffi.h @@ -23,7 +23,6 @@ #include #include "girepository.h" -#include "girffi-private.h" G_BEGIN_DECLS From 7d5da3d09fdd8d21e84b441c4c4429469d544b98 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 7 Jan 2010 16:12:15 -0500 Subject: [PATCH 258/692] Correctly cast to a CommonBlob when looking up embedded types When looking at an embedded type (e.g. a Callback after a Field), the offset we put in the info structure was to the CallbackBlob itself. However the code in g_type_info_get_interface assumed that the offset was to a SimpleTypeBlob, which it wasn't. https://bugzilla.gnome.org/show_bug.cgi?id=606180 --- ginfo.c | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/ginfo.c b/ginfo.c index b11cc8fc2..ed2fc93d4 100644 --- a/ginfo.c +++ b/ginfo.c @@ -997,18 +997,38 @@ GIBaseInfo * g_type_info_get_interface (GITypeInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + /* For embedded types, the given offset is a pointer to the actual blob, + * after the end of the field. In that case we know it's a "subclass" of + * CommonBlob, so use that to determine the info type. + */ if (rinfo->type_is_embedded) - return (GIBaseInfo *) g_info_new (type->offset, (GIBaseInfo*)info, rinfo->typelib, - rinfo->offset); - - if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { - InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->tag == GI_TYPE_TAG_INTERFACE) - return g_info_from_entry (rinfo->repository, rinfo->typelib, blob->interface); + CommonBlob *common = (CommonBlob *)&rinfo->typelib->data[rinfo->offset]; + GIInfoType info_type; + + switch (common->blob_type) + { + case BLOB_TYPE_CALLBACK: + info_type = GI_INFO_TYPE_CALLBACK; + break; + default: + g_assert_not_reached (); + return NULL; + } + return (GIBaseInfo *) g_info_new (info_type, (GIBaseInfo*)info, rinfo->typelib, + rinfo->offset); + } + else + { + SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) + { + InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->tag == GI_TYPE_TAG_INTERFACE) + return g_info_from_entry (rinfo->repository, rinfo->typelib, blob->interface); + } } return NULL; From c5319f668d9d9ffb4d3e1b189f86acff0dd093b7 Mon Sep 17 00:00:00 2001 From: Maxim Ermilov Date: Mon, 25 Jan 2010 00:26:29 +0300 Subject: [PATCH 259/692] increase limit of GIRealInfo's ref_count New limit is 0x7FFFFFFF. --- ginfo.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ginfo.c b/ginfo.c index ed2fc93d4..76d60ef8d 100644 --- a/ginfo.c +++ b/ginfo.c @@ -69,6 +69,8 @@ struct _GIUnresolvedInfo const gchar *namespace; }; +#define INVALID_REFCOUNT 0x7FFFFFFF + static void g_info_init (GIRealInfo *info, GIInfoType type, @@ -80,7 +82,7 @@ g_info_init (GIRealInfo *info, memset (info, 0, sizeof (GIRealInfo)); /* Invalid refcount used to flag stack-allocated infos */ - info->ref_count = 0xFFFF; + info->ref_count = INVALID_REFCOUNT; info->type = type; info->typelib = typelib; @@ -110,7 +112,7 @@ g_info_new_full (GIInfoType type, g_info_init (info, type, repository, container, typelib, offset); info->ref_count = 1; - if (container && ((GIRealInfo *) container)->ref_count != 0xFFFF) + if (container && ((GIRealInfo *) container)->ref_count != INVALID_REFCOUNT) g_base_info_ref (info->container); g_object_ref (info->repository); @@ -170,7 +172,7 @@ g_base_info_ref (GIBaseInfo *info) { GIRealInfo *rinfo = (GIRealInfo*)info; - g_assert (rinfo->ref_count != 0xFFFF); + g_assert (rinfo->ref_count != INVALID_REFCOUNT); ((GIRealInfo*)info)->ref_count++; return info; @@ -181,12 +183,12 @@ g_base_info_unref (GIBaseInfo *info) { GIRealInfo *rinfo = (GIRealInfo*)info; - g_assert (rinfo->ref_count > 0 && rinfo->ref_count != 0xFFFF); + g_assert (rinfo->ref_count > 0 && rinfo->ref_count != INVALID_REFCOUNT); rinfo->ref_count--; if (!rinfo->ref_count) { - if (rinfo->container && ((GIRealInfo *) rinfo->container)->ref_count != 0xFFFF) + if (rinfo->container && ((GIRealInfo *) rinfo->container)->ref_count != INVALID_REFCOUNT) g_base_info_unref (rinfo->container); if (rinfo->repository) From 3a8a1d2653910b029351d3ad80016d29a1adf942 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 11 Feb 2010 17:18:28 -0500 Subject: [PATCH 260/692] [g-ir-compiler] Slightly less lame error messages To make things really better we should track the line origin of element from the .gir file (and actually we need to do better checking in the scanner), but this is slightly less lame. --- girmodule.c | 34 ++++++++++++++++++++++++++++++++++ girmodule.h | 2 ++ girnode.c | 2 +- giroffsets.c | 2 +- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/girmodule.c b/girmodule.c index bf1e856bb..b954d15de 100644 --- a/girmodule.c +++ b/girmodule.c @@ -20,6 +20,7 @@ #include #include +#include #include "girmodule.h" #include "girnode.h" @@ -75,6 +76,39 @@ g_ir_module_free (GIrModule *module) g_free (module); } +/** + * g_ir_module_fatal: + * @module: Current module + * @line: Origin line number, or 0 if unknown + * @msg: printf-format string + * @args: Remaining arguments + * + * Report a fatal error, then exit. + */ +void +g_ir_module_fatal (GIrModule *module, + guint line, + const char *msg, + ...) +{ + char *formatted; + + va_list args; + + va_start (args, msg); + + formatted = g_strdup_vprintf (msg, args); + + if (line) + g_printerr ("%s-%s.gir:%d: error: %s\n", module->name, module->version, line, formatted); + else + g_printerr ("%s-%s.gir: error: %s\n", module->name, module->version, formatted); + + exit (1); + + va_end (args); +} + static void add_alias_foreach (gpointer key, gpointer value, diff --git a/girmodule.h b/girmodule.h index 5a558c359..da3fb35dd 100644 --- a/girmodule.h +++ b/girmodule.h @@ -61,6 +61,8 @@ void g_ir_module_add_include_module (GIrModule *module, GTypelib * g_ir_module_build_typelib (GIrModule *module, GList *modules); +void g_ir_module_fatal (GIrModule *module, guint line, const char *msg, ...) G_GNUC_PRINTF (3, 4) G_GNUC_NORETURN; + void _g_irnode_init_stats (void); void _g_irnode_dump_stats (void); diff --git a/girnode.c b/girnode.c index 9f6234532..2523ee1f1 100644 --- a/girnode.c +++ b/girnode.c @@ -1090,7 +1090,7 @@ find_entry_node (GIrModule *module, goto out; } - g_warning ("Entry '%s' not found", name); + g_ir_module_fatal (module, 0, "Type reference '%s' not found", name); out: diff --git a/giroffsets.c b/giroffsets.c index 96ff57648..dcfd75e57 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -156,7 +156,7 @@ get_interface_size_alignment (GIrNodeType *type, if (!g_ir_find_node (module, modules, type->interface, &iface, &iface_module)) { - g_warning ("Can't resolve type '%s' for %s", type->interface, who); + g_ir_module_fatal (module, 0, "Can't resolve type '%s' for %s", type->interface, who); *size = -1; *alignment = -1; return FALSE; From 6962d651252213f065b76593d32cfb2054fbf26a Mon Sep 17 00:00:00 2001 From: Kedar Sovani Date: Wed, 21 Oct 2009 13:28:12 +0200 Subject: [PATCH 261/692] Fix Alignment Errors. Signed-off-by: Kedar Sovani https://bugzilla.gnome.org/show_bug.cgi?id=606139 --- girnode.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/girnode.c b/girnode.c index 2523ee1f1..ede6d3b7f 100644 --- a/girnode.c +++ b/girnode.c @@ -53,6 +53,13 @@ _g_irnode_dump_stats (void) g_message ("%lu types (%lu before sharing)", unique_types_count, types_count); } +#define DO_ALIGNED_COPY(dest_addr, value, type) \ +do { \ + type tmp_var; \ + tmp_var = value; \ + memcpy(dest_addr, &tmp_var, sizeof(type)); \ +} while(0) + #define ALIGN_VALUE(this, boundary) \ (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) @@ -2271,11 +2278,11 @@ g_ir_node_build_typelib (GIrNode *node, break; case GI_TYPE_TAG_INT64: blob->size = 8; - *(gint64*)&data[blob->offset] = (gint64) parse_int_value (constant->value); + DO_ALIGNED_COPY(&data[blob->offset], parse_int_value (constant->value), gint64); break; case GI_TYPE_TAG_UINT64: blob->size = 8; - *(guint64*)&data[blob->offset] = (guint64) parse_uint_value (constant->value); + DO_ALIGNED_COPY(&data[blob->offset], parse_uint_value (constant->value), guint64); break; case GI_TYPE_TAG_SHORT: blob->size = sizeof (gshort); @@ -2296,21 +2303,21 @@ g_ir_node_build_typelib (GIrNode *node, case GI_TYPE_TAG_SSIZE: /* FIXME */ case GI_TYPE_TAG_LONG: blob->size = sizeof (glong); - *(glong*)&data[blob->offset] = (glong) parse_int_value (constant->value); + DO_ALIGNED_COPY(&data[blob->offset], parse_int_value (constant->value), glong); break; case GI_TYPE_TAG_SIZE: /* FIXME */ case GI_TYPE_TAG_TIME_T: case GI_TYPE_TAG_ULONG: blob->size = sizeof (gulong); - *(gulong*)&data[blob->offset] = (gulong) parse_uint_value (constant->value); + DO_ALIGNED_COPY(&data[blob->offset], parse_uint_value (constant->value), gulong); break; case GI_TYPE_TAG_FLOAT: blob->size = sizeof (gfloat); - *(gfloat*)&data[blob->offset] = (gfloat) parse_float_value (constant->value); + DO_ALIGNED_COPY(&data[blob->offset], parse_float_value (constant->value), gfloat); break; case GI_TYPE_TAG_DOUBLE: blob->size = sizeof (gdouble); - *(gdouble*)&data[blob->offset] = (gdouble) parse_float_value (constant->value); + DO_ALIGNED_COPY(&data[blob->offset], parse_float_value (constant->value), gdouble); break; case GI_TYPE_TAG_UTF8: case GI_TYPE_TAG_FILENAME: From 30fb514e676b0d82b8ae7cda788f7bf6a608068b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 11 Feb 2010 17:49:51 -0500 Subject: [PATCH 262/692] Delete stray g_return_if_fail If g_alloca failed we're pretty much screwed, and g_return_if_fail is for API entry points, not internal assertions. --- ginvoke.c | 1 - 1 file changed, 1 deletion(-) diff --git a/ginvoke.c b/ginvoke.c index ff0495040..b3333f851 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -425,7 +425,6 @@ gi_cclosure_marshal_generic (GClosure *closure, if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_args, rtype, atypes) != FFI_OK) return; - g_return_if_fail (rvalue != NULL); ffi_call (&cif, marshal_data ? marshal_data : cc->callback, rvalue, args); if (return_gvalue && G_VALUE_TYPE (return_gvalue)) From a837d99ee607f796237edfcf02ebcb616e3eaafe Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 17 Mar 2010 19:28:01 -0400 Subject: [PATCH 263/692] Enumerations can be negative Change the internal type for ValueBlob to gint32, since it's perfectly valid for enumerations to have negative values. https://bugzilla.gnome.org/show_bug.cgi?id=613203 --- girnode.h | 2 +- gtypelib.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/girnode.h b/girnode.h index c1b2369cf..427f8e908 100644 --- a/girnode.h +++ b/girnode.h @@ -263,7 +263,7 @@ struct _GIrNodeValue gboolean deprecated; - guint32 value; + gint32 value; }; struct _GIrNodeConstant diff --git a/gtypelib.h b/gtypelib.h index 26486afc5..f02dcfc2e 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -614,7 +614,7 @@ typedef struct { guint32 deprecated : 1; guint32 reserved :31; guint32 name; - guint32 value; + gint32 value; } ValueBlob; /** From 6b0463dd16e9b6166bceecacc04274dd8d255107 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Wed, 24 Mar 2010 15:00:06 -0300 Subject: [PATCH 264/692] [girepository] Remove trailing whitespace --- gdump.c | 6 +- ginfo.c | 318 +++++++++++++++++----------------- ginvoke.c | 44 ++--- girepository.c | 110 ++++++------ girepository.h | 38 ++--- girffi.c | 26 +-- girffi.h | 4 +- girmodule.c | 30 ++-- girmodule.h | 2 +- girnode.c | 246 +++++++++++++------------- girnode.h | 62 +++---- giroffsets.c | 8 +- girparser.c | 456 ++++++++++++++++++++++++------------------------- girwriter.c | 4 +- gtypelib.c | 336 ++++++++++++++++++------------------ gtypelib.h | 252 +++++++++++++-------------- 16 files changed, 971 insertions(+), 971 deletions(-) diff --git a/gdump.c b/gdump.c index b4a3e8eb9..5cb10b045 100644 --- a/gdump.c +++ b/gdump.c @@ -158,7 +158,7 @@ dump_object_type (GType type, const char *symbol, GOutputStream *out) GString *parent_str; GType parent; gboolean first = TRUE; - + parent = type; parent_str = g_string_new (""); do @@ -170,9 +170,9 @@ dump_object_type (GType type, const char *symbol, GOutputStream *out) g_string_append_c (parent_str, ','); g_string_append (parent_str, g_type_name (parent)); } while (parent != G_TYPE_OBJECT && parent != G_TYPE_INVALID); - + escaped_printf (out, " parents=\"%s\"", parent_str->str); - + g_string_free (parent_str, TRUE); } diff --git a/ginfo.c b/ginfo.c index 76d60ef8d..2d777e3ef 100644 --- a/ginfo.c +++ b/ginfo.c @@ -48,10 +48,10 @@ struct _GIRealInfo GTypelib *typelib; guint32 offset; - + guint32 type_is_embedded : 1; /* Used by GITypeInfo */ guint32 reserved : 31; - + gpointer reserved2[4]; }; @@ -76,7 +76,7 @@ g_info_init (GIRealInfo *info, GIInfoType type, GIRepository *repository, GIBaseInfo *container, - GTypelib *typelib, + GTypelib *typelib, guint32 offset) { memset (info, 0, sizeof (GIRealInfo)); @@ -100,7 +100,7 @@ GIBaseInfo * g_info_new_full (GIInfoType type, GIRepository *repository, GIBaseInfo *container, - GTypelib *typelib, + GTypelib *typelib, guint32 offset) { GIRealInfo *info; @@ -108,7 +108,7 @@ g_info_new_full (GIInfoType type, g_return_val_if_fail (container != NULL || repository != NULL, NULL); info = g_new (GIRealInfo, 1); - + g_info_init (info, type, repository, container, typelib, offset); info->ref_count = 1; @@ -123,7 +123,7 @@ g_info_new_full (GIInfoType type, GIBaseInfo * g_info_new (GIInfoType type, GIBaseInfo *container, - GTypelib *typelib, + GTypelib *typelib, guint32 offset) { return g_info_new_full (type, ((GIRealInfo*)container)->repository, container, typelib, offset); @@ -201,7 +201,7 @@ g_base_info_unref (GIBaseInfo *info) GIInfoType g_base_info_get_type (GIBaseInfo *info) { - + return ((GIRealInfo*)info)->type; } @@ -265,7 +265,7 @@ g_base_info_get_name (GIBaseInfo *info) case GI_INFO_TYPE_FIELD: { FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; - + return g_typelib_get_string (rinfo->typelib, blob->name); } break; @@ -273,7 +273,7 @@ g_base_info_get_name (GIBaseInfo *info) case GI_INFO_TYPE_ARG: { ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - + return g_typelib_get_string (rinfo->typelib, blob->name); } break; @@ -304,14 +304,14 @@ g_base_info_get_namespace (GIBaseInfo *info) if (rinfo->type == GI_INFO_TYPE_UNRESOLVED) { GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info; - + return unresolved->namespace; } return g_typelib_get_string (rinfo->typelib, header->namespace); } -gboolean +gboolean g_base_info_is_deprecated (GIBaseInfo *info) { GIRealInfo *rinfo = (GIRealInfo*) info; @@ -365,7 +365,7 @@ g_base_info_is_deprecated (GIBaseInfo *info) default: ; /* no deprecation flag for these */ } - + return FALSE; } @@ -399,7 +399,7 @@ cmp_attribute (const void *av, { const AttributeBlob *a = av; const AttributeBlob *b = bv; - + if (a->offset < b->offset) return -1; else if (a->offset == b->offset) @@ -415,7 +415,7 @@ find_first_attribute (GIRealInfo *rinfo) AttributeBlob blob, *first, *res, *previous; blob.offset = rinfo->offset; - + first = (AttributeBlob *) &rinfo->typelib->data[header->attributes]; res = bsearch (&blob, first, header->n_attributes, @@ -545,13 +545,13 @@ g_function_info_get_flags (GIFunctionInfo *info) GIFunctionInfoFlags flags; GIRealInfo *rinfo = (GIRealInfo *)info; FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; - + flags = 0; /* Make sure we don't flag Constructors as methods */ if (!blob->constructor && !blob->is_static) flags = flags | GI_FUNCTION_IS_METHOD; - + if (blob->constructor) flags = flags | GI_FUNCTION_IS_CONSTRUCTOR; @@ -576,8 +576,8 @@ g_function_info_get_property (GIFunctionInfo *info) GIRealInfo *rinfo = (GIRealInfo *)info; FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; GIInterfaceInfo *container = (GIInterfaceInfo *)rinfo->container; - - return g_interface_info_get_property (container, blob->index); + + return g_interface_info_get_property (container, blob->index); } GIVFuncInfo * @@ -586,8 +586,8 @@ g_function_info_get_vfunc (GIFunctionInfo *info) GIRealInfo *rinfo = (GIRealInfo*)info; FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; GIInterfaceInfo *container = (GIInterfaceInfo *)rinfo->container; - - return g_interface_info_get_vfunc (container, blob->index); + + return g_interface_info_get_vfunc (container, blob->index); } /* GICallableInfo functions */ @@ -636,7 +636,7 @@ g_type_info_init (GIBaseInfo *info, { GIRealInfo *rinfo = (GIRealInfo*)container; SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset]; - + g_info_init ((GIRealInfo*)info, GI_INFO_TYPE_TYPE, rinfo->repository, container, typelib, (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset); } @@ -734,7 +734,7 @@ g_callable_info_get_caller_owns (GICallableInfo *info) * * Returns: The number of arguments this callable expects. */ -gint +gint g_callable_info_get_n_args (GICallableInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; @@ -765,8 +765,8 @@ g_callable_info_get_arg (GICallableInfo *info, gint offset; offset = signature_offset (info); - - return (GIArgInfo *) g_info_new (GI_INFO_TYPE_ARG, (GIBaseInfo*)info, rinfo->typelib, + + return (GIArgInfo *) g_info_new (GI_INFO_TYPE_ARG, (GIBaseInfo*)info, rinfo->typelib, offset + header->signature_blob_size + n * header->arg_blob_size); } @@ -792,9 +792,9 @@ g_callable_info_load_arg (GICallableInfo *info, gint offset; offset = signature_offset (info); - - g_info_init ((GIRealInfo*)arg, GI_INFO_TYPE_ARG, rinfo->repository, (GIBaseInfo*)info, rinfo->typelib, - offset + header->signature_blob_size + n * header->arg_blob_size); + + g_info_init ((GIRealInfo*)arg, GI_INFO_TYPE_ARG, rinfo->repository, (GIBaseInfo*)info, rinfo->typelib, + offset + header->signature_blob_size + n * header->arg_blob_size); } /* GIArgInfo function */ @@ -803,7 +803,7 @@ g_arg_info_get_direction (GIArgInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - + if (blob->in && blob->out) return GI_DIRECTION_INOUT; else if (blob->out) @@ -817,7 +817,7 @@ g_arg_info_is_return_value (GIArgInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - + return blob->return_value; } @@ -826,7 +826,7 @@ g_arg_info_is_dipper (GIArgInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - + return blob->dipper; } @@ -835,7 +835,7 @@ g_arg_info_is_optional (GIArgInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - + return blob->optional; } @@ -844,7 +844,7 @@ g_arg_info_may_be_null (GIArgInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - + return blob->allow_none; } @@ -899,7 +899,7 @@ GITypeInfo * g_arg_info_get_type (GIArgInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - + return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type)); } @@ -919,7 +919,7 @@ g_arg_info_load_type (GIArgInfo *info, GITypeInfo *type) { GIRealInfo *rinfo = (GIRealInfo*) info; - g_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type)); + g_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type)); } /* GITypeInfo functions */ @@ -928,13 +928,13 @@ g_type_info_is_pointer (GITypeInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - + if (type->flags.reserved == 0 && type->flags.reserved2 == 0) return type->flags.pointer; else { InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - + return iface->pointer; } } @@ -963,14 +963,14 @@ g_type_info_get_param_type (GITypeInfo *info, { GIRealInfo *rinfo = (GIRealInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { ParamTypeBlob *param = (ParamTypeBlob *)&rinfo->typelib->data[rinfo->offset]; switch (param->tag) { - case GI_TYPE_TAG_ARRAY: + case GI_TYPE_TAG_ARRAY: case GI_TYPE_TAG_GLIST: case GI_TYPE_TAG_GSLIST: case GI_TYPE_TAG_GHASH: @@ -1041,7 +1041,7 @@ g_type_info_get_array_length (GITypeInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset]; @@ -1061,7 +1061,7 @@ g_type_info_get_array_fixed_size (GITypeInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset]; @@ -1081,7 +1081,7 @@ g_type_info_is_zero_terminated (GITypeInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset]; @@ -1098,7 +1098,7 @@ g_type_info_get_n_error_domains (GITypeInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset]; @@ -1116,7 +1116,7 @@ g_type_info_get_error_domain (GITypeInfo *info, { GIRealInfo *rinfo = (GIRealInfo *)info; SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset]; @@ -1146,13 +1146,13 @@ g_error_domain_info_get_codes (GIErrorDomainInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; ErrorDomainBlob *blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset]; - + return (GIInterfaceInfo *) g_info_from_entry (rinfo->repository, rinfo->typelib, blob->error_codes); } -/* GIValueInfo functions */ +/* GIValueInfo functions */ glong g_value_info_get_value (GIValueInfo *info) { @@ -1187,7 +1187,7 @@ g_field_info_get_size (GIFieldInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; - + return blob->bits; } @@ -1196,7 +1196,7 @@ g_field_info_get_offset (GIFieldInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; - + return blob->struct_offset; } @@ -1253,19 +1253,19 @@ g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info) GType (* get_type_func) (void); GIRealInfo *rinfo = (GIRealInfo*)info; - type_init = g_registered_type_info_get_type_init (info); - + type_init = g_registered_type_info_get_type_init (info); + if (type_init == NULL) return G_TYPE_NONE; else if (!strcmp (type_init, "intern")) return G_TYPE_OBJECT; - + get_type_func = NULL; if (!g_typelib_symbol (rinfo->typelib, type_init, (void**) &get_type_func)) return G_TYPE_NONE; - + return (* get_type_func) (); } @@ -1275,7 +1275,7 @@ g_struct_info_get_n_fields (GIStructInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; - + return blob->n_fields; } @@ -1305,8 +1305,8 @@ g_struct_info_get_field (GIStructInfo *info, gint n) { GIRealInfo *rinfo = (GIRealInfo *)info; - - return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, + + return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, g_struct_get_field_offset (info, n)); } @@ -1315,7 +1315,7 @@ g_struct_info_get_n_methods (GIStructInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; - + return blob->n_methods; } @@ -1325,11 +1325,11 @@ g_struct_info_get_method (GIStructInfo *info, { GIRealInfo *rinfo = (GIRealInfo *)info; StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; gint offset; offset = g_struct_get_field_offset (info, blob->n_fields) + n * header->function_blob_size; - return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, rinfo->typelib, offset); } @@ -1341,7 +1341,7 @@ find_method (GIBaseInfo *base, { /* FIXME hash */ GIRealInfo *rinfo = (GIRealInfo*)base; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; gint i; for (i = 0; i < n_methods; i++) @@ -1350,12 +1350,12 @@ find_method (GIBaseInfo *base, const gchar *fname = (const gchar *)&rinfo->typelib->data[fblob->name]; if (strcmp (name, fname) == 0) - return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, - rinfo->typelib, offset); - + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, + rinfo->typelib, offset); + offset += header->function_blob_size; } - + return NULL; } @@ -1365,7 +1365,7 @@ g_struct_info_find_method (GIStructInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; offset = rinfo->offset + header->struct_blob_size @@ -1395,7 +1395,7 @@ g_struct_info_get_alignment (GIStructInfo *info) /** * g_struct_info_is_gtype_struct: * @info: GIStructInfo - * + * * Return true if this structure represents the "class structure" for some * #GObject or #GInterface. This function is mainly useful to hide this kind of structure * from generated public APIs. @@ -1425,10 +1425,10 @@ g_enum_info_get_value (GIEnumInfo *info, gint n) { GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; gint offset; - offset = rinfo->offset + header->enum_blob_size + offset = rinfo->offset + header->enum_blob_size + n * header->value_blob_size; return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, (GIBaseInfo*)info, rinfo->typelib, offset); } @@ -1530,13 +1530,13 @@ g_object_info_get_field (GIObjectInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - + offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + n * header->field_blob_size; - + return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, offset); } @@ -1546,7 +1546,7 @@ g_object_info_get_n_properties (GIObjectInfo *info) GIRealInfo *rinfo = (GIRealInfo *)info; ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - return blob->n_properties; + return blob->n_properties; } GIPropertyInfo * @@ -1555,15 +1555,15 @@ g_object_info_get_property (GIObjectInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - + offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + blob->n_fields * header->field_blob_size + n * header->property_blob_size; - return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info, + return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info, rinfo->typelib, offset); } @@ -1582,17 +1582,17 @@ g_object_info_get_method (GIObjectInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - + offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + blob->n_fields * header->field_blob_size + blob->n_properties * header->property_blob_size + n * header->function_blob_size; - return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, - rinfo->typelib, offset); + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, + rinfo->typelib, offset); } GIFunctionInfo * @@ -1601,7 +1601,7 @@ g_object_info_find_method (GIObjectInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; offset = rinfo->offset + header->object_blob_size @@ -1627,18 +1627,18 @@ g_object_info_get_signal (GIObjectInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - + offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + blob->n_fields * header->field_blob_size + blob->n_properties * header->property_blob_size - + blob->n_methods * header->function_blob_size + + blob->n_methods * header->function_blob_size + n * header->signal_blob_size; - return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info, - rinfo->typelib, offset); + return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info, + rinfo->typelib, offset); } gint @@ -1646,7 +1646,7 @@ g_object_info_get_n_vfuncs (GIObjectInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - + return blob->n_vfuncs; } @@ -1656,19 +1656,19 @@ g_object_info_get_vfunc (GIObjectInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - + offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + blob->n_fields * header->field_blob_size + blob->n_properties * header->property_blob_size - + blob->n_methods * header->function_blob_size - + blob->n_signals * header->signal_blob_size + + blob->n_methods * header->function_blob_size + + blob->n_signals * header->signal_blob_size + n * header->vfunc_blob_size; - return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info, - rinfo->typelib, offset); + return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info, + rinfo->typelib, offset); } static GIVFuncInfo * @@ -1733,7 +1733,7 @@ g_object_info_get_n_constants (GIObjectInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - + return blob->n_constants; } @@ -1743,26 +1743,26 @@ g_object_info_get_constant (GIObjectInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - + offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + blob->n_fields * header->field_blob_size + blob->n_properties * header->property_blob_size - + blob->n_methods * header->function_blob_size - + blob->n_signals * header->signal_blob_size - + blob->n_vfuncs * header->vfunc_blob_size + + blob->n_methods * header->function_blob_size + + blob->n_signals * header->signal_blob_size + + blob->n_vfuncs * header->vfunc_blob_size + n * header->constant_blob_size; - return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, - rinfo->typelib, offset); + return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, + rinfo->typelib, offset); } /** * g_object_info_get_class_struct: * @info: A #GIObjectInfo to query - * + * * Every #GObject has two structures; an instance structure and a class * structure. This function returns the metadata for the class structure. * @@ -1809,7 +1809,7 @@ g_interface_info_get_n_properties (GIInterfaceInfo *info) GIRealInfo *rinfo = (GIRealInfo *)info; InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - return blob->n_properties; + return blob->n_properties; } GIPropertyInfo * @@ -1818,14 +1818,14 @@ g_interface_info_get_property (GIInterfaceInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - + offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + n * header->property_blob_size; - return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info, + return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info, rinfo->typelib, offset); } @@ -1844,16 +1844,16 @@ g_interface_info_get_method (GIInterfaceInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - + offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 - + blob->n_properties * header->property_blob_size + + blob->n_properties * header->property_blob_size + n * header->function_blob_size; - - return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, - rinfo->typelib, offset); + + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, + rinfo->typelib, offset); } GIFunctionInfo * @@ -1862,7 +1862,7 @@ g_interface_info_find_method (GIInterfaceInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; offset = rinfo->offset + header->interface_blob_size @@ -1887,17 +1887,17 @@ g_interface_info_get_signal (GIInterfaceInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->interface_blob_size + + offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 - + blob->n_properties * header->property_blob_size - + blob->n_methods * header->function_blob_size + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + n * header->signal_blob_size; - - return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info, - rinfo->typelib, offset); + + return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info, + rinfo->typelib, offset); } gint @@ -1915,18 +1915,18 @@ g_interface_info_get_vfunc (GIInterfaceInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->interface_blob_size + + offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 - + blob->n_properties * header->property_blob_size - + blob->n_methods * header->function_blob_size + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + blob->n_signals * header->signal_blob_size + n * header->vfunc_blob_size; - - return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info, - rinfo->typelib, offset); + + return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info, + rinfo->typelib, offset); } /** @@ -1962,7 +1962,7 @@ g_interface_info_get_n_constants (GIInterfaceInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - + return blob->n_constants; } @@ -1972,19 +1972,19 @@ g_interface_info_get_constant (GIInterfaceInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - + offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + blob->n_properties * header->property_blob_size - + blob->n_methods * header->function_blob_size - + blob->n_signals * header->signal_blob_size - + blob->n_vfuncs * header->vfunc_blob_size + + blob->n_methods * header->function_blob_size + + blob->n_signals * header->signal_blob_size + + blob->n_vfuncs * header->vfunc_blob_size + n * header->constant_blob_size; - return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, - rinfo->typelib, offset); + return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, + rinfo->typelib, offset); } /** @@ -2015,7 +2015,7 @@ g_property_info_get_flags (GIPropertyInfo *info) GParamFlags flags; GIRealInfo *rinfo = (GIRealInfo *)info; PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset]; - + flags = 0; if (blob->readable) @@ -2126,7 +2126,7 @@ g_vfunc_info_get_offset (GIVFuncInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; - + return blob->struct_offset; } @@ -2138,7 +2138,7 @@ g_vfunc_info_get_signal (GIVFuncInfo *info) if (blob->class_closure) return g_interface_info_get_signal ((GIInterfaceInfo *)rinfo->container, blob->signal); - + return NULL; } @@ -2179,12 +2179,12 @@ GITypeInfo * g_constant_info_get_type (GIConstantInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - + return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 8); } gint -g_constant_info_get_value (GIConstantInfo *info, +g_constant_info_get_value (GIConstantInfo *info, GArgument *value) { GIRealInfo *rinfo = (GIRealInfo *)info; @@ -2266,7 +2266,7 @@ g_union_info_get_n_fields (GIUnionInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; - + return blob->n_fields; } @@ -2275,10 +2275,10 @@ g_union_info_get_field (GIUnionInfo *info, gint n) { GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - - return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, - rinfo->offset + header->union_blob_size + + Header *header = (Header *)rinfo->typelib->data; + + return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, + rinfo->offset + header->union_blob_size + n * header->field_blob_size); } @@ -2287,7 +2287,7 @@ g_union_info_get_n_methods (GIUnionInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; - + return blob->n_functions; } @@ -2297,13 +2297,13 @@ g_union_info_get_method (GIUnionInfo *info, { GIRealInfo *rinfo = (GIRealInfo *)info; UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; gint offset; - offset = rinfo->offset + header->union_blob_size - + blob->n_fields * header->field_blob_size + offset = rinfo->offset + header->union_blob_size + + blob->n_fields * header->field_blob_size + n * header->function_blob_size; - return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, rinfo->typelib, offset); } @@ -2312,7 +2312,7 @@ g_union_info_is_discriminated (GIUnionInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; - + return blob->discriminated; } @@ -2321,7 +2321,7 @@ g_union_info_get_discriminator_offset (GIUnionInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; - + return blob->discriminator_offset; } @@ -2329,7 +2329,7 @@ GITypeInfo * g_union_info_get_discriminator_type (GIUnionInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - + return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 24); } @@ -2339,19 +2339,19 @@ g_union_info_get_discriminator (GIUnionInfo *info, { GIRealInfo *rinfo = (GIRealInfo *)info; UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; - + if (blob->discriminated) { - Header *header = (Header *)rinfo->typelib->data; + Header *header = (Header *)rinfo->typelib->data; gint offset; - offset = rinfo->offset + header->union_blob_size - + blob->n_fields * header->field_blob_size + offset = rinfo->offset + header->union_blob_size + + blob->n_fields * header->field_blob_size + blob->n_functions * header->function_blob_size + n * header->constant_blob_size; - - return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, - rinfo->typelib, offset); + + return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, + rinfo->typelib, offset); } return NULL; diff --git a/ginvoke.c b/ginvoke.c index b3333f851..2d4c3f562 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -40,31 +40,31 @@ g_invoke_error_quark (void) /** * g_function_info_invoke: * @info: a #GIFunctionInfo describing the function to invoke - * @in_args: an array of #GArguments, one for each in + * @in_args: an array of #GArguments, one for each in * parameter of @info. If there are no in parameter, @in_args * can be %NULL * @n_in_args: the length of the @in_args array * @out_args: an array of #GArguments, one for each out * parameter of @info. If there are no out parameters, @out_args - * may be %NULL + * may be %NULL * @n_out_args: the length of the @out_args array - * @return_value: return location for the return value of the + * @return_value: return location for the return value of the * function. If the function returns void, @return_value may be * %NULL * @error: return location for detailed error information, or %NULL * - * Invokes the function described in @info with the given + * Invokes the function described in @info with the given * arguments. Note that inout parameters must appear in both * argument lists. This function uses dlsym() to obtain a pointer - * to the function, so the library or shared object containing the - * described function must either be linked to the caller, or must + * to the function, so the library or shared object containing the + * described function must either be linked to the caller, or must * have been dlopen()ed before calling this function. * * Returns: %TRUE if the function has been invoked, %FALSE if an - * error occurred. + * error occurred. */ -gboolean -g_function_info_invoke (GIFunctionInfo *info, +gboolean +g_function_info_invoke (GIFunctionInfo *info, const GArgument *in_args, int n_in_args, const GArgument *out_args, @@ -134,7 +134,7 @@ g_function_info_invoke (GIFunctionInfo *info, atypes = g_alloca (sizeof (ffi_type*) * n_invoke_args); args = g_alloca (sizeof (gpointer) * n_invoke_args); - + if (is_method) { atypes[0] = &ffi_type_pointer; @@ -162,7 +162,7 @@ g_function_info_invoke (GIFunctionInfo *info, args[i+offset] = (gpointer)&in_args[in_pos]; in_pos++; - + break; case GI_DIRECTION_OUT: atypes[i+offset] = &ffi_type_pointer; @@ -172,12 +172,12 @@ g_function_info_invoke (GIFunctionInfo *info, g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too few \"out\" arguments (handling out)"); + "Too few \"out\" arguments (handling out)"); goto out; } args[i+offset] = (gpointer)&out_args[out_pos]; - out_pos++; + out_pos++; break; case GI_DIRECTION_INOUT: atypes[i+offset] = &ffi_type_pointer; @@ -196,13 +196,13 @@ g_function_info_invoke (GIFunctionInfo *info, g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too few \"out\" arguments (handling inout)"); + "Too few \"out\" arguments (handling inout)"); goto out; } - + args[i+offset] = (gpointer)&in_args[in_pos]; - in_pos++; - out_pos++; + in_pos++; + out_pos++; break; default: g_assert_not_reached (); @@ -229,7 +229,7 @@ g_function_info_invoke (GIFunctionInfo *info, g_set_error (error, G_INVOKE_ERROR, G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too many \"out\" arguments (at end)"); + "Too many \"out\" arguments (at end)"); goto out; } @@ -382,17 +382,17 @@ gi_cclosure_marshal_generic (GClosure *closure, ffi_cif cif; GCClosure *cc = (GCClosure*) closure; - if (return_gvalue && G_VALUE_TYPE (return_gvalue)) + if (return_gvalue && G_VALUE_TYPE (return_gvalue)) { rtype = value_to_ffi_type (return_gvalue, &rvalue); } - else + else { rtype = &ffi_type_void; } rvalue = g_alloca (MAX (rtype->size, sizeof (ffi_arg))); - + n_args = n_param_values + 1; atypes = g_alloca (sizeof (ffi_type *) * n_args); args = g_alloca (sizeof (gpointer) * n_args); @@ -401,7 +401,7 @@ gi_cclosure_marshal_generic (GClosure *closure, { if (G_CCLOSURE_SWAP_DATA (closure)) { - atypes[n_args-1] = value_to_ffi_type (param_values + 0, + atypes[n_args-1] = value_to_ffi_type (param_values + 0, &args[n_args-1]); atypes[0] = &ffi_type_pointer; args[0] = &closure->data; diff --git a/girepository.c b/girepository.c index e590616da..e7004a9dc 100644 --- a/girepository.c +++ b/girepository.c @@ -40,7 +40,7 @@ static GIRepository *default_repository = NULL; static GSList *search_path = NULL; static GSList *override_search_path = NULL; -struct _GIRepositoryPrivate +struct _GIRepositoryPrivate { GHashTable *typelibs; /* (string) namespace -> GTypelib */ GHashTable *lazy_typelibs; /* (string) namespace-version -> GTypelib */ @@ -49,16 +49,16 @@ struct _GIRepositoryPrivate G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT); -static void +static void g_irepository_init (GIRepository *repository) { repository->priv = G_TYPE_INSTANCE_GET_PRIVATE (repository, G_TYPE_IREPOSITORY, GIRepositoryPrivate); - repository->priv->typelibs + repository->priv->typelibs = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) NULL, (GDestroyNotify) g_typelib_free); - repository->priv->lazy_typelibs + repository->priv->lazy_typelibs = g_hash_table_new (g_str_hash, g_str_equal); repository->priv->info_by_gtype = g_hash_table_new_full (g_direct_hash, g_direct_equal, @@ -74,7 +74,7 @@ g_irepository_finalize (GObject *object) g_hash_table_destroy (repository->priv->typelibs); g_hash_table_destroy (repository->priv->lazy_typelibs); g_hash_table_destroy (repository->priv->info_by_gtype); - + (* G_OBJECT_CLASS (g_irepository_parent_class)->finalize) (G_OBJECT (repository)); } @@ -87,7 +87,7 @@ g_irepository_class_init (GIRepositoryClass *class) gobject_class->finalize = g_irepository_finalize; - g_type_class_add_private (class, sizeof (GIRepositoryPrivate)); + g_type_class_add_private (class, sizeof (GIRepositoryPrivate)); } static void @@ -170,11 +170,11 @@ GSList * build_search_path_with_overrides (void) { GSList *result; - if (override_search_path != NULL) + if (override_search_path != NULL) { result = g_slist_copy (override_search_path); g_slist_last (result)->next = g_slist_copy (search_path); - } + } else result = g_slist_copy (search_path); return result; @@ -216,7 +216,7 @@ get_repository (GIRepository *repository) } static GTypelib * -check_version_conflict (GTypelib *typelib, +check_version_conflict (GTypelib *typelib, const gchar *namespace, const gchar *expected_version, char **version_conflict) @@ -230,11 +230,11 @@ check_version_conflict (GTypelib *typelib, *version_conflict = NULL; return typelib; } - + header = (Header*)typelib->data; loaded_version = g_typelib_get_string (typelib, header->nsversion); g_assert (loaded_version != NULL); - + if (strcmp (expected_version, loaded_version) != 0) { if (version_conflict) @@ -259,7 +259,7 @@ get_registered_status (GIRepository *repository, if (lazy_status) *lazy_status = FALSE; typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); - if (typelib) + if (typelib) return check_version_conflict (typelib, namespace, version, version_conflict); typelib = g_hash_table_lookup (repository->priv->lazy_typelibs, namespace); if (!typelib) @@ -291,7 +291,7 @@ load_dependencies_recurse (GIRepository *repository, if (dependencies != NULL) { int i; - + for (i = 0; dependencies[i]; i++) { char *dependency = dependencies[i]; @@ -302,7 +302,7 @@ load_dependencies_recurse (GIRepository *repository, last_dash = strrchr (dependency, '-'); dependency_namespace = g_strndup (dependency, last_dash - dependency); dependency_version = last_dash+1; - + if (!g_irepository_require (repository, dependency_namespace, dependency_version, 0, error)) { @@ -329,7 +329,7 @@ register_internal (GIRepository *repository, const gchar *version; g_return_val_if_fail (typelib != NULL, FALSE); - + header = (Header *)typelib->data; g_return_val_if_fail (header != NULL, FALSE); @@ -339,9 +339,9 @@ register_internal (GIRepository *repository, if (lazy) { - g_assert (!g_hash_table_lookup (repository->priv->lazy_typelibs, + g_assert (!g_hash_table_lookup (repository->priv->lazy_typelibs, namespace)); - g_hash_table_insert (repository->priv->lazy_typelibs, + g_hash_table_insert (repository->priv->lazy_typelibs, build_typelib_key (namespace, source), (void *)typelib); } else @@ -352,9 +352,9 @@ register_internal (GIRepository *repository, /* First, try loading all the dependencies */ if (!load_dependencies_recurse (repository, typelib, error)) return NULL; - + /* Check if we are transitioning from lazily loaded state */ - if (g_hash_table_lookup_extended (repository->priv->lazy_typelibs, + if (g_hash_table_lookup_extended (repository->priv->lazy_typelibs, namespace, (gpointer)&key, &value)) g_hash_table_remove (repository->priv->lazy_typelibs, key); @@ -416,7 +416,7 @@ g_irepository_load_typelib (GIRepository *repository, namespace = g_typelib_get_string (typelib, header->namespace); nsversion = g_typelib_get_string (typelib, header->nsversion); - if (get_registered_status (repository, namespace, nsversion, allow_lazy, + if (get_registered_status (repository, namespace, nsversion, allow_lazy, &is_lazy, &version_conflict)) { if (version_conflict != NULL) @@ -429,7 +429,7 @@ g_irepository_load_typelib (GIRepository *repository, } return namespace; } - return register_internal (repository, "", + return register_internal (repository, "", allow_lazy, typelib, error); } @@ -445,11 +445,11 @@ g_irepository_load_typelib (GIRepository *repository, * metadata in the namespace, you should call #g_irepository_require * instead which will ensure the namespace is loaded, and return as * quickly as this function will if it has already been loaded. - * + * * Returns: %TRUE if namespace-version is loaded, %FALSE otherwise */ gboolean -g_irepository_is_registered (GIRepository *repository, +g_irepository_is_registered (GIRepository *repository, const gchar *namespace, const gchar *version) { @@ -470,10 +470,10 @@ g_irepository_is_registered (GIRepository *repository, * All methods on #GIRepository also accept %NULL as an instance * parameter to mean this default repository, which is usually more * convenient for C. - * - * Returns: (transfer none): The global singleton #GIRepository + * + * Returns: (transfer none): The global singleton #GIRepository */ -GIRepository * +GIRepository * g_irepository_get_default (void) { return get_repository (NULL); @@ -490,7 +490,7 @@ g_irepository_get_default (void) * * Returns: number of metadata entries */ -gint +gint g_irepository_get_n_infos (GIRepository *repository, const gchar *namespace) { @@ -500,7 +500,7 @@ g_irepository_get_n_infos (GIRepository *repository, g_return_val_if_fail (namespace != NULL, -1); repository = get_repository (repository); - + typelib = get_registered (repository, namespace, NULL); g_return_val_if_fail (typelib != NULL, -1); @@ -533,7 +533,7 @@ find_interface (gpointer key, gint n_entries; const gchar *name; const gchar *type; - DirEntry *entry; + DirEntry *entry; index = 0; n_entries = ((Header *)typelib->data)->n_local_entries; @@ -624,7 +624,7 @@ find_interface (gpointer key, * * Returns: #GIBaseInfo containing metadata */ -GIBaseInfo * +GIBaseInfo * g_irepository_get_info (GIRepository *repository, const gchar *namespace, gint index) @@ -643,12 +643,12 @@ g_irepository_get_info (GIRepository *repository, data.iface = NULL; typelib = get_registered (repository, namespace, NULL); - + g_return_val_if_fail (typelib != NULL, NULL); find_interface ((void *)namespace, typelib, &data); - return data.iface; + return data.iface; } /** @@ -665,7 +665,7 @@ g_irepository_get_info (GIRepository *repository, * * Returns: #GIBaseInfo representing metadata about @type, or %NULL */ -GIBaseInfo * +GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository, GType gtype) { @@ -718,7 +718,7 @@ g_irepository_find_by_gtype (GIRepository *repository, * * Returns: #GIBaseInfo representing metadata about @name, or %NULL */ -GIBaseInfo * +GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, const gchar *namespace, const gchar *name) @@ -737,7 +737,7 @@ g_irepository_find_by_name (GIRepository *repository, data.iface = NULL; typelib = get_registered (repository, namespace, NULL); - + g_return_val_if_fail (typelib != NULL, NULL); find_interface ((void *)namespace, typelib, &data); @@ -763,7 +763,7 @@ collect_namespaces (gpointer key, * * Returns: (utf8) (transfer full): List of namespaces */ -gchar ** +gchar ** g_irepository_get_loaded_namespaces (GIRepository *repository) { GList *l, *list = NULL; @@ -778,7 +778,7 @@ g_irepository_get_loaded_namespaces (GIRepository *repository) names = g_malloc0 (sizeof (gchar *) * (g_list_length (list) + 1)); i = 0; for (l = list; l; l = l->next) - names[i++] = g_strdup (l->data); + names[i++] = g_strdup (l->data); g_list_free (list); return names; @@ -895,14 +895,14 @@ g_irepository_get_c_prefix (GIRepository *repository, * @namespace_: GI namespace to use, e.g. "Gtk" * * If namespace @namespace_ is loaded, return the full path to the - * .typelib file it was loaded from. If the typelib for + * .typelib file it was loaded from. If the typelib for * namespace @namespace_ was included in a shared library, return * the special string "$lt;builtin$gt;". * * Returns: Filesystem path (or $lt;builtin$gt;) if successful, %NULL if namespace is not loaded */ -const gchar * +const gchar * g_irepository_get_typelib_path (GIRepository *repository, const gchar *namespace) { @@ -915,7 +915,7 @@ g_irepository_get_typelib_path (GIRepository *repository, { if (!g_hash_table_lookup_extended (repository->priv->lazy_typelibs, namespace, &orig_key, &value)) - + return NULL; } return ((char*)orig_key) + strlen ((char *) orig_key) + 1; @@ -933,14 +933,14 @@ find_namespace_version (const gchar *namespace, GError *error = NULL; GMappedFile *mfile = NULL; char *fname; - + fname = g_strdup_printf ("%s-%s.typelib", namespace, version); tmp_path = build_search_path_with_overrides (); for (ldir = tmp_path; ldir; ldir = ldir->next) { char *path = g_build_filename (ldir->data, fname, NULL); - + mfile = g_mapped_file_new (path, FALSE, &error); if (error) { @@ -1022,7 +1022,7 @@ compare_candidate_reverse (struct NamespaceVersionCandidadate *c1, return -1; else if (result < 0) return 1; - else + else { /* Now check the path index, which says how early in the search path * we found it. This ensures that of equal version targets, we @@ -1067,7 +1067,7 @@ find_namespace_latest (const gchar *namespace, namespace_typelib = g_strdup_printf ("%s.typelib", namespace); index = 0; - tmp_path = build_search_path_with_overrides (); + tmp_path = build_search_path_with_overrides (); for (ldir = tmp_path; ldir; ldir = ldir->next) { GDir *dir; @@ -1078,7 +1078,7 @@ find_namespace_latest (const gchar *namespace, dir = g_dir_open (dirname, 0, NULL); if (dir == NULL) continue; - while ((entry = g_dir_read_name (dir)) != NULL) + while ((entry = g_dir_read_name (dir)) != NULL) { GMappedFile *mfile; char *path, *version; @@ -1086,7 +1086,7 @@ find_namespace_latest (const gchar *namespace, if (!g_str_has_suffix (entry, ".typelib")) continue; - + if (g_str_has_prefix (entry, namespace_dash)) { const char *last_dash; @@ -1126,21 +1126,21 @@ find_namespace_latest (const gchar *namespace, { struct NamespaceVersionCandidadate *elected; candidates = g_slist_sort (candidates, (GCompareFunc) compare_candidate_reverse); - + elected = (struct NamespaceVersionCandidadate *) candidates->data; /* Remove the elected one so we don't try to free its contents */ candidates = g_slist_delete_link (candidates, candidates); - + result = elected->mfile; *path_ret = elected->path; *version_ret = elected->version; g_free (elected); /* just free the container */ g_slist_foreach (candidates, (GFunc) free_candidate, NULL); g_slist_free (candidates); - } + } g_free (namespace_dash); g_free (namespace_typelib); - g_slist_free (tmp_path); + g_slist_free (tmp_path); return result; } @@ -1182,7 +1182,7 @@ g_irepository_require (GIRepository *repository, repository = get_repository (repository); - typelib = get_registered_status (repository, namespace, version, allow_lazy, + typelib = get_registered_status (repository, namespace, version, allow_lazy, &is_lazy, &version_conflict); if (typelib) return typelib; @@ -1205,7 +1205,7 @@ g_irepository_require (GIRepository *repository, { mfile = find_namespace_latest (namespace, &tmp_version, &path); } - + if (mfile == NULL) { if (version != NULL) @@ -1225,7 +1225,7 @@ g_irepository_require (GIRepository *repository, header = (Header *) typelib->data; typelib_namespace = g_typelib_get_string (typelib, header->namespace); typelib_version = g_typelib_get_string (typelib, header->nsversion); - + if (strcmp (typelib_namespace, namespace) != 0) { g_set_error (error, G_IREPOSITORY_ERROR, @@ -1245,7 +1245,7 @@ g_irepository_require (GIRepository *repository, goto out; } - if (!register_internal (repository, path, allow_lazy, + if (!register_internal (repository, path, allow_lazy, typelib, error)) { g_typelib_free (typelib); @@ -1255,7 +1255,7 @@ g_irepository_require (GIRepository *repository, out: g_free (tmp_version); g_free (path); - return ret; + return ret; } static gboolean diff --git a/girepository.h b/girepository.h index 93cf126ac..083b11c06 100644 --- a/girepository.h +++ b/girepository.h @@ -34,9 +34,9 @@ G_BEGIN_DECLS #define G_IS_IREPOSITORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_IREPOSITORY)) #define G_IREPOSITORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_IREPOSITORY, GIRepositoryClass)) -typedef struct _GIRepository GIRepository; -typedef struct _GIRepositoryClass GIRepositoryClass; -typedef struct _GIRepositoryPrivate GIRepositoryPrivate; +typedef struct _GIRepository GIRepository; +typedef struct _GIRepositoryClass GIRepositoryClass; +typedef struct _GIRepositoryPrivate GIRepositoryPrivate; typedef struct _GIBaseInfoStub GIBaseInfo; @@ -73,8 +73,8 @@ typedef GIBaseInfo GIErrorDomainInfo; typedef struct _GIUnresolvedInfo GIUnresolvedInfo; typedef struct _GTypelib GTypelib; -struct _GIRepository -{ +struct _GIRepository +{ GObject parent; /*< private >*/ @@ -82,8 +82,8 @@ struct _GIRepository }; struct _GIRepositoryClass -{ - GObjectClass parent; +{ + GObjectClass parent; }; typedef enum @@ -173,7 +173,7 @@ void gi_cclosure_marshal_generic (GClosure *closure, /* Types of objects registered in the repository */ -typedef enum +typedef enum { GI_INFO_TYPE_INVALID, GI_INFO_TYPE_FUNCTION, @@ -226,7 +226,7 @@ gboolean g_base_info_equal (GIBaseInfo *info1, GIBaseInfo * g_info_new (GIInfoType type, GIBaseInfo *container, - GTypelib *typelib, + GTypelib *typelib, guint32 offset); @@ -247,7 +247,7 @@ GIFunctionInfoFlags g_function_info_get_flags (GIFunctionInfo *info); GIPropertyInfo * g_function_info_get_property (GIFunctionInfo *info); GIVFuncInfo * g_function_info_get_vfunc (GIFunctionInfo *info); -typedef union +typedef union { gboolean v_boolean; gint8 v_int8; @@ -282,7 +282,7 @@ typedef enum G_INVOKE_ERROR_ARGUMENT_MISMATCH } GInvokeError; -gboolean g_function_info_invoke (GIFunctionInfo *info, +gboolean g_function_info_invoke (GIFunctionInfo *info, const GArgument *in_args, int n_in_args, const GArgument *out_args, @@ -323,8 +323,8 @@ typedef enum { GI_SCOPE_TYPE_INVALID, /* The argument is not of callback type */ GI_SCOPE_TYPE_CALL, /* The callback and associated user_data is only used during the call to this function */ - GI_SCOPE_TYPE_ASYNC, /* The callback and associated user_data is - only used until the callback is invoked, and the callback + GI_SCOPE_TYPE_ASYNC, /* The callback and associated user_data is + only used until the callback is invoked, and the callback is invoked always exactly once. */ GI_SCOPE_TYPE_NOTIFIED /* The callback and and associated user_data is used until the caller is notfied via the destroy_notify */ @@ -353,7 +353,7 @@ typedef enum { GI_TYPE_TAG_INT8 = 2, GI_TYPE_TAG_UINT8 = 3, GI_TYPE_TAG_INT16 = 4, - GI_TYPE_TAG_UINT16 = 5, + GI_TYPE_TAG_UINT16 = 5, GI_TYPE_TAG_INT32 = 6, GI_TYPE_TAG_UINT32 = 7, GI_TYPE_TAG_INT64 = 8, @@ -407,7 +407,7 @@ GIInterfaceInfo * g_error_domain_info_get_codes (GIErrorDomainInfo *in /* GIValueInfo */ - + glong g_value_info_get_value (GIValueInfo *info); @@ -477,8 +477,8 @@ GITypeTag g_enum_info_get_storage_type (GIEnumInfo *in /* GIObjectInfo */ -const gchar * g_object_info_get_type_name (GIObjectInfo *info); -const gchar * g_object_info_get_type_init (GIObjectInfo *info); +const gchar * g_object_info_get_type_name (GIObjectInfo *info); +const gchar * g_object_info_get_type_init (GIObjectInfo *info); gboolean g_object_info_get_abstract (GIObjectInfo *info); GIObjectInfo * g_object_info_get_parent (GIObjectInfo *info); gint g_object_info_get_n_interfaces (GIObjectInfo *info); @@ -508,7 +508,7 @@ GIConstantInfo * g_object_info_get_constant (GIObjectInfo *in gint n); GIStructInfo * g_object_info_get_class_struct (GIObjectInfo *info); - + /* GIInterfaceInfo */ gint g_interface_info_get_n_prerequisites (GIInterfaceInfo *info); @@ -521,7 +521,7 @@ gint g_interface_info_get_n_methods (GIInterfaceInfo *in GIFunctionInfo * g_interface_info_get_method (GIInterfaceInfo *info, gint n); GIFunctionInfo * g_interface_info_find_method (GIInterfaceInfo *info, - const gchar *name); + const gchar *name); gint g_interface_info_get_n_signals (GIInterfaceInfo *info); GISignalInfo * g_interface_info_get_signal (GIInterfaceInfo *info, gint n); diff --git a/girffi.c b/girffi.c index 769cd6b01..88cafec90 100644 --- a/girffi.c +++ b/girffi.c @@ -114,7 +114,7 @@ g_ir_ffi_get_ffi_type (GITypeTag tag, g_assert_not_reached (); return NULL; -} +} /** * g_type_info_get_ffi_type: @@ -140,13 +140,13 @@ g_callable_info_get_ffi_arg_types (GICallableInfo *callable_info) { ffi_type **arg_types; gint n_args, i; - + g_return_val_if_fail (callable_info != NULL, NULL); n_args = g_callable_info_get_n_args (callable_info); - + arg_types = (ffi_type **) g_new0 (ffi_type *, n_args + 1); - + for (i = 0; i < n_args; ++i) { GIArgInfo *arg_info = g_callable_info_get_arg (callable_info, i); @@ -181,7 +181,7 @@ g_callable_info_get_ffi_return_type (GICallableInfo *callable_info) type_tag = g_type_info_get_tag (return_type); return_ffi_type = g_type_info_get_ffi_type (return_type); g_base_info_unref((GIBaseInfo*)return_type); - + return return_ffi_type; } @@ -212,12 +212,12 @@ g_function_info_prep_invoker (GIFunctionInfo *info, gboolean is_method; gboolean throws; gint n_args, n_invoke_args, i; - + g_return_val_if_fail (info != NULL, FALSE); g_return_val_if_fail (invoker != NULL, FALSE); - + symbol = g_function_info_get_symbol ((GIFunctionInfo*) info); - + if (!g_typelib_symbol (g_base_info_get_typelib((GIBaseInfo *) info), symbol, &(invoker->native_address))) { @@ -249,7 +249,7 @@ g_function_info_prep_invoker (GIFunctionInfo *info, /* TODO: avoid malloc here? */ atypes = g_malloc0 (sizeof (ffi_type*) * n_invoke_args); - + if (is_method) { atypes[0] = &ffi_type_pointer; @@ -286,7 +286,7 @@ g_function_info_prep_invoker (GIFunctionInfo *info, /** * g_function_info_invoker_destroy: * @invoker: A #GIFunctionInvoker - * + * * Release all resources allocated for the internals of @invoker; callers * are responsible for freeing any resources allocated for the structure * itself however. @@ -320,11 +320,11 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, { ffi_closure *closure; ffi_status status; - + g_return_val_if_fail (callable_info != NULL, FALSE); g_return_val_if_fail (cif != NULL, FALSE); g_return_val_if_fail (callback != NULL, FALSE); - + closure = mmap (NULL, sizeof (ffi_closure), PROT_EXEC | PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, sysconf (_SC_PAGE_SIZE)); @@ -359,7 +359,7 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, munmap(closure, sizeof (closure)); return NULL; } - + return closure; } diff --git a/girffi.h b/girffi.h index 10a20a243..54ce7b58f 100644 --- a/girffi.h +++ b/girffi.h @@ -36,7 +36,7 @@ typedef struct _GIFunctionInvoker GIFunctionInvoker; struct _GIFunctionInvoker { ffi_cif cif; gpointer native_address; - + gpointer padding[3]; }; @@ -45,7 +45,7 @@ ffi_type * g_type_info_get_ffi_type (GITypeInfo *info); gboolean g_function_info_prep_invoker (GIFunctionInfo *info, GIFunctionInvoker *invoker, GError **error); - + void g_function_invoker_destroy (GIFunctionInvoker *invoker); diff --git a/girmodule.c b/girmodule.c index b954d15de..66efceb26 100644 --- a/girmodule.c +++ b/girmodule.c @@ -1,4 +1,4 @@ -/* GObject introspection: Typelib creation +/* GObject introspection: Typelib creation * * Copyright (C) 2005 Matthias Clasen * @@ -30,13 +30,13 @@ GIrModule * -g_ir_module_new (const gchar *name, +g_ir_module_new (const gchar *name, const gchar *version, const gchar *shared_library, const gchar *c_prefix) { GIrModule *module; - + module = g_new0 (GIrModule, 1); module->name = g_strdup (name); @@ -94,18 +94,18 @@ g_ir_module_fatal (GIrModule *module, char *formatted; va_list args; - + va_start (args, msg); - + formatted = g_strdup_vprintf (msg, args); - + if (line) g_printerr ("%s-%s.gir:%d: error: %s\n", module->name, module->version, line, formatted); else g_printerr ("%s-%s.gir: error: %s\n", module->name, module->version, formatted); - + exit (1); - + va_end (args); } @@ -247,7 +247,7 @@ g_ir_module_build_typelib (GIrModule *module, g_message ("%d entries (%d local), %d dependencies\n", n_entries, n_local_entries, g_list_length (module->dependencies)); - + dir_size = n_entries * sizeof (DirEntry); size = header_size + dir_size; @@ -256,7 +256,7 @@ g_ir_module_build_typelib (GIrModule *module, for (e = module->entries; e; e = e->next) { GIrNode *node = e->data; - + size += g_ir_node_get_full_size (node); size += g_ir_node_get_attribute_size (node); @@ -266,14 +266,14 @@ g_ir_module_build_typelib (GIrModule *module, /* Adjust size for strings allocated in header below specially */ size += ALIGN_VALUE (strlen (module->name) + 1, 4); - if (module->shared_library) + if (module->shared_library) size += ALIGN_VALUE (strlen (module->shared_library) + 1, 4); if (dependencies != NULL) size += ALIGN_VALUE (strlen (dependencies) + 1, 4); if (module->c_prefix != NULL) size += ALIGN_VALUE (strlen (module->c_prefix) + 1, 4); - g_message ("allocating %d bytes (%d header, %d directory, %d entries)\n", + 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); @@ -361,13 +361,13 @@ g_ir_module_build_typelib (GIrModule *module, goto restart; } - + offset = offset2; if (node->type == G_IR_NODE_XREF) { const char *namespace = ((GIrNodeXRef*)node)->namespace; - + entry->blob_type = 0; entry->local = FALSE; entry->offset = write_string (namespace, strings, data, &offset2); @@ -419,7 +419,7 @@ g_ir_module_build_typelib (GIrModule *module, write_attributes (module, node, strings, data, &offset, &offset2); } - + g_message ("reallocating to %d bytes", offset2); data = g_realloc (data, offset2); diff --git a/girmodule.h b/girmodule.h index da3fb35dd..3ebb3eb72 100644 --- a/girmodule.h +++ b/girmodule.h @@ -30,7 +30,7 @@ G_BEGIN_DECLS typedef struct _GIrModule GIrModule; struct _GIrModule -{ +{ gchar *name; gchar *version; gchar *shared_library; diff --git a/girnode.c b/girnode.c index ede6d3b7f..43bdfa631 100644 --- a/girnode.c +++ b/girnode.c @@ -213,7 +213,7 @@ g_ir_node_free (GIrNode *node) case G_IR_NODE_CALLBACK: { GIrNodeFunction *function = (GIrNodeFunction *)node; - + g_free (node->name); g_free (function->symbol); g_ir_node_free ((GIrNode *)function->result); @@ -226,7 +226,7 @@ g_ir_node_free (GIrNode *node) case G_IR_NODE_TYPE: { GIrNodeType *type = (GIrNodeType *)node; - + g_free (node->name); g_ir_node_free ((GIrNode *)type->parameter_type1); g_ir_node_free ((GIrNode *)type->parameter_type2); @@ -240,7 +240,7 @@ g_ir_node_free (GIrNode *node) case G_IR_NODE_PARAM: { GIrNodeParam *param = (GIrNodeParam *)node; - + g_free (node->name); g_ir_node_free ((GIrNode *)param->type); } @@ -249,7 +249,7 @@ g_ir_node_free (GIrNode *node) case G_IR_NODE_PROPERTY: { GIrNodeProperty *property = (GIrNodeProperty *)node; - + g_free (node->name); g_ir_node_free ((GIrNode *)property->type); } @@ -258,7 +258,7 @@ g_ir_node_free (GIrNode *node) case G_IR_NODE_SIGNAL: { GIrNodeSignal *signal = (GIrNodeSignal *)node; - + g_free (node->name); for (l = signal->parameters; l; l = l->next) g_ir_node_free ((GIrNode *)l->data); @@ -270,7 +270,7 @@ g_ir_node_free (GIrNode *node) case G_IR_NODE_VFUNC: { GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node; - + g_free (node->name); g_free (vfunc->invoker); for (l = vfunc->parameters; l; l = l->next) @@ -283,7 +283,7 @@ g_ir_node_free (GIrNode *node) case G_IR_NODE_FIELD: { GIrNodeField *field = (GIrNodeField *)node; - + g_free (node->name); g_ir_node_free ((GIrNode *)field->type); g_ir_node_free ((GIrNode *)field->callback); @@ -294,7 +294,7 @@ g_ir_node_free (GIrNode *node) case G_IR_NODE_INTERFACE: { GIrNodeInterface *iface = (GIrNodeInterface *)node; - + g_free (node->name); g_free (iface->gtype_name); g_free (iface->gtype_init); @@ -313,7 +313,7 @@ g_ir_node_free (GIrNode *node) } break; - + case G_IR_NODE_VALUE: { g_free (node->name); @@ -324,7 +324,7 @@ g_ir_node_free (GIrNode *node) case G_IR_NODE_FLAGS: { GIrNodeEnum *enum_ = (GIrNodeEnum *)node; - + g_free (node->name); g_free (enum_->gtype_name); g_free (enum_->gtype_init); @@ -338,7 +338,7 @@ g_ir_node_free (GIrNode *node) case G_IR_NODE_BOXED: { GIrNodeBoxed *boxed = (GIrNodeBoxed *)node; - + g_free (node->name); g_free (boxed->gtype_name); g_free (boxed->gtype_init); @@ -366,7 +366,7 @@ g_ir_node_free (GIrNode *node) case G_IR_NODE_CONSTANT: { GIrNodeConstant *constant = (GIrNodeConstant *)node; - + g_free (node->name); g_free (constant->value); g_ir_node_free ((GIrNode *)constant->type); @@ -376,7 +376,7 @@ g_ir_node_free (GIrNode *node) case G_IR_NODE_ERROR_DOMAIN: { GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node; - + g_free (node->name); g_free (domain->getquark); g_free (domain->codes); @@ -386,7 +386,7 @@ g_ir_node_free (GIrNode *node) case G_IR_NODE_XREF: { GIrNodeXRef *xref = (GIrNodeXRef *)node; - + g_free (node->name); g_free (xref->namespace); } @@ -395,7 +395,7 @@ g_ir_node_free (GIrNode *node) case G_IR_NODE_UNION: { GIrNodeUnion *union_ = (GIrNodeUnion *)node; - + g_free (node->name); g_free (union_->gtype_name); g_free (union_->gtype_init); @@ -411,7 +411,7 @@ g_ir_node_free (GIrNode *node) default: g_error ("Unhandled node type %d\n", node->type); break; - } + } g_hash_table_destroy (node->attributes); @@ -472,7 +472,7 @@ g_ir_node_get_size (GIrNode *node) case G_IR_NODE_FLAGS: { GIrNodeEnum *enum_ = (GIrNodeEnum *)node; - + size = sizeof (EnumBlob); for (l = enum_->values; l; l = l->next) size += g_ir_node_get_size ((GIrNode *)l->data); @@ -549,7 +549,7 @@ g_ir_node_get_size (GIrNode *node) } break; - default: + default: g_error ("Unhandled node type '%s'\n", g_ir_node_type_to_string (node->type)); size = 0; @@ -617,12 +617,12 @@ g_ir_node_get_full_size_internal (GIrNode *parent, case G_IR_NODE_PARAM: { GIrNodeParam *param = (GIrNodeParam *)node; - + /* See the comment in the G_IR_NODE_PARAM/ArgBlob writing below */ size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob); if (node->name) size += ALIGN_VALUE (strlen (node->name) + 1, 4); - size += g_ir_node_get_full_size_internal (node, (GIrNode *)param->type); + size += g_ir_node_get_full_size_internal (node, (GIrNode *)param->type); } break; @@ -661,7 +661,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, case GI_TYPE_TAG_ERROR: { gint n; - + if (type->errors) n = g_strv_length (type->errors); else @@ -719,7 +719,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, case G_IR_NODE_FLAGS: { GIrNodeEnum *enum_ = (GIrNodeEnum *)node; - + size = sizeof (EnumBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); if (enum_->gtype_name) @@ -729,7 +729,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, } for (l = enum_->values; l; l = l->next) - size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); } break; @@ -774,10 +774,10 @@ g_ir_node_get_full_size_internal (GIrNode *parent, case G_IR_NODE_PROPERTY: { GIrNodeProperty *prop = (GIrNodeProperty *)node; - + size = sizeof (PropertyBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); - size += g_ir_node_get_full_size_internal (node, (GIrNode *)prop->type); + size += g_ir_node_get_full_size_internal (node, (GIrNode *)prop->type); } break; @@ -826,7 +826,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size += ALIGN_VALUE (strlen (node->name) + 1, 4); /* FIXME non-string values */ size += ALIGN_VALUE (strlen (constant->value) + 1, 4); - size += g_ir_node_get_full_size_internal (node, (GIrNode *)constant->type); + size += g_ir_node_get_full_size_internal (node, (GIrNode *)constant->type); } break; @@ -843,7 +843,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, case G_IR_NODE_XREF: { GIrNodeXRef *xref = (GIrNodeXRef *)node; - + size = 0; size += ALIGN_VALUE (strlen (node->name) + 1, 4); size += ALIGN_VALUE (strlen (xref->namespace) + 1, 4); @@ -867,7 +867,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, } break; - default: + default: g_error ("Unknown type tag %d\n", node->type); size = 0; } @@ -947,7 +947,7 @@ g_ir_node_add_member (GIrNode *node, { g_return_if_fail (node != NULL); g_return_if_fail (member != NULL); - + switch (node->type) { case G_IR_NODE_OBJECT: @@ -1026,7 +1026,7 @@ parse_boolean_value (const gchar *str) { if (strcmp (str, "TRUE") == 0) return TRUE; - + if (strcmp (str, "FALSE") == 0) return FALSE; @@ -1048,31 +1048,31 @@ find_entry_node (GIrModule *module, g_assert (name != NULL); g_assert (strlen (name) > 0); - + names = g_strsplit (name, ".", 0); n_names = g_strv_length (names); if (n_names > 2) g_error ("Too many name parts"); - + for (l = module->entries, i = 1; l; l = l->next, i++) { GIrNode *node = (GIrNode *)l->data; - + if (n_names > 1) { if (node->type != G_IR_NODE_XREF) continue; - + if (((GIrNodeXRef *)node)->namespace == NULL || strcmp (((GIrNodeXRef *)node)->namespace, names[0]) != 0) continue; } - + if (strcmp (node->name, names[n_names - 1]) == 0) { if (idx) *idx = i; - + result = node; goto out; } @@ -1084,9 +1084,9 @@ find_entry_node (GIrModule *module, ((GIrNodeXRef *)node)->namespace = g_strdup (names[0]); node->name = g_strdup (names[1]); - + module->entries = g_list_append (module->entries, node); - + if (idx) *idx = g_list_length (module->entries); @@ -1229,23 +1229,23 @@ get_index_of_member_type (GIrNodeInterface *node, } static void -serialize_type (GIrModule *module, +serialize_type (GIrModule *module, GList *modules, - GIrNodeType *node, + GIrNodeType *node, GString *str) { gint i; const gchar* basic[] = { - "void", - "boolean", - "int8", - "uint8", - "int16", - "uint16", - "int32", - "uint32", - "int64", - "uint64", + "void", + "boolean", + "int8", + "uint8", + "int16", + "uint16", + "int32", + "uint32", + "int64", + "uint64", "short", "ushort", "int", @@ -1254,14 +1254,14 @@ serialize_type (GIrModule *module, "ulong", "ssize", "size", - "float", + "float", "double", "time_t", "GType", - "utf8", + "utf8", "filename", }; - + if (node->tag < GI_TYPE_TAG_ARRAY) { g_string_append_printf (str, "%s%s", basic[node->tag], @@ -1276,11 +1276,11 @@ serialize_type (GIrModule *module, g_string_append_printf (str, "length=%d", node->length); else if (node->has_size) g_string_append_printf (str, "fixed-size=%d", node->size); - + if (node->zero_terminated) - g_string_append_printf (str, "%szero-terminated=1", + g_string_append_printf (str, "%szero-terminated=1", node->has_length ? "," : ""); - + g_string_append (str, "]"); } else if (node->tag == GI_TYPE_TAG_INTERFACE) @@ -1309,9 +1309,9 @@ serialize_type (GIrModule *module, g_string_append (str, "GList"); if (node->parameter_type1) { - g_string_append (str, "<"); + g_string_append (str, "<"); serialize_type (module, modules, node->parameter_type1, str); - g_string_append (str, ">"); + g_string_append (str, ">"); } } else if (node->tag == GI_TYPE_TAG_GSLIST) @@ -1319,9 +1319,9 @@ serialize_type (GIrModule *module, g_string_append (str, "GSList"); if (node->parameter_type1) { - g_string_append (str, "<"); + g_string_append (str, "<"); serialize_type (module, modules, node->parameter_type1, str); - g_string_append (str, ">"); + g_string_append (str, ">"); } } else if (node->tag == GI_TYPE_TAG_GHASH) @@ -1329,11 +1329,11 @@ serialize_type (GIrModule *module, g_string_append (str, "GHashTable<"); if (node->parameter_type1) { - g_string_append (str, "<"); + g_string_append (str, "<"); serialize_type (module, modules, node->parameter_type1, str); - g_string_append (str, ","); + g_string_append (str, ","); serialize_type (module, modules, node->parameter_type2, str); - g_string_append (str, ">"); + g_string_append (str, ">"); } } else if (node->tag == GI_TYPE_TAG_ERROR) @@ -1341,14 +1341,14 @@ serialize_type (GIrModule *module, g_string_append (str, "GError"); if (node->errors) { - g_string_append (str, "<"); + 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, ">"); + g_string_append (str, ">"); } } } @@ -1450,27 +1450,27 @@ g_ir_node_build_typelib (GIrNode *node, SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset]; *offset += sizeof (SimpleTypeBlob); - + if (type->tag < GI_TYPE_TAG_ARRAY || type->tag == GI_TYPE_TAG_UTF8 || type->tag == GI_TYPE_TAG_FILENAME) - { + { blob->flags.reserved = 0; blob->flags.reserved2 = 0; blob->flags.pointer = type->is_pointer; blob->flags.reserved3 = 0; blob->flags.tag = type->tag; } - else + 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) @@ -1482,7 +1482,7 @@ g_ir_node_build_typelib (GIrNode *node, { unique_types_count += 1; g_hash_table_insert (types, s, GUINT_TO_POINTER(*offset2)); - + blob->offset = *offset2; switch (type->tag) { @@ -1490,7 +1490,7 @@ g_ir_node_build_typelib (GIrNode *node, { ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2]; guint32 pos; - + array->pointer = 1; array->reserved = 0; array->tag = type->tag; @@ -1504,15 +1504,15 @@ g_ir_node_build_typelib (GIrNode *node, array->dimensions.size = type->size; else array->dimensions.length = -1; - + pos = *offset2 + G_STRUCT_OFFSET (ArrayTypeBlob, type); *offset2 += sizeof (ArrayTypeBlob); - + g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, node, build, &pos, offset2); } break; - + case GI_TYPE_TAG_INTERFACE: { InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2]; @@ -1526,69 +1526,69 @@ g_ir_node_build_typelib (GIrNode *node, } break; - + case GI_TYPE_TAG_GLIST: case GI_TYPE_TAG_GSLIST: { 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 + G_STRUCT_OFFSET (ParamTypeBlob, type); *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob); - - g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, + + g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, node, build, &pos, offset2); } break; - + case GI_TYPE_TAG_GHASH: { 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 + G_STRUCT_OFFSET (ParamTypeBlob, type); *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob)*2; - - g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, + + g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, node, build, &pos, offset2); - g_ir_node_build_typelib ((GIrNode *)type->parameter_type2, + g_ir_node_build_typelib ((GIrNode *)type->parameter_type2, node, build, &pos, offset2); } break; - + case GI_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) + if (type->errors) blob->n_domains = g_strv_length (type->errors); else blob->n_domains = 0; - + *offset2 = ALIGN_VALUE (*offset2 + G_STRUCT_OFFSET (ErrorTypeBlob, domains) + 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; @@ -1649,7 +1649,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->construct_only = prop->construct_only; blob->reserved = 0; - g_ir_node_build_typelib ((GIrNode *)prop->type, + g_ir_node_build_typelib ((GIrNode *)prop->type, node, build, offset, offset2); } break; @@ -1683,7 +1683,7 @@ g_ir_node_build_typelib (GIrNode *node, g_debug ("building function '%s'", function->symbol); - g_ir_node_build_typelib ((GIrNode *)function->result->type, + g_ir_node_build_typelib ((GIrNode *)function->result->type, node, build, &signature, offset2); blob2->may_return_null = function->result->allow_none; @@ -1693,7 +1693,7 @@ g_ir_node_build_typelib (GIrNode *node, blob2->n_arguments = n; signature += 4; - + for (l = function->parameters; l; l = l->next) { GIrNode *param = (GIrNode *)l->data; @@ -1723,8 +1723,8 @@ g_ir_node_build_typelib (GIrNode *node, blob->reserved = 0; blob->name = write_string (node->name, strings, data, offset2); blob->signature = signature; - - g_ir_node_build_typelib ((GIrNode *)function->result->type, + + g_ir_node_build_typelib ((GIrNode *)function->result->type, node, build, &signature, offset2); blob2->may_return_null = function->result->allow_none; @@ -1734,7 +1734,7 @@ g_ir_node_build_typelib (GIrNode *node, blob2->n_arguments = n; signature += 4; - + for (l = function->parameters; l; l = l->next) { GIrNode *param = (GIrNode *)l->data; @@ -1772,8 +1772,8 @@ g_ir_node_build_typelib (GIrNode *node, blob->class_closure = 0; /* FIXME */ blob->name = write_string (node->name, strings, data, offset2); blob->signature = signature; - - g_ir_node_build_typelib ((GIrNode *)signal->result->type, + + g_ir_node_build_typelib ((GIrNode *)signal->result->type, node, build, &signature, offset2); blob2->may_return_null = signal->result->allow_none; @@ -1783,7 +1783,7 @@ g_ir_node_build_typelib (GIrNode *node, blob2->n_arguments = n; signature += 4; - + for (l = signal->parameters; l; l = l->next) { GIrNode *param = (GIrNode *)l->data; @@ -1829,8 +1829,8 @@ g_ir_node_build_typelib (GIrNode *node, blob->struct_offset = vfunc->offset; blob->reserved2 = 0; blob->signature = signature; - - g_ir_node_build_typelib ((GIrNode *)vfunc->result->type, + + g_ir_node_build_typelib ((GIrNode *)vfunc->result->type, node, build, &signature, offset2); blob2->may_return_null = vfunc->result->allow_none; @@ -1840,7 +1840,7 @@ g_ir_node_build_typelib (GIrNode *node, blob2->n_arguments = n; signature += 4; - + for (l = vfunc->parameters; l; l = l->next) { GIrNode *param = (GIrNode *)l->data; @@ -1873,7 +1873,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->reserved = 0; blob->closure = param->closure; blob->destroy = param->destroy; - + g_ir_node_build_typelib ((GIrNode *)param->type, node, build, offset, offset2); } break; @@ -1883,7 +1883,7 @@ g_ir_node_build_typelib (GIrNode *node, StructBlob *blob = (StructBlob *)&data[*offset]; GIrNodeStruct *struct_ = (GIrNodeStruct *)node; GList *members; - + blob->blob_type = BLOB_TYPE_STRUCT; blob->deprecated = struct_->deprecated; blob->is_gtype_struct = struct_->is_gtype_struct; @@ -1995,7 +1995,7 @@ g_ir_node_build_typelib (GIrNode *node, { *offset += 28; blob->discriminated = TRUE; - g_ir_node_build_typelib ((GIrNode *)union_->discriminator_type, + g_ir_node_build_typelib ((GIrNode *)union_->discriminator_type, build, offset, offset2); } else @@ -2004,7 +2004,7 @@ g_ir_node_build_typelib (GIrNode *node, *offset += sizeof (UnionBlob); blob->discriminated = FALSE; blob->discriminator_type.offset = 0; - + members = g_list_copy (union_->members); g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, @@ -2022,7 +2022,7 @@ g_ir_node_build_typelib (GIrNode *node, for (l = union_->discriminators; l; l = l->next) { GIrNode *member = (GIrNode *)l->data; - + g_ir_node_build_typelib (member, node, build, offset, offset2); } } @@ -2035,13 +2035,13 @@ g_ir_node_build_typelib (GIrNode *node, EnumBlob *blob = (EnumBlob *)&data[*offset]; GIrNodeEnum *enum_ = (GIrNodeEnum *)node; - *offset += sizeof (EnumBlob); + *offset += sizeof (EnumBlob); if (node->type == G_IR_NODE_ENUM) blob->blob_type = BLOB_TYPE_ENUM; else blob->blob_type = BLOB_TYPE_FLAGS; - + blob->deprecated = enum_->deprecated; blob->reserved = 0; blob->storage_type = enum_->storage_type; @@ -2071,7 +2071,7 @@ g_ir_node_build_typelib (GIrNode *node, } } break; - + case G_IR_NODE_OBJECT: { ObjectBlob *blob = (ObjectBlob *)&data[*offset]; @@ -2101,7 +2101,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->n_signals = 0; blob->n_vfuncs = 0; blob->n_constants = 0; - + *offset += sizeof(ObjectBlob); for (l = object->interfaces; l; l = l->next) { @@ -2109,7 +2109,7 @@ g_ir_node_build_typelib (GIrNode *node, *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data); *offset += 2; } - + members = g_list_copy (object->members); *offset = ALIGN_VALUE (*offset, 4); @@ -2164,7 +2164,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->n_signals = 0; blob->n_vfuncs = 0; blob->n_constants = 0; - + *offset += sizeof (InterfaceBlob); for (l = iface->prerequisites; l; l = l->next) { @@ -2172,7 +2172,7 @@ g_ir_node_build_typelib (GIrNode *node, *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data); *offset += 2; } - + members = g_list_copy (iface->members); *offset = ALIGN_VALUE (*offset, 4); @@ -2306,7 +2306,7 @@ g_ir_node_build_typelib (GIrNode *node, DO_ALIGNED_COPY(&data[blob->offset], parse_int_value (constant->value), glong); break; case GI_TYPE_TAG_SIZE: /* FIXME */ - case GI_TYPE_TAG_TIME_T: + case GI_TYPE_TAG_TIME_T: case GI_TYPE_TAG_ULONG: blob->size = sizeof (gulong); DO_ALIGNED_COPY(&data[blob->offset], parse_uint_value (constant->value), gulong); @@ -2326,14 +2326,14 @@ g_ir_node_build_typelib (GIrNode *node, break; } *offset2 += ALIGN_VALUE (blob->size, 4); - + g_ir_node_build_typelib ((GIrNode *)constant->type, node, build, &pos, offset2); } break; default: g_assert_not_reached (); } - + g_debug ("node %s%s%s%p type '%s', offset %d -> %d, offset2 %d -> %d", node->name ? "'" : "", node->name ? node->name : "", @@ -2347,12 +2347,12 @@ g_ir_node_build_typelib (GIrNode *node, } /* if str is already in the pool, return previous location, otherwise write str - * to the typelib at offset, put it in the pool and update offset. If the + * to the typelib at offset, put it in the pool and update offset. If the * typelib is not large enough to hold the string, reallocate it. */ -guint32 +guint32 write_string (const gchar *str, - GHashTable *strings, + GHashTable *strings, guchar *data, guint32 *offset) { @@ -2363,7 +2363,7 @@ write_string (const gchar *str, string_size += strlen (str); value = g_hash_table_lookup (strings, str); - + if (value) return GPOINTER_TO_UINT (value); @@ -2376,7 +2376,7 @@ write_string (const gchar *str, *offset = ALIGN_VALUE (start + strlen (str) + 1, 4); strcpy ((gchar*)&data[start], str); - + return start; } diff --git a/girnode.h b/girnode.h index 427f8e908..148488477 100644 --- a/girnode.h +++ b/girnode.h @@ -28,7 +28,7 @@ G_BEGIN_DECLS typedef struct _GIrTypelibBuild GIrTypelibBuild; -typedef struct _GIrNode GIrNode; +typedef struct _GIrNode GIrNode; typedef struct _GIrNodeFunction GIrNodeFunction; typedef struct _GIrNodeParam GIrNodeParam; typedef struct _GIrNodeType GIrNodeType; @@ -53,10 +53,10 @@ struct _GIrTypelibBuild { GHashTable *types; GList *offset_ordered_nodes; guint32 n_attributes; - guchar *data; + guchar *data; }; -typedef enum +typedef enum { G_IR_NODE_INVALID = 0, G_IR_NODE_FUNCTION = 1, @@ -64,7 +64,7 @@ typedef enum G_IR_NODE_STRUCT = 3, G_IR_NODE_BOXED = 4, G_IR_NODE_ENUM = 5, - G_IR_NODE_FLAGS = 6, + G_IR_NODE_FLAGS = 6, G_IR_NODE_OBJECT = 7, G_IR_NODE_INTERFACE = 8, G_IR_NODE_CONSTANT = 9, @@ -102,7 +102,7 @@ struct _GIrNodeFunction GIrNode node; gboolean deprecated; - gboolean is_varargs; /* Not in typelib yet */ + gboolean is_varargs; /* Not in typelib yet */ gboolean is_method; gboolean is_setter; @@ -117,7 +117,7 @@ struct _GIrNodeFunction GList *parameters; }; -struct _GIrNodeType +struct _GIrNodeType { GIrNode node; @@ -138,15 +138,15 @@ struct _GIrNodeType gint length; gboolean has_size; gint size; - + GIrNodeType *parameter_type1; - GIrNodeType *parameter_type2; + GIrNodeType *parameter_type2; gchar *interface; gchar **errors; }; -struct _GIrNodeParam +struct _GIrNodeParam { GIrNode node; @@ -159,10 +159,10 @@ struct _GIrNodeParam gboolean transfer; gboolean shallow_transfer; GIScopeType scope; - + gint8 closure; gint8 destroy; - + GIrNodeType *type; }; @@ -177,11 +177,11 @@ struct _GIrNodeProperty gboolean writable; gboolean construct; gboolean construct_only; - + GIrNodeType *type; }; -struct _GIrNodeSignal +struct _GIrNodeSignal { GIrNode node; @@ -194,30 +194,30 @@ struct _GIrNodeSignal gboolean detailed; gboolean action; gboolean no_hooks; - + gboolean has_class_closure; gboolean true_stops_emit; - + gint class_closure; - + GList *parameters; - GIrNodeParam *result; + GIrNodeParam *result; }; -struct _GIrNodeVFunc +struct _GIrNodeVFunc { GIrNode node; - gboolean is_varargs; /* Not in typelib yet */ + gboolean is_varargs; /* Not in typelib yet */ gboolean must_chain_up; gboolean must_be_implemented; gboolean must_not_be_implemented; gboolean is_class_closure; - + char *invoker; GList *parameters; - GIrNodeParam *result; + GIrNodeParam *result; gint offset; }; @@ -231,7 +231,7 @@ struct _GIrNodeField gint bits; gint offset; GIrNodeFunction *callback; - + GIrNodeType *type; }; @@ -247,13 +247,13 @@ struct _GIrNodeInterface gchar *parent; gchar *glib_type_struct; - + GList *interfaces; GList *prerequisites; gint alignment; gint size; - + GList *members; }; @@ -273,7 +273,7 @@ struct _GIrNodeConstant gboolean deprecated; GIrNodeType *type; - + gchar *value; }; @@ -291,7 +291,7 @@ struct _GIrNodeEnum }; struct _GIrNodeBoxed -{ +{ GIrNode node; gboolean deprecated; @@ -301,7 +301,7 @@ struct _GIrNodeBoxed gint alignment; gint size; - + GList *members; }; @@ -318,7 +318,7 @@ struct _GIrNodeStruct gint alignment; gint size; - + GList *members; }; @@ -327,7 +327,7 @@ struct _GIrNodeUnion GIrNode node; gboolean deprecated; - + GList *members; GList *discriminators; @@ -347,7 +347,7 @@ struct _GIrNodeErrorDomain GIrNode node; gboolean deprecated; - + gchar *name; gchar *getquark; gchar *codes; @@ -370,7 +370,7 @@ gboolean g_ir_node_can_have_member (GIrNode *node); void g_ir_node_add_member (GIrNode *node, GIrNodeFunction *member); guint32 write_string (const gchar *str, - GHashTable *strings, + GHashTable *strings, guchar *data, guint32 *offset); diff --git a/giroffsets.c b/giroffsets.c index dcfd75e57..ab9bde0b4 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -235,7 +235,7 @@ get_type_size_alignment (GIrNodeType *type, if (type->tag == GI_TYPE_TAG_ARRAY) { gint elt_size, elt_alignment; - + if (!type->has_size || !get_type_size_alignment(type->parameter_type1, module, modules, &elt_size, &elt_alignment, who)) @@ -244,10 +244,10 @@ get_type_size_alignment (GIrNodeType *type, *alignment = -1; return FALSE; } - + *size = type->size * elt_size; *alignment = elt_alignment; - + return TRUE; } else if (type->is_pointer) @@ -300,7 +300,7 @@ get_field_size_alignment (GIrNodeField *field, { gchar *who; gboolean success; - + who = g_strdup_printf ("field %s.%s.%s", module->name, parent_node->name, ((GIrNode *)field)->name); if (field->callback) diff --git a/girparser.c b/girparser.c index 77416177d..12c1d9890 100644 --- a/girparser.c +++ b/girparser.c @@ -124,7 +124,7 @@ static void cleanup (GMarkupParseContext *context, GError *error, gpointer user_data); -static GMarkupParser markup_parser = +static GMarkupParser markup_parser = { start_element_handler, end_element_handler, @@ -141,7 +141,7 @@ start_alias (GMarkupParseContext *context, ParseContext *ctx, GError **error); -static const gchar *find_attribute (const gchar *name, +static const gchar *find_attribute (const gchar *name, const gchar **attribute_names, const gchar **attribute_values); @@ -188,7 +188,7 @@ firstpass_start_element_handler (GMarkupParseContext *context, { ParseContext *ctx = user_data; - if (strcmp (element_name, "alias") == 0) + if (strcmp (element_name, "alias") == 0) { start_alias (context, element_name, attribute_names, attribute_values, ctx, error); @@ -219,7 +219,7 @@ firstpass_end_element_handler (GMarkupParseContext *context, { } -static GMarkupParser firstpass_parser = +static GMarkupParser firstpass_parser = { firstpass_start_element_handler, firstpass_end_element_handler, @@ -235,12 +235,12 @@ locate_gir (GIrParser *parser, const gchar *const *datadirs; const gchar *const *dir; char *path = NULL; - + datadirs = g_get_system_data_dirs (); - + if (parser->includes != NULL) { - for (dir = (const gchar *const *)parser->includes; *dir; dir++) + for (dir = (const gchar *const *)parser->includes; *dir; dir++) { path = g_build_filename (*dir, girname, NULL); if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) @@ -249,7 +249,7 @@ locate_gir (GIrParser *parser, path = NULL; } } - for (dir = datadirs; *dir; dir++) + for (dir = datadirs; *dir; dir++) { path = g_build_filename (*dir, GIR_SUFFIX, girname, NULL); if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) @@ -300,16 +300,16 @@ backtrace_stderr (void) static const gchar * -find_attribute (const gchar *name, +find_attribute (const gchar *name, const gchar **attribute_names, const gchar **attribute_values) { gint i; - + for (i = 0; attribute_names[i] != NULL; i++) if (strcmp (attribute_names[i], name) == 0) return attribute_values[i]; - + return 0; } @@ -325,10 +325,10 @@ static GIrNode * pop_node (ParseContext *ctx) { g_assert (ctx->node_stack != 0); - + GSList *top = ctx->node_stack; GIrNode *node = top->data; - + g_debug ("popping node %d %s", node->type, node->name); ctx->node_stack = top->next; g_slist_free_1 (top); @@ -379,21 +379,21 @@ static BasicTypeInfo basic_types[] = { { "double", GI_TYPE_TAG_DOUBLE, 0 }, { "time_t", GI_TYPE_TAG_TIME_T, 0 }, { "GType", GI_TYPE_TAG_GTYPE, 0 }, - { "utf8", GI_TYPE_TAG_UTF8, 1 }, + { "utf8", GI_TYPE_TAG_UTF8, 1 }, { "filename", GI_TYPE_TAG_FILENAME,1 }, -}; +}; static const BasicTypeInfo * parse_basic (const char *str) { gint i; gint n_basic = G_N_ELEMENTS (basic_types); - + for (i = 0; i < n_basic; i++) { if (g_str_has_prefix (str, basic_types[i].str)) return &(basic_types[i]); - } + } return NULL; } @@ -401,21 +401,21 @@ static GIrNodeType * parse_type_internal (const gchar *str, char **next, gboolean in_glib, gboolean in_gobject) { - const BasicTypeInfo *basic; + const BasicTypeInfo *basic; GIrNodeType *type; char *temporary_type = NULL; - + type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE); - + type->unparsed = g_strdup (str); /* See comment below on GLib.List handling */ - if (in_gobject && strcmp (str, "Type") == 0) + if (in_gobject && strcmp (str, "Type") == 0) { temporary_type = g_strdup ("GLib.Type"); str = temporary_type; } - + basic = parse_basic (str); if (basic != NULL) { @@ -429,7 +429,7 @@ parse_type_internal (const gchar *str, char **next, gboolean in_glib, { /* If we're inside GLib, handle "List" etc. by prefixing with * "GLib." so the parsing code below doesn't have to get more - * special. + * special. */ if (g_str_has_prefix (str, "List<") || strcmp (str, "List") == 0) @@ -495,12 +495,12 @@ parse_type_internal (const gchar *str, char **next, gboolean in_glib, type->is_error = TRUE; type->is_pointer = TRUE; str += strlen ("Error"); - + if (*str == '<') { (str)++; char *tmp, *end; - + end = strchr (str, '>'); tmp = g_strndup (str, end - str); type->errors = g_strsplit (tmp, ",", 0); @@ -509,23 +509,23 @@ parse_type_internal (const gchar *str, char **next, gboolean in_glib, str = end; } } - else + else { type->tag = GI_TYPE_TAG_INTERFACE; - type->is_interface = TRUE; + type->is_interface = TRUE; const char *start = str; /* must be an interface type */ - while (g_ascii_isalnum (*str) || - *str == '.' || - *str == '-' || + while (g_ascii_isalnum (*str) || + *str == '.' || + *str == '-' || *str == '_' || *str == ':') (str)++; type->interface = g_strndup (start, str - start); } - + if (next) *next = (char*)str; g_assert (type->tag >= 0 && type->tag <= GI_TYPE_TAG_ERROR); @@ -534,7 +534,7 @@ parse_type_internal (const gchar *str, char **next, gboolean in_glib, /* error: */ g_ir_node_free ((GIrNode *)type); - g_free (temporary_type); + g_free (temporary_type); return NULL; } @@ -574,7 +574,7 @@ resolve_aliases (ParseContext *ctx, const gchar *type) lookup = type; g_free (prefixed); - + return lookup; } @@ -598,9 +598,9 @@ is_disguised_structure (ParseContext *ctx, const gchar *type) result = g_hash_table_lookup (ctx->current_module->disguised_structures, lookup) != NULL; - + g_free (prefixed); - + return result; } @@ -650,7 +650,7 @@ start_glib_boxed (GMarkupParseContext *context, typename = find_attribute ("glib:type-name", attribute_names, attribute_values); typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - + if (name == NULL) { MISSING_ATTRIBUTE (context, error, element_name, "glib:name"); @@ -668,7 +668,7 @@ start_glib_boxed (GMarkupParseContext *context, } boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED); - + ((GIrNode *)boxed)->name = g_strdup (name); boxed->gtype_name = g_strdup (typename); boxed->gtype_init = g_strdup (typeinit); @@ -676,11 +676,11 @@ start_glib_boxed (GMarkupParseContext *context, boxed->deprecated = TRUE; else boxed->deprecated = FALSE; - + push_node (ctx, (GIrNode *)boxed); - ctx->current_module->entries = + ctx->current_module->entries = g_list_append (ctx->current_module->entries, boxed); - + state_switch (ctx, STATE_BOXED); return TRUE; @@ -700,7 +700,7 @@ start_function (GMarkupParseContext *context, const gchar *throws; GIrNodeFunction *function; gboolean found = FALSE; - + switch (ctx->state) { case STATE_NAMESPACE: @@ -735,7 +735,7 @@ start_function (GMarkupParseContext *context, symbol = find_attribute ("c:identifier", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); throws = find_attribute ("throws", attribute_names, attribute_values); - + if (name == NULL) { MISSING_ATTRIBUTE (context, error, element_name, "name"); @@ -748,7 +748,7 @@ start_function (GMarkupParseContext *context, } function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION); - + ((GIrNode *)function)->name = g_strdup (name); function->symbol = g_strdup (symbol); function->parameters = NULL; @@ -756,12 +756,12 @@ start_function (GMarkupParseContext *context, function->deprecated = TRUE; else function->deprecated = FALSE; - + if (strcmp (element_name, "method") == 0 || strcmp (element_name, "constructor") == 0) { function->is_method = TRUE; - + if (strcmp (element_name, "constructor") == 0) function->is_constructor = TRUE; else @@ -784,8 +784,8 @@ start_function (GMarkupParseContext *context, if (ctx->node_stack == NULL) { - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, function); + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, function); } else if (ctx->current_typed) { @@ -801,7 +801,7 @@ start_function (GMarkupParseContext *context, case G_IR_NODE_OBJECT: { GIrNodeInterface *iface; - + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); iface->members = g_list_append (iface->members, function); } @@ -809,7 +809,7 @@ start_function (GMarkupParseContext *context, case G_IR_NODE_BOXED: { GIrNodeBoxed *boxed; - + boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx); boxed->members = g_list_append (boxed->members, function); } @@ -817,14 +817,14 @@ start_function (GMarkupParseContext *context, case G_IR_NODE_STRUCT: { GIrNodeStruct *struct_; - + struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx); struct_->members = g_list_append (struct_->members, function); } break; case G_IR_NODE_UNION: { GIrNodeUnion *union_; - + union_ = (GIrNodeUnion *)CURRENT_NODE (ctx); union_->members = g_list_append (union_->members, function); } @@ -832,10 +832,10 @@ start_function (GMarkupParseContext *context, default: g_assert_not_reached (); } - + push_node(ctx, (GIrNode *)function); state_switch (ctx, STATE_FUNCTION); - + return TRUE; } @@ -889,7 +889,7 @@ start_parameter (GMarkupParseContext *context, const gchar *closure; const gchar *destroy; GIrNodeParam *param; - + if (!(strcmp (element_name, "parameter") == 0 && ctx->state == STATE_FUNCTION_PARAMETERS)) return FALSE; @@ -904,7 +904,7 @@ start_parameter (GMarkupParseContext *context, scope = find_attribute ("scope", attribute_names, attribute_values); closure = find_attribute ("closure", attribute_names, attribute_values); destroy = find_attribute ("destroy", attribute_names, attribute_values); - + if (name == NULL) name = "unknown"; @@ -961,12 +961,12 @@ start_parameter (GMarkupParseContext *context, param->scope = GI_SCOPE_TYPE_NOTIFIED; else param->scope = GI_SCOPE_TYPE_INVALID; - + param->closure = closure ? atoi (closure) : -1; param->destroy = destroy ? atoi (destroy) : -1; - + ((GIrNode *)param)->name = g_strdup (name); - + switch (CURRENT_NODE (ctx)->type) { case G_IR_NODE_FUNCTION: @@ -989,7 +989,7 @@ start_parameter (GMarkupParseContext *context, case G_IR_NODE_VFUNC: { GIrNodeVFunc *vfunc; - + vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx); vfunc->parameters = g_list_append (vfunc->parameters, param); } @@ -1027,16 +1027,16 @@ start_field (GMarkupParseContext *context, default: return FALSE; } - + if (strcmp (element_name, "field") != 0) return FALSE; - + name = find_attribute ("name", attribute_names, attribute_values); readable = find_attribute ("readable", attribute_names, attribute_values); writable = find_attribute ("writable", attribute_names, attribute_values); bits = find_attribute ("bits", attribute_names, attribute_values); branch = find_attribute ("branch", attribute_names, attribute_values); - + if (name == NULL) { MISSING_ATTRIBUTE (context, error, element_name, "name"); @@ -1051,18 +1051,18 @@ start_field (GMarkupParseContext *context, */ field->readable = readable == NULL || strcmp (readable, "0") == 0; field->writable = writable != NULL && strcmp (writable, "1") == 0; - + if (bits) field->bits = atoi (bits); else field->bits = 0; - + switch (CURRENT_NODE (ctx)->type) { case G_IR_NODE_OBJECT: { GIrNodeInterface *iface; - + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); iface->members = g_list_append (iface->members, field); state_switch (ctx, STATE_CLASS_FIELD); @@ -1071,7 +1071,7 @@ start_field (GMarkupParseContext *context, case G_IR_NODE_INTERFACE: { GIrNodeInterface *iface; - + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); iface->members = g_list_append (iface->members, field); state_switch (ctx, STATE_INTERFACE_FIELD); @@ -1080,7 +1080,7 @@ start_field (GMarkupParseContext *context, case G_IR_NODE_BOXED: { GIrNodeBoxed *boxed; - + boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx); boxed->members = g_list_append (boxed->members, field); state_switch (ctx, STATE_BOXED_FIELD); @@ -1089,7 +1089,7 @@ start_field (GMarkupParseContext *context, case G_IR_NODE_STRUCT: { GIrNodeStruct *struct_; - + struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx); struct_->members = g_list_append (struct_->members, field); state_switch (ctx, STATE_STRUCT_FIELD); @@ -1098,19 +1098,19 @@ start_field (GMarkupParseContext *context, case G_IR_NODE_UNION: { GIrNodeUnion *union_; - + union_ = (GIrNodeUnion *)CURRENT_NODE (ctx); union_->members = g_list_append (union_->members, field); if (branch) { GIrNodeConstant *constant; - + constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT); ((GIrNode *)constant)->name = g_strdup (name); - constant->value = g_strdup (branch); + constant->value = g_strdup (branch); constant->type = union_->discriminator_type; constant->deprecated = FALSE; - + union_->discriminators = g_list_append (union_->discriminators, constant); } state_switch (ctx, STATE_UNION_FIELD); @@ -1119,7 +1119,7 @@ start_field (GMarkupParseContext *context, default: g_assert_not_reached (); } - + return TRUE; } @@ -1182,18 +1182,18 @@ start_enum (GMarkupParseContext *context, const gchar *typename; const gchar *typeinit; const gchar *deprecated; - + name = find_attribute ("name", attribute_names, attribute_values); typename = find_attribute ("glib:type-name", attribute_names, attribute_values); typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - + if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { + else + { GIrNodeEnum *enum_; - + if (strcmp (element_name, "enumeration") == 0) enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM); else @@ -1207,12 +1207,12 @@ start_enum (GMarkupParseContext *context, enum_->deprecated = FALSE; push_node (ctx, (GIrNode *) enum_); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, enum_); - + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, enum_); + state_switch (ctx, STATE_ENUM); } - + return TRUE; } return FALSE; @@ -1235,25 +1235,25 @@ start_property (GMarkupParseContext *context, const gchar *writable; const gchar *construct; const gchar *construct_only; - + name = find_attribute ("name", attribute_names, attribute_values); readable = find_attribute ("readable", attribute_names, attribute_values); writable = find_attribute ("writable", attribute_names, attribute_values); construct = find_attribute ("construct", attribute_names, attribute_values); construct_only = find_attribute ("construct-only", attribute_names, attribute_values); - + if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { + else + { GIrNodeProperty *property; GIrNodeInterface *iface; - + property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY); ctx->current_typed = (GIrNode*) property; ((GIrNode *)property)->name = g_strdup (name); - + /* Assume properties are readable */ if (readable == NULL || strcmp (readable, "1") == 0) property->readable = TRUE; @@ -1282,7 +1282,7 @@ start_property (GMarkupParseContext *context, else g_assert_not_reached (); } - + return TRUE; } return FALSE; @@ -1292,7 +1292,7 @@ static gint parse_value (const gchar *str) { gchar *shift_op; - + /* FIXME just a quick hack */ shift_op = strstr (str, "<<"); @@ -1302,7 +1302,7 @@ parse_value (const gchar *str) base = strtol (str, NULL, 10); shift = strtol (shift_op + 3, NULL, 10); - + return base << shift; } else @@ -1325,24 +1325,24 @@ start_member (GMarkupParseContext *context, const gchar *name; const gchar *value; const gchar *deprecated; - + name = find_attribute ("name", attribute_names, attribute_values); value = find_attribute ("value", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - + if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { + else + { GIrNodeEnum *enum_; GIrNodeValue *value_; value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE); ((GIrNode *)value_)->name = g_strdup (name); - + value_->value = parse_value (value); - + if (deprecated) value_->deprecated = TRUE; else @@ -1351,7 +1351,7 @@ start_member (GMarkupParseContext *context, enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx); enum_->values = g_list_append (enum_->values, value_); } - + return TRUE; } return FALSE; @@ -1373,17 +1373,17 @@ start_constant (GMarkupParseContext *context, const gchar *name; const gchar *value; const gchar *deprecated; - + name = find_attribute ("name", attribute_names, attribute_values); value = find_attribute ("value", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - + if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); else if (value == NULL) MISSING_ATTRIBUTE (context, error, element_name, "value"); - else - { + else + { GIrNodeConstant *constant; constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT); @@ -1401,7 +1401,7 @@ start_constant (GMarkupParseContext *context, if (ctx->state == STATE_NAMESPACE) { push_node (ctx, (GIrNode *) constant); - ctx->current_module->entries = + ctx->current_module->entries = g_list_append (ctx->current_module->entries, constant); } else @@ -1428,7 +1428,7 @@ start_constant (GMarkupParseContext *context, break; } } - + return TRUE; } return FALSE; @@ -1449,20 +1449,20 @@ start_errordomain (GMarkupParseContext *context, const gchar *getquark; const gchar *codes; const gchar *deprecated; - + name = find_attribute ("name", attribute_names, attribute_values); getquark = find_attribute ("get-quark", attribute_names, attribute_values); codes = find_attribute ("codes", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - + if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); else if (getquark == NULL) MISSING_ATTRIBUTE (context, error, element_name, "getquark"); else if (codes == NULL) MISSING_ATTRIBUTE (context, error, element_name, "codes"); - else - { + else + { GIrNodeErrorDomain *domain; domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN); @@ -1477,12 +1477,12 @@ start_errordomain (GMarkupParseContext *context, domain->deprecated = FALSE; push_node (ctx, (GIrNode *) domain); - ctx->current_module->entries = + ctx->current_module->entries = g_list_append (ctx->current_module->entries, domain); state_switch (ctx, STATE_ERRORDOMAIN); } - + return TRUE; } return FALSE; @@ -1504,13 +1504,13 @@ start_interface (GMarkupParseContext *context, const gchar *typeinit; const gchar *deprecated; const gchar *glib_type_struct; - + name = find_attribute ("name", attribute_names, attribute_values); typename = find_attribute ("glib:type-name", attribute_names, attribute_values); typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - + if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); else if (typename == NULL) @@ -1530,15 +1530,15 @@ start_interface (GMarkupParseContext *context, iface->deprecated = TRUE; else iface->deprecated = FALSE; - + push_node (ctx, (GIrNode *) iface); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, iface); - + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, iface); + state_switch (ctx, STATE_INTERFACE); - + } - + return TRUE; } return FALSE; @@ -1562,7 +1562,7 @@ start_class (GMarkupParseContext *context, const gchar *typeinit; const gchar *deprecated; const gchar *abstract; - + name = find_attribute ("name", attribute_names, attribute_values); parent = find_attribute ("parent", attribute_names, attribute_values); glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values); @@ -1570,7 +1570,7 @@ start_class (GMarkupParseContext *context, typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); abstract = find_attribute ("abstract", attribute_names, attribute_values); - + if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); else if (typename == NULL) @@ -1595,12 +1595,12 @@ start_class (GMarkupParseContext *context, iface->abstract = abstract && strcmp (abstract, "1") == 0; push_node (ctx, (GIrNode *) iface); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, iface); - + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, iface); + state_switch (ctx, STATE_CLASS); } - + return TRUE; } return FALSE; @@ -1626,14 +1626,14 @@ start_type (GMarkupParseContext *context, if (!(is_array || is_varargs || (strcmp (element_name, "type") == 0))) return FALSE; - if (ctx->state == STATE_TYPE) + if (ctx->state == STATE_TYPE) { ctx->type_depth++; ctx->type_stack = g_list_prepend (ctx->type_stack, ctx->type_parameters); ctx->type_parameters = NULL; - } + } else if (ctx->state == STATE_FUNCTION_PARAMETER || - ctx->state == STATE_FUNCTION_RETURN || + ctx->state == STATE_FUNCTION_RETURN || ctx->state == STATE_STRUCT_FIELD || ctx->state == STATE_UNION_FIELD || ctx->state == STATE_CLASS_PROPERTY || @@ -1705,7 +1705,7 @@ start_type (GMarkupParseContext *context, if (is_varargs) return TRUE; - if (is_array) + if (is_array) { const char *zero; const char *len; @@ -1716,15 +1716,15 @@ start_type (GMarkupParseContext *context, typenode->tag = GI_TYPE_TAG_ARRAY; typenode->is_pointer = TRUE; typenode->is_array = TRUE; - + zero = find_attribute ("zero-terminated", attribute_names, attribute_values); len = find_attribute ("length", attribute_names, attribute_values); size = find_attribute ("fixed-size", attribute_names, attribute_values); - + typenode->zero_terminated = !(zero && strcmp (zero, "1") != 0); typenode->has_length = len != NULL; typenode->length = typenode->has_length ? atoi (len) : -1; - + typenode->has_size = size != NULL; typenode->size = typenode->has_size ? atoi (size) : -1; @@ -1741,7 +1741,7 @@ start_type (GMarkupParseContext *context, if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); - + pointer_depth = 0; ctype = find_attribute ("c:type", attribute_names, attribute_values); if (ctype != NULL) @@ -1750,12 +1750,12 @@ start_type (GMarkupParseContext *context, while (cp > ctype && *cp-- == '*') pointer_depth++; } - + if (ctx->current_typed->type == G_IR_NODE_PARAM && ((GIrNodeParam *)ctx->current_typed)->out && pointer_depth > 0) pointer_depth--; - + typenode = parse_type (ctx, name); /* A 'disguised' structure is one where the c:type is a typedef that @@ -1770,7 +1770,7 @@ start_type (GMarkupParseContext *context, } ctx->type_parameters = g_list_append (ctx->type_parameters, typenode); - + return TRUE; } @@ -1833,7 +1833,7 @@ end_type_top (ParseContext *ctx) } g_list_free (ctx->type_parameters); - out: + out: ctx->type_depth = 0; ctx->type_parameters = NULL; ctx->current_typed = NULL; @@ -1979,7 +1979,7 @@ start_return_value (GMarkupParseContext *context, default: g_assert_not_reached (); } - + return TRUE; } @@ -2002,14 +2002,14 @@ start_implements (GMarkupParseContext *context, return FALSE; state_switch (ctx, STATE_IMPLEMENTS); - + name = find_attribute ("name", attribute_names, attribute_values); if (name == NULL) { MISSING_ATTRIBUTE (context, error, element_name, "name"); return FALSE; } - + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); iface->interfaces = g_list_append (iface->interfaces, g_strdup (name)); @@ -2024,7 +2024,7 @@ start_glib_signal (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "glib:signal") == 0 && + if (strcmp (element_name, "glib:signal") == 0 && (ctx->state == STATE_CLASS || ctx->state == STATE_INTERFACE)) { @@ -2035,7 +2035,7 @@ start_glib_signal (GMarkupParseContext *context, const gchar *action; const gchar *no_hooks; const gchar *has_class_closure; - + name = find_attribute ("name", attribute_names, attribute_values); when = find_attribute ("when", attribute_names, attribute_values); no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values); @@ -2043,7 +2043,7 @@ start_glib_signal (GMarkupParseContext *context, action = find_attribute ("action", attribute_names, attribute_values); no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values); has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values); - + if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); else @@ -2052,9 +2052,9 @@ start_glib_signal (GMarkupParseContext *context, GIrNodeSignal *signal; signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL); - + ((GIrNode *)signal)->name = g_strdup (name); - + signal->run_first = FALSE; signal->run_last = FALSE; signal->run_cleanup = FALSE; @@ -2062,9 +2062,9 @@ start_glib_signal (GMarkupParseContext *context, signal->run_last = TRUE; else if (strcmp (when, "FIRST") == 0) signal->run_first = TRUE; - else + else signal->run_cleanup = TRUE; - + if (no_recurse && strcmp (no_recurse, "1") == 0) signal->no_recurse = TRUE; else @@ -2092,7 +2092,7 @@ start_glib_signal (GMarkupParseContext *context, push_node (ctx, (GIrNode *)signal); state_switch (ctx, STATE_FUNCTION); } - + return TRUE; } return FALSE; @@ -2116,14 +2116,14 @@ start_vfunc (GMarkupParseContext *context, const gchar *is_class_closure; const gchar *offset; const gchar *invoker; - + name = find_attribute ("name", attribute_names, attribute_values); - must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values); + must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values); override = find_attribute ("override", attribute_names, attribute_values); is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values); offset = find_attribute ("offset", attribute_names, attribute_values); invoker = find_attribute ("invoker", attribute_names, attribute_values); - + if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); else @@ -2132,7 +2132,7 @@ start_vfunc (GMarkupParseContext *context, GIrNodeVFunc *vfunc; vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC); - + ((GIrNode *)vfunc)->name = g_strdup (name); if (must_chain_up && strcmp (must_chain_up, "1") == 0) @@ -2155,12 +2155,12 @@ start_vfunc (GMarkupParseContext *context, vfunc->must_be_implemented = FALSE; vfunc->must_not_be_implemented = FALSE; } - + if (is_class_closure && strcmp (is_class_closure, "1") == 0) vfunc->is_class_closure = TRUE; else vfunc->is_class_closure = FALSE; - + if (offset) vfunc->offset = atoi (offset); else @@ -2174,7 +2174,7 @@ start_vfunc (GMarkupParseContext *context, push_node (ctx, (GIrNode *)vfunc); state_switch (ctx, STATE_FUNCTION); } - + return TRUE; } return FALSE; @@ -2189,7 +2189,7 @@ start_struct (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "record") == 0 && + if (strcmp (element_name, "record") == 0 && (ctx->state == STATE_NAMESPACE || ctx->state == STATE_UNION || ctx->state == STATE_STRUCT || @@ -2202,7 +2202,7 @@ start_struct (GMarkupParseContext *context, const gchar *gtype_init; const gchar *gtype_struct; GIrNodeStruct *struct_; - + name = find_attribute ("name", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); disguised = find_attribute ("disguised", attribute_names, attribute_values); @@ -2227,7 +2227,7 @@ start_struct (GMarkupParseContext *context, } struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT); - + ((GIrNode *)struct_)->name = g_strdup (name ? name : ""); if (deprecated) struct_->deprecated = TRUE; @@ -2236,23 +2236,23 @@ start_struct (GMarkupParseContext *context, if (disguised && strcmp (disguised, "1") == 0) struct_->disguised = TRUE; - + struct_->is_gtype_struct = gtype_struct != NULL; struct_->gtype_name = g_strdup (gtype_name); struct_->gtype_init = g_strdup (gtype_init); if (ctx->node_stack == NULL) - ctx->current_module->entries = + ctx->current_module->entries = g_list_append (ctx->current_module->entries, struct_); push_node (ctx, (GIrNode *)struct_); - + state_switch (ctx, STATE_STRUCT); return TRUE; } return FALSE; } - + static gboolean start_union (GMarkupParseContext *context, @@ -2272,12 +2272,12 @@ start_union (GMarkupParseContext *context, const gchar *deprecated; const gchar *typename; const gchar *typeinit; - + name = find_attribute ("name", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); typename = find_attribute ("glib:type-name", attribute_names, attribute_values); typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); - + if (name == NULL && ctx->node_stack == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); else @@ -2285,7 +2285,7 @@ start_union (GMarkupParseContext *context, GIrNodeUnion *union_; union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION); - + ((GIrNode *)union_)->name = g_strdup (name ? name : ""); union_->gtype_name = g_strdup (typename); union_->gtype_init = g_strdup (typeinit); @@ -2295,10 +2295,10 @@ start_union (GMarkupParseContext *context, union_->deprecated = FALSE; if (ctx->node_stack == NULL) - ctx->current_module->entries = + ctx->current_module->entries = g_list_append (ctx->current_module->entries, union_); push_node (ctx, (GIrNode *)union_); - + state_switch (ctx, STATE_UNION); } return TRUE; @@ -2319,7 +2319,7 @@ start_discriminator (GMarkupParseContext *context, { const gchar *type; const gchar *offset; - + type = find_attribute ("type", attribute_names, attribute_values); offset = find_attribute ("offset", attribute_names, attribute_values); if (type == NULL) @@ -2327,12 +2327,12 @@ start_discriminator (GMarkupParseContext *context, else if (offset == NULL) MISSING_ATTRIBUTE (context, error, element_name, "offset"); { - ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type + ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type = parse_type (ctx, type); - ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset + ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset = atoi (offset); } - + return TRUE; } @@ -2411,7 +2411,7 @@ parse_include (GMarkupParseContext *context, return success; } - + extern GLogLevelFlags logged_levels; static void @@ -2443,10 +2443,10 @@ start_element_handler (GMarkupParseContext *context, g_string_free (tags, TRUE); } - switch (element_name[0]) + switch (element_name[0]) { case 'a': - if (ctx->state == STATE_NAMESPACE && strcmp (element_name, "alias") == 0) + if (ctx->state == STATE_NAMESPACE && strcmp (element_name, "alias") == 0) { state_switch (ctx, STATE_ALIAS); goto out; @@ -2461,13 +2461,13 @@ start_element_handler (GMarkupParseContext *context, goto out; break; case 'b': - if (start_enum (context, element_name, + if (start_enum (context, element_name, attribute_names, attribute_values, ctx, error)) goto out; break; case 'c': - if (start_function (context, element_name, + if (start_function (context, element_name, attribute_names, attribute_values, ctx, error)) goto out; @@ -2475,36 +2475,36 @@ start_element_handler (GMarkupParseContext *context, attribute_names, attribute_values, ctx, error)) goto out; - else if (start_class (context, element_name, + else if (start_class (context, element_name, attribute_names, attribute_values, ctx, error)) goto out; break; case 'd': - if (start_discriminator (context, element_name, + if (start_discriminator (context, element_name, attribute_names, attribute_values, ctx, error)) goto out; break; case 'e': - if (start_enum (context, element_name, + if (start_enum (context, element_name, attribute_names, attribute_values, ctx, error)) goto out; - else if (start_errordomain (context, element_name, + else if (start_errordomain (context, element_name, attribute_names, attribute_values, ctx, error)) goto out; break; case 'f': - if (start_function (context, element_name, + if (start_function (context, element_name, attribute_names, attribute_values, ctx, error)) goto out; - else if (start_field (context, element_name, + else if (start_field (context, element_name, attribute_names, attribute_values, ctx, error)) goto out; @@ -2552,7 +2552,7 @@ start_element_handler (GMarkupParseContext *context, state_switch (ctx, STATE_INCLUDE); goto out; } - if (start_interface (context, element_name, + if (start_interface (context, element_name, attribute_names, attribute_values, ctx, error)) goto out; @@ -2563,11 +2563,11 @@ start_element_handler (GMarkupParseContext *context, break; case 'm': - if (start_function (context, element_name, + if (start_function (context, element_name, attribute_names, attribute_values, ctx, error)) goto out; - else if (start_member (context, element_name, + else if (start_member (context, element_name, attribute_names, attribute_values, ctx, error)) goto out; @@ -2657,7 +2657,7 @@ start_element_handler (GMarkupParseContext *context, if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); else - { + { GIrNodeInterface *iface; iface = (GIrNodeInterface *)CURRENT_NODE(ctx); @@ -2679,7 +2679,7 @@ start_element_handler (GMarkupParseContext *context, const gchar *version; version = find_attribute ("version", attribute_names, attribute_values); - + if (version == NULL) MISSING_ATTRIBUTE (context, error, element_name, "version"); else if (strcmp (version, "1.0") != 0) @@ -2690,17 +2690,17 @@ start_element_handler (GMarkupParseContext *context, version); else state_switch (ctx, STATE_REPOSITORY); - + goto out; } else if (start_return_value (context, element_name, attribute_names, attribute_values, ctx, error)) - goto out; + goto out; else if (start_struct (context, element_name, attribute_names, attribute_values, ctx, error)) - goto out; + goto out; break; case 'u': @@ -2738,9 +2738,9 @@ start_element_handler (GMarkupParseContext *context, { ctx->unknown_depth += 1; } - + out: - if (*error) + if (*error) { g_markup_parse_context_get_position (context, &line_number, &char_number); @@ -2753,7 +2753,7 @@ static gboolean require_one_of_end_elements (GMarkupParseContext *context, ParseContext *ctx, const char *actual_name, - GError **error, + GError **error, ...) { va_list args; @@ -2763,7 +2763,7 @@ require_one_of_end_elements (GMarkupParseContext *context, va_start (args, error); - while ((expected = va_arg (args, const char*)) != NULL) + while ((expected = va_arg (args, const char*)) != NULL) { if (strcmp (expected, actual_name) == 0) { @@ -2782,7 +2782,7 @@ require_one_of_end_elements (GMarkupParseContext *context, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "Unexpected end tag '%s' on line %d char %d; current state=%d", - actual_name, + actual_name, line_number, char_number, ctx->state); backtrace_stderr(); return FALSE; @@ -2799,7 +2799,7 @@ state_switch_end_struct_or_union (GMarkupParseContext *context, { state_switch (ctx, STATE_NAMESPACE); } - else + else { if (CURRENT_NODE (ctx)->type == G_IR_NODE_STRUCT) state_switch (ctx, STATE_STRUCT); @@ -2860,13 +2860,13 @@ end_element_handler (GMarkupParseContext *context, state_switch (ctx, STATE_REPOSITORY); } break; - + case STATE_PACKAGE: if (require_end_element (context, ctx, "package", element_name, error)) { state_switch (ctx, STATE_REPOSITORY); } - break; + break; case STATE_NAMESPACE: if (require_end_element (context, ctx, "namespace", element_name, error)) @@ -2915,7 +2915,7 @@ end_element_handler (GMarkupParseContext *context, { state_switch (ctx, STATE_NAMESPACE); } - else + else { g_debug("case STATE_FUNCTION %d", CURRENT_NODE (ctx)->type); if (ctx->in_embedded_type) @@ -2925,7 +2925,7 @@ end_element_handler (GMarkupParseContext *context, } else if (CURRENT_NODE (ctx)->type == G_IR_NODE_INTERFACE) state_switch (ctx, STATE_INTERFACE); - else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT) + else if (CURRENT_NODE (ctx)->type == G_IR_NODE_OBJECT) state_switch (ctx, STATE_CLASS); else if (CURRENT_NODE (ctx)->type == G_IR_NODE_BOXED) state_switch (ctx, STATE_BOXED); @@ -3011,8 +3011,8 @@ end_element_handler (GMarkupParseContext *context, case STATE_ENUM: if (strcmp ("member", element_name) == 0) break; - else if (require_one_of_end_elements (context, ctx, - element_name, error, "enumeration", + else if (require_one_of_end_elements (context, ctx, + element_name, error, "enumeration", "bitfield", NULL)) { pop_node (ctx); @@ -3127,10 +3127,10 @@ end_element_handler (GMarkupParseContext *context, } } -static void +static void text_handler (GMarkupParseContext *context, const gchar *text, - gsize text_len, + gsize text_len, gpointer user_data, GError **error) { @@ -3149,25 +3149,25 @@ cleanup (GMarkupParseContext *context, g_ir_module_free (m->data); g_list_free (ctx->modules); ctx->modules = NULL; - + ctx->current_module = NULL; } static GList * -post_filter_toplevel_varargs_functions (GList *list, +post_filter_toplevel_varargs_functions (GList *list, GList **varargs_callbacks_out) { GList *iter; GList *varargs_callbacks = *varargs_callbacks_out; - + iter = list; while (iter) { GList *link = iter; GIrNode *node = iter->data; - + iter = iter->next; - + if (node->type == G_IR_NODE_FUNCTION) { if (((GIrNodeFunction*)node)->is_varargs) @@ -3185,9 +3185,9 @@ post_filter_toplevel_varargs_functions (GList *list, } } } - + *varargs_callbacks_out = varargs_callbacks; - + return list; } @@ -3196,9 +3196,9 @@ post_filter_varargs_functions (GList *list, GList ** varargs_callbacks_out) { GList *iter; GList *varargs_callbacks; - + list = post_filter_toplevel_varargs_functions (list, varargs_callbacks_out); - + varargs_callbacks = *varargs_callbacks_out; iter = list; @@ -3206,20 +3206,20 @@ post_filter_varargs_functions (GList *list, GList ** varargs_callbacks_out) { GList *link = iter; GIrNode *node = iter->data; - + iter = iter->next; - + if (node->type == G_IR_NODE_FUNCTION) { GList *param; gboolean function_done = FALSE; - + for (param = ((GIrNodeFunction *)node)->parameters; param; param = param->next) { GIrNodeParam *node = (GIrNodeParam *)param->data; - + if (function_done) break; @@ -3242,9 +3242,9 @@ post_filter_varargs_functions (GList *list, GList ** varargs_callbacks_out) } } } - + *varargs_callbacks_out = varargs_callbacks; - + return list; } @@ -3253,18 +3253,18 @@ post_filter (GIrModule *module) { GList *iter; GList *varargs_callbacks = NULL; - + module->entries = post_filter_varargs_functions (module->entries, &varargs_callbacks); iter = module->entries; while (iter) { GIrNode *node = iter->data; - + iter = iter->next; - - if (node->type == G_IR_NODE_OBJECT || - node->type == G_IR_NODE_INTERFACE) + + if (node->type == G_IR_NODE_OBJECT || + node->type == G_IR_NODE_INTERFACE) { GIrNodeInterface *iface = (GIrNodeInterface*)node; iface->members = post_filter_varargs_functions (iface->members, @@ -3335,7 +3335,7 @@ g_ir_parser_parse_string (GIrParser *parser, goto out; g_markup_parse_context_free (context); - + context = g_markup_parse_context_new (&markup_parser, 0, &ctx, NULL); if (!g_markup_parse_context_parse (context, buffer, length, error)) goto out; @@ -3359,9 +3359,9 @@ g_ir_parser_parse_string (GIrParser *parser, g_hash_table_destroy (ctx.disguised_structures); g_list_free (ctx.include_modules); } - + g_markup_parse_context_free (context); - + return ctx.modules; } @@ -3415,10 +3415,10 @@ g_ir_parser_parse_file (GIrParser *parser, if (!g_file_get_contents (filename, &buffer, &length, error)) return NULL; - + modules = g_ir_parser_parse_string (parser, namespace, buffer, length, error); - for (iter = modules; iter; iter = iter->next) + for (iter = modules; iter; iter = iter->next) { post_filter ((GIrModule*)iter->data); } diff --git a/girwriter.c b/girwriter.c index 5a9459fd2..2d18d1453 100644 --- a/girwriter.c +++ b/girwriter.c @@ -170,7 +170,7 @@ function_generate (GIdlWriter * writer, GIdlNodeFunction * node) { GIdlNodeParam *param = l->data; const gchar *direction = g_idl_node_param_direction_string (param); - + markup_s = g_string_new ("node.name); @@ -186,7 +186,7 @@ function_generate (GIdlWriter * writer, GIdlNodeFunction * node) if (param->allow_none) g_string_append (markup_s, g_markup_printf_escaped (" allow-none=\"1\"")); - + if (strcmp (direction, "in") != 0) g_string_append (markup_s, g_markup_printf_escaped (" direction=\"%s\"", diff --git a/gtypelib.c b/gtypelib.c index a34ca32f0..da7e5ee6d 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1,4 +1,4 @@ -/* GObject introspection: typelib validation, auxiliary functions +/* GObject introspection: typelib validation, auxiliary functions * related to the binary typelib format * * Copyright (C) 2005 Matthias Clasen @@ -46,7 +46,7 @@ static void pop_context (ValidateContext *ctx) { g_assert (ctx->context_stack != NULL); - ctx->context_stack = g_slist_delete_link (ctx->context_stack, + ctx->context_stack = g_slist_delete_link (ctx->context_stack, ctx->context_stack); } @@ -69,7 +69,7 @@ get_dir_entry_checked (GTypelib *typelib, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Invalid directory index %d", index); - return FALSE; + return FALSE; } offset = header->directory + (index - 1) * header->entry_blob_size; @@ -139,7 +139,7 @@ g_typelib_get_dir_entry (GTypelib *typelib, return (DirEntry *)&typelib->data[header->directory + (index - 1) * header->entry_blob_size]; } -void +void g_typelib_check_sanity (void) { /* Check that struct layout is as we expect */ @@ -161,7 +161,7 @@ g_typelib_check_sanity (void) * * Everything else in the code however should be using sizeof(). */ - + CHECK_SIZE (Header, 112); CHECK_SIZE (DirEntry, 12); CHECK_SIZE (SimpleTypeBlob, 4); @@ -237,7 +237,7 @@ validate_name (GTypelib *typelib, if (!name) return FALSE; - if (!memchr (name, '\0', MAX_NAME_LEN)) + if (!memchr (name, '\0', MAX_NAME_LEN)) { g_set_error (error, G_TYPELIB_ERROR, @@ -246,8 +246,8 @@ validate_name (GTypelib *typelib, msg, name); return FALSE; } - - if (strspn (name, G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_") < strlen (name)) + + if (strspn (name, G_CSET_a_2_z G_CSET_A_2_Z G_CSET_DIGITS "-_") < strlen (name)) { g_set_error (error, G_TYPELIB_ERROR, @@ -256,11 +256,11 @@ validate_name (GTypelib *typelib, msg, name); return FALSE; } - + return TRUE; } -static gboolean +static gboolean validate_header (ValidateContext *ctx, GError **error) { @@ -285,7 +285,7 @@ validate_header (ValidateContext *ctx, G_TYPELIB_ERROR_INVALID_HEADER, "Magic string not found"); return FALSE; - + } if (header->major_version != 2 || header->minor_version != 0) @@ -295,7 +295,7 @@ validate_header (ValidateContext *ctx, G_TYPELIB_ERROR_INVALID_HEADER, "Version mismatch"); return FALSE; - + } if (header->n_entries < header->n_local_entries) @@ -304,7 +304,7 @@ validate_header (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_HEADER, "Inconsistent entry counts"); - return FALSE; + return FALSE; } if (header->size != typelib->len) @@ -313,12 +313,12 @@ validate_header (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_HEADER, "Typelib size mismatch"); - return FALSE; + return FALSE; } - + /* This is a sanity check for a specific typelib; it * prevents us from loading an incompatible typelib. - * + * * The hardcoded checks in g_typelib_check_sanity to * protect against inadvertent or buggy changes to the typelib format * itself. @@ -347,7 +347,7 @@ validate_header (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_HEADER, "Blob size mismatch"); - return FALSE; + return FALSE; } if (!is_aligned (header->directory)) @@ -356,7 +356,7 @@ validate_header (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_HEADER, "Misaligned directory"); - return FALSE; + return FALSE; } if (!is_aligned (header->attributes)) @@ -365,7 +365,7 @@ validate_header (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_HEADER, "Misaligned attributes"); - return FALSE; + return FALSE; } if (header->attributes == 0 && header->n_attributes > 0) @@ -374,11 +374,11 @@ validate_header (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_HEADER, "Wrong number of attributes"); - return FALSE; + return FALSE; } if (!validate_name (typelib, "namespace", typelib->data, header->namespace, error)) - return FALSE; + return FALSE; return TRUE; } @@ -406,7 +406,7 @@ validate_array_type_blob (GTypelib *typelib, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Pointer type exected for tag %d", blob->tag); - return FALSE; + return FALSE; } /* FIXME validate length */ @@ -460,18 +460,18 @@ validate_param_type_blob (GTypelib *typelib, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Pointer type exected for tag %d", blob->tag); - return FALSE; + return FALSE; } - + if (blob->n_types != n_params) { g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Parameter type number mismatch"); - return FALSE; + return FALSE; } - + for (i = 0; i < n_params; i++) { if (!validate_type_blob (typelib, @@ -506,9 +506,9 @@ validate_error_type_blob (GTypelib *typelib, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Pointer type exected for tag %d", blob->tag); - return FALSE; + return FALSE; } - + for (i = 0; i < blob->n_domains; i++) { if (blob->domains[i] == 0 || blob->domains[i] > header->n_entries) @@ -517,7 +517,7 @@ validate_error_type_blob (GTypelib *typelib, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Invalid directory index %d", blob->domains[i]); - return FALSE; + return FALSE; } entry = g_typelib_get_dir_entry (typelib, blob->domains[i]); @@ -529,7 +529,7 @@ validate_error_type_blob (GTypelib *typelib, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Wrong blob type"); - return FALSE; + return FALSE; } } @@ -545,10 +545,10 @@ validate_type_blob (GTypelib *typelib, { SimpleTypeBlob *simple; InterfaceTypeBlob *iface; - + simple = (SimpleTypeBlob *)&typelib->data[offset]; - if (simple->flags.reserved == 0 && + if (simple->flags.reserved == 0 && simple->flags.reserved2 == 0) { if (simple->flags.tag >= GI_TYPE_TAG_ARRAY) @@ -559,7 +559,7 @@ validate_type_blob (GTypelib *typelib, "Wrong tag in simple type"); return FALSE; } - + if (simple->flags.tag >= GI_TYPE_TAG_UTF8 && !simple->flags.pointer) { @@ -567,7 +567,7 @@ validate_type_blob (GTypelib *typelib, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Pointer type exected for tag %d", simple->flags.tag); - return FALSE; + return FALSE; } return TRUE; @@ -578,28 +578,28 @@ validate_type_blob (GTypelib *typelib, switch (iface->tag) { case GI_TYPE_TAG_ARRAY: - if (!validate_array_type_blob (typelib, simple->offset, + if (!validate_array_type_blob (typelib, simple->offset, signature_offset, return_type, error)) return FALSE; break; case GI_TYPE_TAG_INTERFACE: - if (!validate_iface_type_blob (typelib, simple->offset, + if (!validate_iface_type_blob (typelib, simple->offset, signature_offset, return_type, error)) return FALSE; break; case GI_TYPE_TAG_GLIST: case GI_TYPE_TAG_GSLIST: - if (!validate_param_type_blob (typelib, simple->offset, + if (!validate_param_type_blob (typelib, simple->offset, signature_offset, return_type, 1, error)) return FALSE; break; case GI_TYPE_TAG_GHASH: - if (!validate_param_type_blob (typelib, simple->offset, + if (!validate_param_type_blob (typelib, simple->offset, signature_offset, return_type, 2, error)) return FALSE; break; case GI_TYPE_TAG_ERROR: - if (!validate_error_type_blob (typelib, simple->offset, + if (!validate_error_type_blob (typelib, simple->offset, signature_offset, return_type, error)) return FALSE; break; @@ -634,10 +634,10 @@ validate_arg_blob (GTypelib *typelib, blob = (ArgBlob*) &typelib->data[offset]; if (!validate_name (typelib, "argument", typelib->data, blob->name, error)) - return FALSE; - - if (!validate_type_blob (typelib, - offset + G_STRUCT_OFFSET (ArgBlob, arg_type), + return FALSE; + + if (!validate_type_blob (typelib, + offset + G_STRUCT_OFFSET (ArgBlob, arg_type), signature_offset, FALSE, error)) return FALSE; @@ -693,18 +693,18 @@ validate_signature_blob (GTypelib *typelib, if (blob->return_type.offset != 0) { - if (!validate_type_blob (typelib, - offset + G_STRUCT_OFFSET (SignatureBlob, return_type), + if (!validate_type_blob (typelib, + offset + G_STRUCT_OFFSET (SignatureBlob, return_type), offset, TRUE, error)) return FALSE; } for (i = 0; i < blob->n_arguments; i++) { - if (!validate_arg_blob (typelib, - offset + sizeof (SignatureBlob) + - i * sizeof (ArgBlob), - offset, + if (!validate_arg_blob (typelib, + offset + sizeof (SignatureBlob) + + i * sizeof (ArgBlob), + offset, error)) return FALSE; } @@ -746,12 +746,12 @@ validate_function_blob (ValidateContext *ctx, } if (!validate_name (typelib, "function", typelib->data, blob->name, error)) - return FALSE; + return FALSE; push_context (ctx, get_string_nofail (typelib, blob->name)); - + if (!validate_name (typelib, "function symbol", typelib->data, blob->symbol, error)) - return FALSE; + return FALSE; switch (container_type) { @@ -765,7 +765,7 @@ validate_function_blob (ValidateContext *ctx, default: is_method = FALSE; } - + if (blob->constructor) { switch (container_type) @@ -820,7 +820,7 @@ validate_function_blob (ValidateContext *ctx, sigblob = (SignatureBlob*) &typelib->data[blob->signature]; - if (blob->constructor) + if (blob->constructor) { SimpleTypeBlob *simple = return_type_from_signature (typelib, blob->signature, @@ -877,15 +877,15 @@ validate_callback_blob (ValidateContext *ctx, } if (!validate_name (typelib, "callback", typelib->data, blob->name, error)) - return FALSE; + return FALSE; push_context (ctx, get_string_nofail (typelib, blob->name)); - + if (!validate_signature_blob (typelib, blob->signature, error)) return FALSE; pop_context (ctx); - + return TRUE; } @@ -950,9 +950,9 @@ validate_constant_blob (GTypelib *typelib, } if (!validate_name (typelib, "constant", typelib->data, blob->name, error)) - return FALSE; - - if (!validate_type_blob (typelib, offset + G_STRUCT_OFFSET (ConstantBlob, type), + return FALSE; + + if (!validate_type_blob (typelib, offset + G_STRUCT_OFFSET (ConstantBlob, type), 0, FALSE, error)) return FALSE; @@ -964,7 +964,7 @@ validate_constant_blob (GTypelib *typelib, "Misaligned constant value"); return FALSE; } - + type = (SimpleTypeBlob *)&typelib->data[offset + G_STRUCT_OFFSET (ConstantBlob, type)]; if (type->flags.reserved == 0 && type->flags.reserved2 == 0) { @@ -1011,8 +1011,8 @@ validate_value_blob (GTypelib *typelib, blob = (ValueBlob*) &typelib->data[offset]; if (!validate_name (typelib, "value", typelib->data, blob->name, error)) - return FALSE; - + return FALSE; + return TRUE; } @@ -1035,9 +1035,9 @@ validate_field_blob (ValidateContext *ctx, } blob = (FieldBlob*) &typelib->data[offset]; - + if (!validate_name (typelib, "field", typelib->data, blob->name, error)) - return FALSE; + return FALSE; if (blob->has_embedded_type) { @@ -1045,7 +1045,7 @@ validate_field_blob (ValidateContext *ctx, return FALSE; } else if (!validate_type_blob (typelib, - offset + G_STRUCT_OFFSET (FieldBlob, type), + offset + G_STRUCT_OFFSET (FieldBlob, type), 0, FALSE, error)) return FALSE; @@ -1069,12 +1069,12 @@ validate_property_blob (GTypelib *typelib, } blob = (PropertyBlob*) &typelib->data[offset]; - + if (!validate_name (typelib, "property", typelib->data, blob->name, error)) - return FALSE; - + return FALSE; + if (!validate_type_blob (typelib, - offset + G_STRUCT_OFFSET (PropertyBlob, type), + offset + G_STRUCT_OFFSET (PropertyBlob, type), 0, FALSE, error)) return FALSE; @@ -1102,17 +1102,17 @@ validate_signal_blob (GTypelib *typelib, blob = (SignalBlob*) &typelib->data[offset]; if (!validate_name (typelib, "signal", typelib->data, blob->name, error)) - return FALSE; - - if ((blob->run_first != 0) + - (blob->run_last != 0) + + return FALSE; + + if ((blob->run_first != 0) + + (blob->run_last != 0) + (blob->run_cleanup != 0) != 1) { g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Invalid signal run flags"); - return FALSE; + return FALSE; } if (blob->has_class_closure) @@ -1122,15 +1122,15 @@ validate_signal_blob (GTypelib *typelib, ObjectBlob *object; object = (ObjectBlob*)&typelib->data[container_offset]; - + n_signals = object->n_signals; } else { InterfaceBlob *iface; - + iface = (InterfaceBlob*)&typelib->data[container_offset]; - + n_signals = iface->n_signals; } @@ -1140,13 +1140,13 @@ validate_signal_blob (GTypelib *typelib, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Invalid class closure index"); - return FALSE; + return FALSE; } } if (!validate_signature_blob (typelib, blob->signature, error)) return FALSE; - + return TRUE; } @@ -1171,8 +1171,8 @@ validate_vfunc_blob (GTypelib *typelib, blob = (VFuncBlob*) &typelib->data[offset]; if (!validate_name (typelib, "vfunc", typelib->data, blob->name, error)) - return FALSE; - + return FALSE; + if (blob->class_closure) { if (((CommonBlob*)&typelib->data[container_offset])->blob_type == BLOB_TYPE_OBJECT) @@ -1180,15 +1180,15 @@ validate_vfunc_blob (GTypelib *typelib, ObjectBlob *object; object = (ObjectBlob*)&typelib->data[container_offset]; - + n_vfuncs = object->n_vfuncs; } else { InterfaceBlob *iface; - + iface = (InterfaceBlob*)&typelib->data[container_offset]; - + n_vfuncs = iface->n_vfuncs; } @@ -1198,13 +1198,13 @@ validate_vfunc_blob (GTypelib *typelib, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Invalid class closure index"); - return FALSE; + return FALSE; } } if (!validate_signature_blob (typelib, blob->signature, error)) return FALSE; - + return TRUE; } @@ -1240,17 +1240,17 @@ validate_struct_blob (ValidateContext *ctx, } if (!validate_name (typelib, "struct", typelib->data, blob->name, error)) - return FALSE; + return FALSE; push_context (ctx, get_string_nofail (typelib, blob->name)); - + if (!blob->unregistered) { if (!validate_name (typelib, "boxed", typelib->data, blob->gtype_name, error)) - return FALSE; + return FALSE; if (!validate_name (typelib, "boxed", typelib->data, blob->gtype_init, error)) - return FALSE; + return FALSE; } else { @@ -1260,11 +1260,11 @@ validate_struct_blob (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Gtype data in struct"); - return FALSE; + return FALSE; } } - if (typelib->len < offset + sizeof (StructBlob) + + if (typelib->len < offset + sizeof (StructBlob) + blob->n_fields * sizeof (FieldBlob) + blob->n_methods * sizeof (FunctionBlob)) { @@ -1292,9 +1292,9 @@ validate_struct_blob (ValidateContext *ctx, for (i = 0; i < blob->n_methods; i++) { - if (!validate_function_blob (ctx, - field_offset + - i * sizeof (FunctionBlob), + if (!validate_function_blob (ctx, + field_offset + + i * sizeof (FunctionBlob), blob_type, error)) return FALSE; @@ -1334,14 +1334,14 @@ validate_enum_blob (ValidateContext *ctx, "Wrong blob type"); return FALSE; } - + if (!blob->unregistered) { if (!validate_name (typelib, "enum", typelib->data, blob->gtype_name, error)) - return FALSE; + return FALSE; if (!validate_name (typelib, "enum", typelib->data, blob->gtype_init, error)) - return FALSE; + return FALSE; } else { @@ -1351,14 +1351,14 @@ validate_enum_blob (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Gtype data in unregistered enum"); - return FALSE; + return FALSE; } } if (!validate_name (typelib, "enum", typelib->data, blob->name, error)) - return FALSE; - - if (typelib->len < offset + sizeof (EnumBlob) + + return FALSE; + + if (typelib->len < offset + sizeof (EnumBlob) + blob->n_values * sizeof (ValueBlob)) { g_set_error (error, @@ -1369,21 +1369,21 @@ validate_enum_blob (ValidateContext *ctx, } push_context (ctx, get_string_nofail (typelib, blob->name)); - + for (i = 0; i < blob->n_values; i++) { - if (!validate_value_blob (typelib, - offset + sizeof (EnumBlob) + - i * sizeof (ValueBlob), + if (!validate_value_blob (typelib, + offset + sizeof (EnumBlob) + + i * sizeof (ValueBlob), error)) return FALSE; #if 0 - v1 = (ValueBlob *)&typelib->data[offset + sizeof (EnumBlob) + + v1 = (ValueBlob *)&typelib->data[offset + sizeof (EnumBlob) + i * sizeof (ValueBlob)]; - for (j = 0; j < i; j++) + for (j = 0; j < i; j++) { - v2 = (ValueBlob *)&typelib->data[offset + sizeof (EnumBlob) + + v2 = (ValueBlob *)&typelib->data[offset + sizeof (EnumBlob) + j * sizeof (ValueBlob)]; if (v1->value == v2->value) @@ -1397,11 +1397,11 @@ validate_enum_blob (ValidateContext *ctx, return FALSE; } } -#endif +#endif } pop_context (ctx); - + return TRUE; } @@ -1437,15 +1437,15 @@ validate_object_blob (ValidateContext *ctx, "Wrong blob type"); return FALSE; } - + if (!validate_name (typelib, "object", typelib->data, blob->gtype_name, error)) - return FALSE; - + return FALSE; + if (!validate_name (typelib, "object", typelib->data, blob->gtype_init, error)) - return FALSE; - + return FALSE; + if (!validate_name (typelib, "object", typelib->data, blob->name, error)) - return FALSE; + return FALSE; if (blob->parent > header->n_entries) { @@ -1453,7 +1453,7 @@ validate_object_blob (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Invalid parent index"); - return FALSE; + return FALSE; } if (blob->parent != 0) @@ -1470,10 +1470,10 @@ validate_object_blob (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Parent not object"); - return FALSE; + return FALSE; } } - + if (blob->gtype_struct != 0) { DirEntry *entry; @@ -1487,11 +1487,11 @@ validate_object_blob (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Class struct invalid type or not local"); - return FALSE; + return FALSE; } - } - - if (typelib->len < offset + sizeof (ObjectBlob) + + } + + if (typelib->len < offset + sizeof (ObjectBlob) + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + blob->n_fields * sizeof (FieldBlob) + blob->n_properties * sizeof (PropertyBlob) + @@ -1499,7 +1499,7 @@ validate_object_blob (ValidateContext *ctx, blob->n_signals * sizeof (SignalBlob) + blob->n_vfuncs * sizeof (VFuncBlob) + blob->n_constants * sizeof (ConstantBlob)) - + { g_set_error (error, G_TYPELIB_ERROR, @@ -1522,9 +1522,9 @@ validate_object_blob (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Invalid interface index"); - return FALSE; + return FALSE; } - + entry = get_dir_entry_checked (typelib, iface, error); if (!entry) return FALSE; @@ -1536,14 +1536,14 @@ validate_object_blob (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Not an interface"); - return FALSE; + return FALSE; } } offset2 += 2 * (blob->n_interfaces %2); push_context (ctx, get_string_nofail (typelib, blob->name)); - + for (i = 0; i < blob->n_fields; i++, offset2 += sizeof (FieldBlob)) { if (!validate_field_blob (ctx, offset2, error)) @@ -1595,7 +1595,7 @@ validate_interface_blob (ValidateContext *ctx, InterfaceBlob *blob; gint i; guint32 offset2; - + header = (Header *)typelib->data; if (typelib->len < offset + sizeof (InterfaceBlob)) @@ -1617,24 +1617,24 @@ validate_interface_blob (ValidateContext *ctx, "Wrong blob type; expected interface, got %d", blob->blob_type); return FALSE; } - + if (!validate_name (typelib, "interface", typelib->data, blob->gtype_name, error)) - return FALSE; - + return FALSE; + if (!validate_name (typelib, "interface", typelib->data, blob->gtype_init, error)) - return FALSE; - + return FALSE; + if (!validate_name (typelib, "interface", typelib->data, blob->name, error)) - return FALSE; - - if (typelib->len < offset + sizeof (InterfaceBlob) + + return FALSE; + + if (typelib->len < offset + sizeof (InterfaceBlob) + (blob->n_prerequisites + blob->n_prerequisites % 2) * 2 + blob->n_properties * sizeof (PropertyBlob) + blob->n_methods * sizeof (FunctionBlob) + blob->n_signals * sizeof (SignalBlob) + blob->n_vfuncs * sizeof (VFuncBlob) + blob->n_constants * sizeof (ConstantBlob)) - + { g_set_error (error, G_TYPELIB_ERROR, @@ -1657,7 +1657,7 @@ validate_interface_blob (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Invalid prerequisite index"); - return FALSE; + return FALSE; } entry = g_typelib_get_dir_entry (typelib, req); @@ -1669,14 +1669,14 @@ validate_interface_blob (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Not an interface or object"); - return FALSE; + return FALSE; } } offset2 += 2 * (blob->n_prerequisites % 2); push_context (ctx, get_string_nofail (typelib, blob->name)); - + for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob)) { if (!validate_property_blob (typelib, offset2, error)) @@ -1688,13 +1688,13 @@ validate_interface_blob (ValidateContext *ctx, if (!validate_function_blob (ctx, offset2, BLOB_TYPE_INTERFACE, error)) return FALSE; } - + for (i = 0; i < blob->n_signals; i++, offset2 += sizeof (SignalBlob)) { if (!validate_signal_blob (typelib, offset2, offset, error)) return FALSE; } - + for (i = 0; i < blob->n_vfuncs; i++, offset2 += sizeof (VFuncBlob)) { if (!validate_vfunc_blob (typelib, offset2, offset, error)) @@ -1746,7 +1746,7 @@ validate_blob (ValidateContext *ctx, } common = (CommonBlob*)&typelib->data[offset]; - + switch (common->blob_type) { case BLOB_TYPE_FUNCTION: @@ -1788,7 +1788,7 @@ validate_blob (ValidateContext *ctx, return FALSE; break; default: - g_set_error (error, + g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_ENTRY, "Invalid blob type"); @@ -1798,7 +1798,7 @@ validate_blob (ValidateContext *ctx, return TRUE; } -static gboolean +static gboolean validate_directory (ValidateContext *ctx, GError **error) { @@ -1806,7 +1806,7 @@ validate_directory (ValidateContext *ctx, Header *header = (Header *)typelib->data; DirEntry *entry; gint i; - + if (typelib->len < header->directory + header->n_entries * sizeof (DirEntry)) { g_set_error (error, @@ -1821,8 +1821,8 @@ validate_directory (ValidateContext *ctx, entry = g_typelib_get_dir_entry (typelib, i + 1); if (!validate_name (typelib, "entry", typelib->data, entry->name, error)) - return FALSE; - + return FALSE; + if ((entry->local && entry->blob_type == BLOB_TYPE_INVALID) || entry->blob_type > BLOB_TYPE_UNION) { @@ -1830,7 +1830,7 @@ validate_directory (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_DIRECTORY, "Invalid entry type"); - return FALSE; + return FALSE; } if (i < header->n_local_entries) @@ -1868,7 +1868,7 @@ validate_directory (ValidateContext *ctx, } if (!validate_name (typelib, "namespace", typelib->data, entry->offset, error)) - return FALSE; + return FALSE; } } @@ -1888,9 +1888,9 @@ validate_attributes (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID, "The buffer is too short"); - return FALSE; + return FALSE; } - + return TRUE; } @@ -1902,7 +1902,7 @@ prefix_with_context (GError **error, GString *str = g_string_new (NULL); GSList *link; char *buf; - + link = ctx->context_stack; if (!link) { @@ -1922,7 +1922,7 @@ prefix_with_context (GError **error, g_free (buf); } -gboolean +gboolean g_typelib_validate (GTypelib *typelib, GError **error) { @@ -1965,7 +1965,7 @@ _g_typelib_do_dlopen (GTypelib *typelib) { Header *header; const char *shlib_str; - + header = (Header *) typelib->data; /* note that NULL shlib means to open the main app, which is allowed */ if (header->shared_library) @@ -2059,11 +2059,11 @@ _g_typelib_ensure_open (GTypelib *typelib) * g_typelib_new_from_memory: * @memory: address of memory chunk containing the typelib * @len: length of memory chunk containing the typelib - * + * * Creates a new #GTypelib from a memory location. The memory block * pointed to by @typelib will be automatically g_free()d when the * repository is destroyed. - * + * * Return value: the new #GTypelib **/ GTypelib * @@ -2084,9 +2084,9 @@ g_typelib_new_from_memory (guchar *memory, gsize len) * g_typelib_new_from_const_memory: * @memory: address of memory chunk containing the typelib * @len: length of memory chunk containing the typelib - * + * * Creates a new #GTypelib from a memory location. - * + * * Return value: the new #GTypelib **/ GTypelib * @@ -2106,9 +2106,9 @@ g_typelib_new_from_const_memory (const guchar *memory, gsize len) /** * g_typelib_new_from_mapped_file: * @mfile: a #GMappedFile, that will be free'd when the repository is destroyed - * + * * Creates a new #GTypelib from a #GMappedFile. - * + * * Return value: the new #GTypelib **/ GTypelib * @@ -2128,7 +2128,7 @@ g_typelib_new_from_mapped_file (GMappedFile *mfile) /** * g_typelib_free: * @typelib: a #GTypelib - * + * * Free a #GTypelib. **/ void @@ -2167,7 +2167,7 @@ gboolean g_typelib_symbol (GTypelib *typelib, const char *symbol_name, gpointer *symbol) { GList *l; - + _g_typelib_ensure_open (typelib); /* @@ -2177,9 +2177,9 @@ g_typelib_symbol (GTypelib *typelib, const char *symbol_name, gpointer *symbol) * will be the custom one, which overrides the main one. A bit * inefficient, but the problem will go away when gir-repository * does. - * + * * For modules with no shared library, we dlopen'd the current - * process above. + * process above. */ for (l = typelib->modules; l; l = l->next) { diff --git a/gtypelib.h b/gtypelib.h index f02dcfc2e..99d4472c8 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -35,21 +35,21 @@ G_BEGIN_DECLS * * The "typelib" is a binary, readonly, memory-mappable database * containing reflective information about a GObject library. - * - * The format of GObject typelib is strongly influenced by the Mozilla XPCOM - * format. + * + * The format of GObject typelib is strongly influenced by the Mozilla XPCOM + * format. * * Some of the differences to XPCOM include: - * - Type information is stored not quite as compactly (XPCOM stores it inline - * in function descriptions in variable-sized blobs of 1 to n bytes. We store - * 16 bits of type information for each parameter, which is enough to encode - * simple types inline. Complex (e.g. recursive) types are stored out of line + * - Type information is stored not quite as compactly (XPCOM stores it inline + * in function descriptions in variable-sized blobs of 1 to n bytes. We store + * 16 bits of type information for each parameter, which is enough to encode + * simple types inline. Complex (e.g. recursive) types are stored out of line * in a separate list of types. - * - String and complex type data is stored outside of typelib entry blobs, - * references are stored as offsets relative to the start of the typelib. - * One possibility is to store the strings and types in a pools at the end - * of the typelib. - * + * - String and complex type data is stored outside of typelib entry blobs, + * references are stored as offsets relative to the start of the typelib. + * One possibility is to store the strings and types in a pools at the end + * of the typelib. + * * The typelib has the following general format. * * typelib ::= header, directory, blobs, attributes, attributedata @@ -63,8 +63,8 @@ G_BEGIN_DECLS * attributedata ::= string data for attributes * * Details - * - * We describe the fragments that make up the typelib in the form of C structs + * + * We describe the fragments that make up the typelib in the form of C structs * (although some fall short of being valid C structs since they contain multiple * flexible arrays). */ @@ -113,11 +113,11 @@ Changes since 0.1: - use 'blob' as collective name for the various blob types - rename 'type' field in blobs to 'blob_type' - rename 'type_name' and 'type_init' fields to 'gtype_name', 'gtype_init' -- shrink directory entries to 12 bytes +- shrink directory entries to 12 bytes - merge struct and boxed blobs - split interface blobs into enum, object and interface blobs - add an 'unregistered' flag to struct and enum blobs -- add a 'wraps_vfunc' flag to function blobs and link them to +- add a 'wraps_vfunc' flag to function blobs and link them to the vfuncs they wrap - restrict value blobs to only occur inside enums and flags again - add constant blobs, allow them toplevel, in interfaces and in objects @@ -133,8 +133,8 @@ Changes since 0.1: /** * G_IR_MAGIC: - * - * Identifying prefix for the typelib. This was inspired by XPCOM, + * + * Identifying prefix for the typelib. This was inspired by XPCOM, * which in turn borrowed from PNG. */ #define G_IR_MAGIC "GOBJ\nMETADATA\r\n\032" @@ -153,7 +153,7 @@ Changes since 0.1: * @BLOB_TYPE_CONSTANT: A #ConstantBlob * @BLOB_TYPE_ERROR_DOMAIN: A #ErrorDomainBlob * @BLOB_TYPE_UNION: A #UnionBlob - * + * * The integral value of this enumeration appears in each "Blob" * component of a typelib to identify its type. */ @@ -182,8 +182,8 @@ typedef enum { /** * Header: * @magic: See #G_IR_MAGIC. - * @major_version: The version of the typelib format. Minor version changes indicate - * compatible changes and should still allow the typelib to be parsed + * @major_version: The version of the typelib format. Minor version changes indicate + * compatible changes and should still allow the typelib to be parsed * by a parser designed for the same major_version. * @minor_version: See major_version. * @n_entries: The number of entries in the directory. @@ -197,7 +197,7 @@ typedef enum { * dependencies are required in order to avoid having programs * consuming a typelib check for an "Unresolved" type return * from every API call. - * @size: The size in bytes of the typelib. + * @size: The size in bytes of the typelib. * @namespace: Offset of the namespace string in the typelib. * @nsversion: Offset of the namespace version string in the typelib. * @shared_library: This field is the set of shared libraries associated @@ -222,13 +222,13 @@ typedef enum { * @struct_blob_size: See above. * @error_domain_blob_size: See above. * @interface_blob_size: For variable-size blobs, the size of the struct up to the first - * flexible array member. Recording this information here allows to - * write parser which continue to work if the format is extended by - * adding new fields before the first flexible array member in + * flexible array member. Recording this information here allows to + * write parser which continue to work if the format is extended by + * adding new fields before the first flexible array member in * variable-size blobs. - * + * * The header structure appears exactly once at the beginning of a typelib. It is a - * collection of meta-information, such as the number of entries and dependencies. + * collection of meta-information, such as the number of entries and dependencies. */ typedef struct { gchar magic[16]; @@ -268,7 +268,7 @@ typedef struct { guint16 object_blob_size; guint16 interface_blob_size; guint16 union_blob_size; - + guint16 padding[7]; } Header; @@ -280,10 +280,10 @@ typedef struct { * @offset: If is_local is set, this is the offset of the blob in the typelib. * Otherwise, it is the offset of the namespace in which the blob has * to be looked up by name. - * + * * References to directory entries are stored as 1-based 16-bit indexes. - * - * All blobs pointed to by a directory entry start with the same layout for + * + * All blobs pointed to by a directory entry start with the same layout for * the first 8 bytes (the reserved flags may be used by some blob types) */ typedef struct { @@ -298,9 +298,9 @@ typedef struct { /** * SimpleTypeBlob: - * @is_pointer: Indicates whether the type is passed by reference. + * @is_pointer: Indicates whether the type is passed by reference. * @tag: A #GITypeTag - * @offset: Offset relative to header->types that points to a TypeBlob. + * @offset: Offset relative to header->types that points to a TypeBlob. * Unlike other offsets, this is in words (ie 32bit units) rather * than bytes. * @@ -320,53 +320,53 @@ typedef struct { */ typedef union { - struct + struct { guint reserved : 8; guint reserved2 :16; guint pointer : 1; guint reserved3 : 2; - guint tag : 5; + guint tag : 5; } flags; guint32 offset; } SimpleTypeBlob; /* * ArgBlob: - * @name: A suggested name for the parameter. + * @name: A suggested name for the parameter. * @in: The parameter is an input to the function - * @out: The parameter is used to return an output of the function. - * Parameters can be both in and out. Out parameters implicitly - * add another level of indirection to the parameter type. Ie if - * the type is uint32 in an out parameter, the function actually + * @out: The parameter is used to return an output of the function. + * Parameters can be both in and out. Out parameters implicitly + * add another level of indirection to the parameter type. Ie if + * the type is uint32 in an out parameter, the function actually * takes an uint32*. - * @dipper: The parameter is a pointer to a struct or object that will - * receive an output of the function. + * @dipper: The parameter is a pointer to a struct or object that will + * receive an output of the function. * @allow_none: Only meaningful for types which are passed as pointers. - * For an in parameter, indicates if it is ok to pass NULL in, for - * an out parameter, whether it may return NULL. Note that NULL is a + * For an in parameter, indicates if it is ok to pass NULL in, for + * an out parameter, whether it may return NULL. Note that NULL is a * valid GList and GSList value, thus allow_none will normally be set * for parameters of these types. * @optional: For an out parameter, indicates that NULL may be passed in * if the value is not needed. - * @transfer_ownership: For an in parameter, indicates that the function takes over - * ownership of the parameter value. For an out parameter, it - * indicates that the caller is responsible for freeing the return + * @transfer_ownership: For an in parameter, indicates that the function takes over + * ownership of the parameter value. For an out parameter, it + * indicates that the caller is responsible for freeing the return * value. * @transfer_container_ownership: For container types, indicates that the - * ownership of the container, but not of its contents is transferred. This is typically the case + * ownership of the container, but not of its contents is transferred. This is typically the case * for out parameters returning lists of statically allocated things. - * @is_return_value: The parameter should be considered the return value of the function. - * Only out parameters can be marked as return value, and there can be - * at most one per function call. If an out parameter is marked as - * return value, the actual return value of the function should be + * @is_return_value: The parameter should be considered the return value of the function. + * Only out parameters can be marked as return value, and there can be + * at most one per function call. If an out parameter is marked as + * return value, the actual return value of the function should be * either void or a boolean indicating the success of the call. * @scope: A #GIScopeType. If the parameter is of a callback type, this denotes the scope * of the user_data and the callback function pointer itself * (for languages that emit code at run-time). - * @closure: Index of the closure (user_data) parameter associated with the callback, + * @closure: Index of the closure (user_data) parameter associated with the callback, * or -1. - * @destroy: Index of the destroy notfication callback parameter associated with + * @destroy: Index of the destroy notfication callback parameter associated with * the callback, or -1. * @arg_type: Describes the type of the parameter. See details below. * @@ -402,9 +402,9 @@ typedef struct { * @caller_owns_return_value: If set, the caller is responsible for freeing the return value * if it is no longer needed. * @caller_owns_return_container: This flag is only relevant if the return type is a container type. - * If the flag is set, the caller is resonsible for freeing the + * If the flag is set, the caller is resonsible for freeing the * container, but not its contents. - * @n_arguments: The number of arguments that this function expects, also the length + * @n_arguments: The number of arguments that this function expects, also the length * of the array of ArgBlobs. * @arguments: An array of ArgBlob for the arguments of the function. */ @@ -426,9 +426,9 @@ typedef struct { * @blob_type: A #GTypelibBlobType * @deprecated: Whether the blob is deprecated. * @name: The name of the blob. - * + * * The #CommonBlob is shared between #FunctionBlob, - * #CallbackBlob, #SignalBlob. + * #CallbackBlob, #SignalBlob. */ typedef struct { guint16 blob_type; /* 1 */ @@ -442,22 +442,22 @@ typedef struct { /** * FunctionBlob: * @blob_Type: #BLOB_TYPE_FUNCTION - * @symbol: The symbol which can be used to obtain the function pointer with + * @symbol: The symbol which can be used to obtain the function pointer with * dlsym(). * @deprecated: The function is deprecated. - * @setter: The function is a setter for a property. Language bindings may - * prefer to not bind individual setters and rely on the generic + * @setter: The function is a setter for a property. Language bindings may + * prefer to not bind individual setters and rely on the generic * g_object_set(). - * @getter: The function is a getter for a property. Language bindings may - * prefer to not bind individual getters and rely on the generic + * @getter: The function is a getter for a property. Language bindings may + * prefer to not bind individual getters and rely on the generic * g_object_get(). - * @constructor:The function acts as a constructor for the object it is contained + * @constructor:The function acts as a constructor for the object it is contained * in. * @wraps_vfunc: The function is a simple wrapper for a virtual function. - * @index: Index of the property that this function is a setter or getter of + * @index: Index of the property that this function is a setter or getter of * in the array of properties of the containing interface, or index * of the virtual function that this function wraps. - * @signature: Offset of the SignatureBlob describing the parameter types and the + * @signature: Offset of the SignatureBlob describing the parameter types and the * return value type. * @is_static: The function is a "static method"; in other words it's a pure * function whose name is conceptually scoped to the object. @@ -487,7 +487,7 @@ typedef struct { /** * CallbackBlob: - * @signature: Offset of the #SignatureBlob describing the parameter types and the + * @signature: Offset of the #SignatureBlob describing the parameter types and the * return value type. */ typedef struct { @@ -505,36 +505,36 @@ typedef struct { * @pointer: Whether this type represents an indirection * @tag: A #GITypeTag * @interface: Index of the directory entry for the interface. - * + * * If the interface is an enum of flags type, is_pointer is 0, otherwise it is 1. */ typedef struct { guint8 pointer :1; guint8 reserved :2; - guint8 tag :5; + guint8 tag :5; guint8 reserved2; - guint16 interface; + guint16 interface; } InterfaceTypeBlob; /** * ArrayTypeBlob: - * @zero_terminated: Indicates that the array must be terminated by a suitable #NULL - * value. - * @has_length: Indicates that length points to a parameter specifying the length - * of the array. If both has_length and zero_terminated are set, the - * convention is to pass -1 for the length if the array is - * zero-terminated. - * @length: The index of the parameter which is used to pass the length of the - * array. The parameter must be an integer type and have the same - * direction as this one. + * @zero_terminated: Indicates that the array must be terminated by a suitable #NULL + * value. + * @has_length: Indicates that length points to a parameter specifying the length + * of the array. If both has_length and zero_terminated are set, the + * convention is to pass -1 for the length if the array is + * zero-terminated. + * @length: The index of the parameter which is used to pass the length of the + * array. The parameter must be an integer type and have the same + * direction as this one. * @type: The type of the array elements. - * + * * Arrays are passed by reference, thus is_pointer is always 1. */ typedef struct { guint16 pointer :1; guint16 reserved :2; - guint16 tag :5; + guint16 tag :5; guint16 zero_terminated :1; guint16 has_length :1; @@ -553,12 +553,12 @@ typedef struct { * ParamTypeBlob: * @n_types: The number of parameter types to follow. * @type: Describes the type of the list elements. - * + * */ typedef struct { guint8 pointer :1; guint8 reserved :2; - guint8 tag :5; + guint8 tag :5; guint8 reserved2; guint16 n_types; @@ -574,7 +574,7 @@ typedef struct { typedef struct { guint8 pointer :1; guint8 reserved :2; - guint8 tag :5; + guint8 tag :5; guint8 reserved2; guint16 n_domains; @@ -584,7 +584,7 @@ typedef struct { /** * ErrorDomainBlob: - * @get_quark: The symbol name of the function which must be called to obtain the + * @get_quark: The symbol name of the function which must be called to obtain the * GQuark for the error domain. * @error_codes: Index of the InterfaceBlob describing the enumeration which lists * the possible error codes. @@ -594,7 +594,7 @@ typedef struct { guint16 deprecated : 1; guint16 reserved :15; - + guint32 name; guint32 get_quark; @@ -607,7 +607,7 @@ typedef struct { * @deprecated: Whether this value is deprecated * @value: The numerical value * @name: Name of blob - * + * * Values commonly occur in enums and flags. */ typedef struct { @@ -633,7 +633,7 @@ typedef struct { typedef struct { guint32 name; - guint8 readable :1; + guint8 readable :1; guint8 writable :1; guint8 has_embedded_type :1; guint8 reserved :5; @@ -652,11 +652,11 @@ typedef struct { * @gtype_init: The symbol name of the get_type() function which registers the type. */ typedef struct { - guint16 blob_type; - guint16 deprecated : 1; + guint16 blob_type; + guint16 deprecated : 1; guint16 unregistered : 1; guint16 reserved :14; - guint32 name; + guint32 name; guint32 gtype_name; guint32 gtype_init; @@ -672,10 +672,10 @@ typedef struct { * @size: The size of the struct in bytes. * @gtype_name: String name of the associated #GType * @gtype_init: String naming the symbol which gets the runtime #GType - * @n_fields: + * @n_fields: * @n_functions: The lengths of the arrays. - * @fields: An array of n_fields FieldBlobs. - * @functions: An array of n_functions FunctionBlobs. The described functions + * @fields: An array of n_fields FieldBlobs. + * @functions: An array of n_functions FunctionBlobs. The described functions * should be considered as methods of the struct. */ typedef struct { @@ -684,7 +684,7 @@ typedef struct { guint16 deprecated : 1; guint16 unregistered : 1; guint16 is_gtype_struct : 1; - guint16 alignment : 6; + guint16 alignment : 6; guint16 reserved : 7; guint32 name; @@ -702,7 +702,7 @@ typedef struct { #if 0 /* variable-length parts of the blob */ - FieldBlob fields[]; + FieldBlob fields[]; FunctionBlob methods[]; #endif } StructBlob; @@ -720,12 +720,12 @@ typedef struct { * discriminator of a discriminated union is located. * The value 0xFFFF indicates that the discriminator offset * is unknown. - * @discriminator_type: Type of the discriminator + * @discriminator_type: Type of the discriminator * @discriminator_values: On discriminator value per field * @fields: Array of FieldBlobs describing the alternative branches of the union */ typedef struct { - guint16 blob_type; + guint16 blob_type; guint16 deprecated : 1; guint16 unregistered : 1; guint16 discriminated : 1; @@ -744,12 +744,12 @@ typedef struct { guint32 reserved2; guint32 reserved3; - gint32 discriminator_offset; + gint32 discriminator_offset; SimpleTypeBlob discriminator_type; #if 0 - FieldBlob fields[]; - FunctionBlob functions[]; + FieldBlob fields[]; + FunctionBlob functions[]; ConstantBlob discriminator_values[] #endif } UnionBlob; @@ -762,17 +762,17 @@ typedef struct { * @gtype_name: String name of the associated #GType * @gtype_init: String naming the symbol which gets the runtime #GType * @n_values: The lengths of the values arrays. - * @values: Describes the enum values. + * @values: Describes the enum values. */ typedef struct { guint16 blob_type; - guint16 deprecated : 1; + guint16 deprecated : 1; guint16 unregistered : 1; guint16 storage_type : 5; guint16 reserved : 9; - guint32 name; + guint32 name; guint32 gtype_name; guint32 gtype_init; @@ -782,15 +782,15 @@ typedef struct { guint32 reserved3; - ValueBlob values[]; + ValueBlob values[]; } EnumBlob; /** * PropertyBlob: - * @name: The name of the property. + * @name: The name of the property. * @readable: - * @writable: - * @construct: + * @writable: + * @construct: * @construct_only: The ParamFlags used when registering the property. * @type: Describes the type of the property. */ @@ -823,7 +823,7 @@ typedef struct { * @true_stops_emit: Whether the signal has true-stops-emit semantics * @class_closure: The index of the class closure in the list of virtual functions * of the object or interface on which the signal is defined. - * @signature: Offset of the SignatureBlob describing the parameter types and the + * @signature: Offset of the SignatureBlob describing the parameter types and the * return value type. */ typedef struct { @@ -852,19 +852,19 @@ typedef struct { * VFuncBlob: * @name: The name of the virtual function. * @must_chain_up: If set, every implementation of this virtual function must - * chain up to the implementation of the parent class. + * chain up to the implementation of the parent class. * @must_be_implemented: If set, every derived class must override this virtual function. * @must_not_be_implemented: If set, derived class must not override this virtual function. * @class_closure: Set if this virtual function is the class closure of a signal. - * @signal: The index of the signal in the list of signals of the object or + * @signal: The index of the signal in the list of signals of the object or * interface to which this virtual function belongs. * @struct_offset: The offset of the function pointer in the class struct. The value * 0xFFFF indicates that the struct offset is unknown. * @invoker: If a method invoker for this virtual exists, this is the offset in the * class structure of the method. If no method is known, this value will be 0x3ff. - * @signature: - * Offset of the SignatureBlob describing the parameter types and the - * return value type. + * @signature: + * Offset of the SignatureBlob describing the parameter types and the + * return value type. */ typedef struct { guint32 name; @@ -889,19 +889,19 @@ typedef struct { * @blob_type: #BLOB_TYPE_OBJECT * @gtype_name: String name of the associated #GType * @gtype_init: String naming the symbol which gets the runtime #GType - * @parent: The directory index of the parent type. This is only set for + * @parent: The directory index of the parent type. This is only set for * objects. If an object does not have a parent, it is zero. * @n_interfaces: - * @n_fields: + * @n_fields: * @n_properties: * @n_methods: * @n_signals: * @n_vfuncs: - * @n_constants: The lengths of the arrays.Up to 16bits of padding may be inserted + * @n_constants: The lengths of the arrays.Up to 16bits of padding may be inserted * between the arrays to ensure that they start on a 32bit boundary. - * @interfaces: An array of indices of directory entries for the implemented + * @interfaces: An array of indices of directory entries for the implemented * interfaces. - * @fields: Describes the fields. + * @fields: Describes the fields. * @methods: Describes the methods, constructors, setters and getters. * @properties: Describes the properties. * @signals: Describes the signals. @@ -934,7 +934,7 @@ typedef struct { guint32 reserved4; guint16 interfaces[]; - + #if 0 /* variable-length parts of the blob */ FieldBlob fields[]; @@ -965,10 +965,10 @@ typedef struct { * @constants: Describes the constants. */ typedef struct { - guint16 blob_type; + guint16 blob_type; guint16 deprecated : 1; guint16 reserved :15; - guint32 name; + guint32 name; guint32 gtype_name; guint32 gtype_init; @@ -979,14 +979,14 @@ typedef struct { guint16 n_methods; guint16 n_signals; guint16 n_vfuncs; - guint16 n_constants; + guint16 n_constants; guint32 reserved2; guint32 reserved3; guint16 prerequisites[]; -#if 0 +#if 0 /* variable-length parts of the blob */ PropertyBlob properties[]; FunctionBlob methods[]; @@ -1005,9 +1005,9 @@ typedef struct { */ typedef struct { guint16 blob_type; - guint16 deprecated : 1; + guint16 deprecated : 1; guint16 reserved :15; - guint32 name; + guint32 name; SimpleTypeBlob type; From 591e74061155590ff0463e8b609b95f8023accda Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 25 Mar 2010 09:17:03 -0300 Subject: [PATCH 265/692] Remove trailing whitespace --- girnode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girnode.c b/girnode.c index 43bdfa631..afe391319 100644 --- a/girnode.c +++ b/girnode.c @@ -1967,7 +1967,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->blob_type = BLOB_TYPE_UNION; blob->deprecated = union_->deprecated; - blob->reserved = 0; + blob->reserved = 0; blob->name = write_string (node->name, strings, data, offset2); blob->alignment = union_->alignment; blob->size = union_->size; From d9e0c19ce2fa4d3fe05a3e7c3b34ff28d21c2a5b Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 25 Mar 2010 09:17:20 -0300 Subject: [PATCH 266/692] Remove unused file girwriter.c --- girwriter.c | 532 ---------------------------------------------------- 1 file changed, 532 deletions(-) delete mode 100644 girwriter.c diff --git a/girwriter.c b/girwriter.c deleted file mode 100644 index 2d18d1453..000000000 --- a/girwriter.c +++ /dev/null @@ -1,532 +0,0 @@ -/* GObject introspection: gen-introspect - * - * Copyright (C) 2007 Jürg Billeter - * Copyright (C) 2007 Johan Dahlin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 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. - * - * Author: - * Jürg Billeter - */ - -#include -#include -#include "scanner.h" -#include "gidlnode.h" - -typedef struct { - int indent; - FILE *output; -} GIdlWriter; - -static void node_generate (GIdlWriter * writer, GIdlNode * node); - -static void -g_writer_write_inline (GIdlWriter * writer, const char *s) -{ - fprintf (writer->output, "%s", s); -} - -static void -g_writer_write (GIdlWriter * writer, const char *s) -{ - int i; - for (i = 0; i < writer->indent; i++) - { - fprintf (writer->output, "\t"); - } - - g_writer_write_inline (writer, s); -} - -static void -g_writer_write_indent (GIdlWriter * writer, const char *s) -{ - g_writer_write (writer, s); - writer->indent++; -} - -static void -g_writer_write_unindent (GIdlWriter * writer, const char *s) -{ - writer->indent--; - g_writer_write (writer, s); -} - -static void -field_generate (GIdlWriter * writer, GIdlNodeField * node) -{ - char *markup = - g_markup_printf_escaped ("\n", - node->node.name, node->type->unparsed); - g_writer_write (writer, markup); - g_free (markup); -} - -static void -value_generate (GIdlWriter * writer, GIdlNodeValue * node) -{ - char *markup = - g_markup_printf_escaped ("\n", - node->node.name, node->value); - g_writer_write (writer, markup); - g_free (markup); -} - -static void -constant_generate (GIdlWriter * writer, GIdlNodeConstant * node) -{ - char *markup = - g_markup_printf_escaped - ("\n", node->node.name, - node->type->unparsed, node->value); - g_writer_write (writer, markup); - g_free (markup); -} - -static void -property_generate (GIdlWriter * writer, GIdlNodeProperty * node) -{ - char *markup = - g_markup_printf_escaped ("\n", - node->node.name, - node->type->unparsed, - node->readable ? "1" : "0", - node->writable ? "1" : "0", - node->construct ? "1" : "0", - node->construct_only ? "1" : "0"); - g_writer_write (writer, markup); - g_free (markup); -} - -static void -function_generate (GIdlWriter * writer, GIdlNodeFunction * node) -{ - const char *tag_name; - GString *markup_s; - gchar *markup; - - if (node->node.type == G_IR_NODE_CALLBACK) - tag_name = "callback"; - else if (node->is_constructor) - tag_name = "constructor"; - else if (node->is_method) - tag_name = "method"; - else - tag_name = "function"; - - markup_s = g_string_new ("<"); - g_string_append_printf (markup_s, - "%s name=\"%s\"", - tag_name, node->node.name); - - if (node->node.type != G_IR_NODE_CALLBACK) - g_string_append_printf (markup_s, - g_markup_printf_escaped (" symbol=\"%s\"", node->symbol)); - - if (node->deprecated) - g_string_append_printf (markup_s, " deprecated=\"1\""); - - g_string_append (markup_s, ">\n"); - - g_writer_write_indent (writer, markup_s->str); - g_string_free (markup_s, TRUE); - - markup_s = - g_string_new (g_markup_printf_escaped ("result->type->unparsed)); - - if (node->result->transfer) - g_string_append (markup_s, g_markup_printf_escaped (" transfer=\"full\"/>\n")); - else - g_string_append (markup_s, "/>\n"); - - g_writer_write (writer, markup_s->str); - g_string_free (markup_s, TRUE); - - if (node->parameters != NULL) - { - GList *l; - g_writer_write_indent (writer, "\n"); - for (l = node->parameters; l != NULL; l = l->next) - { - GIdlNodeParam *param = l->data; - const gchar *direction = g_idl_node_param_direction_string (param); - - markup_s = g_string_new ("node.name); - - g_string_append (markup_s, - g_markup_printf_escaped (" type=\"%s\"", - param->type->unparsed)); - - if (param->transfer) - g_string_append (markup_s, - g_markup_printf_escaped (" transfer=\"full\"")); - - if (param->allow_none) - g_string_append (markup_s, - g_markup_printf_escaped (" allow-none=\"1\"")); - - if (strcmp (direction, "in") != 0) - g_string_append (markup_s, - g_markup_printf_escaped (" direction=\"%s\"", - direction)); - - g_string_append (markup_s, "/>\n"); - - g_writer_write (writer, markup_s->str); - g_string_free (markup_s, TRUE); - } - g_writer_write_unindent (writer, "\n"); - } - markup = g_strdup_printf ("\n", tag_name); - g_writer_write_unindent (writer, markup); - g_free (markup); -} - -static void -vfunc_generate (GIdlWriter * writer, GIdlNodeVFunc * node) -{ - char *markup = - g_markup_printf_escaped ("\n", node->node.name); - g_writer_write_indent (writer, markup); - g_free (markup); - markup = - g_markup_printf_escaped ("\n", - node->result->type->unparsed); - g_writer_write (writer, markup); - g_free (markup); - if (node->parameters != NULL) - { - GList *l; - g_writer_write_indent (writer, "\n"); - for (l = node->parameters; l != NULL; l = l->next) - { - GIdlNodeParam *param = l->data; - markup = - g_markup_printf_escaped ("\n", - param->node.name, param->type->unparsed); - g_writer_write (writer, markup); - g_free (markup); - } - g_writer_write_unindent (writer, "\n"); - } - g_writer_write_unindent (writer, "\n"); -} - -static void -signal_generate (GIdlWriter * writer, GIdlNodeSignal * node) -{ - char *markup; - const char *when = "LAST"; - if (node->run_first) - { - when = "FIRST"; - } - else if (node->run_cleanup) - { - when = "CLEANUP"; - } - markup = - g_markup_printf_escaped ("\n", - node->node.name, when); - g_writer_write_indent (writer, markup); - g_free (markup); - markup = - g_markup_printf_escaped ("\n", - node->result->type->unparsed); - g_writer_write (writer, markup); - g_free (markup); - if (node->parameters != NULL) - { - GList *l; - g_writer_write_indent (writer, "\n"); - for (l = node->parameters; l != NULL; l = l->next) - { - GIdlNodeParam *param = l->data; - markup = - g_markup_printf_escaped ("\n", - param->node.name, param->type->unparsed); - g_writer_write (writer, markup); - g_free (markup); - } - g_writer_write_unindent (writer, "\n"); - } - g_writer_write_unindent (writer, "\n"); -} - -static void -interface_generate (GIdlWriter * writer, GIdlNodeInterface * node) -{ - GList *l; - char *markup; - if (node->node.type == G_IR_NODE_OBJECT) - { - markup = - g_markup_printf_escaped ("\n", - node->node.name, - node->parent, - node->gtype_name, - node->gtype_init); - } - else if (node->node.type == G_IR_NODE_INTERFACE) - { - markup = - g_markup_printf_escaped - ("\n", - node->node.name, node->gtype_name, node->gtype_init); - } - - g_writer_write_indent (writer, markup); - g_free (markup); - if (node->node.type == G_IR_NODE_OBJECT && node->interfaces != NULL) - { - GList *l; - g_writer_write_indent (writer, "\n"); - for (l = node->interfaces; l != NULL; l = l->next) - { - markup = - g_markup_printf_escaped ("\n", - (char *) l->data); - g_writer_write (writer, markup); - g_free (markup); - } - g_writer_write_unindent (writer, "\n"); - } - else if (node->node.type == G_IR_NODE_INTERFACE - && node->prerequisites != NULL) - { - GList *l; - g_writer_write_indent (writer, "\n"); - for (l = node->prerequisites; l != NULL; l = l->next) - { - markup = - g_markup_printf_escaped ("\n", - (char *) l->data); - g_writer_write (writer, markup); - g_free (markup); - } - g_writer_write_unindent (writer, "\n"); - } - - for (l = node->members; l != NULL; l = l->next) - { - node_generate (writer, l->data); - } - - if (node->node.type == G_IR_NODE_OBJECT) - { - g_writer_write_unindent (writer, "\n"); - } - else if (node->node.type == G_IR_NODE_INTERFACE) - { - g_writer_write_unindent (writer, "\n"); - } -} - -static void -struct_generate (GIdlWriter * writer, GIdlNodeStruct * node) -{ - GList *l; - char *markup = - g_markup_printf_escaped ("\n", node->node.name); - g_writer_write_indent (writer, markup); - g_free (markup); - for (l = node->members; l != NULL; l = l->next) - { - node_generate (writer, l->data); - } - g_writer_write_unindent (writer, "\n"); -} - -static void -union_generate (GIdlWriter * writer, GIdlNodeUnion * node) -{ - GList *l; - char *markup = - g_markup_printf_escaped ("\n", node->node.name); - g_writer_write_indent (writer, markup); - g_free (markup); - for (l = node->members; l != NULL; l = l->next) - { - node_generate (writer, l->data); - } - g_writer_write_unindent (writer, "\n"); -} - -static void -boxed_generate (GIdlWriter * writer, GIdlNodeBoxed * node) -{ - GList *l; - char *markup = - g_markup_printf_escaped - ("\n", - node->node.name, node->gtype_name, node->gtype_init); - g_writer_write_indent (writer, markup); - g_free (markup); - for (l = node->members; l != NULL; l = l->next) - { - node_generate (writer, l->data); - } - g_writer_write_unindent (writer, "\n"); -} - -static void -enum_generate (GIdlWriter * writer, GIdlNodeEnum * node) -{ - GList *l; - GString *markup_s; - char *markup; - const char *tag_name = NULL; - - if (node->node.type == G_IR_NODE_ENUM) - { - tag_name = "enum"; - } - else if (node->node.type == G_IR_NODE_FLAGS) - { - tag_name = "flags"; - } - - markup_s = g_string_new ("<"); - g_string_append_printf (markup_s, - "%s name=\"%s\"", - tag_name, node->node.name); - - if (node->gtype_name != NULL) - g_string_append_printf (markup_s, - g_markup_printf_escaped (" type-name=\"%s\"", node->gtype_name)); - - if (node->gtype_init != NULL) - g_string_append_printf (markup_s, - g_markup_printf_escaped (" get-type=\"%s\"", node->gtype_init)); - - if (node->deprecated) - g_string_append_printf (markup_s, " deprecated=\"1\""); - - g_string_append (markup_s, ">\n"); - - g_writer_write_indent (writer, markup_s->str); - g_string_free (markup_s, TRUE); - - for (l = node->values; l != NULL; l = l->next) - { - node_generate (writer, l->data); - } - - markup = g_strdup_printf ("\n", tag_name); - g_writer_write_unindent (writer, markup); - g_free (markup); -} - -static void -node_generate (GIdlWriter * writer, GIdlNode * node) -{ - switch (node->type) - { - case G_IR_NODE_FUNCTION: - case G_IR_NODE_CALLBACK: - function_generate (writer, (GIdlNodeFunction *) node); - break; - case G_IR_NODE_VFUNC: - vfunc_generate (writer, (GIdlNodeVFunc *) node); - break; - case G_IR_NODE_OBJECT: - case G_IR_NODE_INTERFACE: - interface_generate (writer, (GIdlNodeInterface *) node); - break; - case G_IR_NODE_STRUCT: - struct_generate (writer, (GIdlNodeStruct *) node); - break; - case G_IR_NODE_UNION: - union_generate (writer, (GIdlNodeUnion *) node); - break; - case G_IR_NODE_BOXED: - boxed_generate (writer, (GIdlNodeBoxed *) node); - break; - case G_IR_NODE_ENUM: - case G_IR_NODE_FLAGS: - enum_generate (writer, (GIdlNodeEnum *) node); - break; - case G_IR_NODE_PROPERTY: - property_generate (writer, (GIdlNodeProperty *) node); - break; - case G_IR_NODE_FIELD: - field_generate (writer, (GIdlNodeField *) node); - break; - case G_IR_NODE_SIGNAL: - signal_generate (writer, (GIdlNodeSignal *) node); - break; - case G_IR_NODE_VALUE: - value_generate (writer, (GIdlNodeValue *) node); - break; - case G_IR_NODE_CONSTANT: - constant_generate (writer, (GIdlNodeConstant *) node); - break; - default: - g_assert_not_reached (); - } -} - -static void -g_writer_write_module (GIdlWriter * writer, GIdlModule * module) -{ - GList *l; - char *markup = - g_markup_printf_escaped ("\n", module->name); - g_writer_write_indent (writer, markup); - g_free (markup); - for (l = module->entries; l != NULL; l = l->next) - { - node_generate (writer, l->data); - } - g_writer_write_unindent (writer, "\n"); -} - -void -g_idl_writer_save_file (GIdlModule *module, - const gchar *filename) -{ - GIdlWriter *writer; - - writer = g_new0 (GIdlWriter, 1); - - if (!filename) - writer->output = stdout; - else - writer->output = fopen (filename, "w"); - - g_writer_write (writer, "\n"); - g_writer_write_indent (writer, ""); - g_writer_write_module (writer, module); - g_writer_write_unindent (writer, "\n"); - - if (filename) - fclose (writer->output); -} From 3b91df6678b1163dbff8287dd3940a4efb8ec261 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Wed, 24 Mar 2010 15:20:14 -0300 Subject: [PATCH 267/692] [typelib] Remove space/indent mismatch --- ginfo.c | 10 +++++----- girnode.c | 14 +++++++------- gtypelib.h | 10 +++++----- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/ginfo.c b/ginfo.c index 2d777e3ef..e39361794 100644 --- a/ginfo.c +++ b/ginfo.c @@ -619,8 +619,8 @@ signature_offset (GICallableInfo *info) GITypeInfo * g_type_info_new (GIBaseInfo *container, - GTypelib *typelib, - guint32 offset) + GTypelib *typelib, + guint32 offset) { SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset]; @@ -758,7 +758,7 @@ g_callable_info_get_n_args (GICallableInfo *info) */ GIArgInfo * g_callable_info_get_arg (GICallableInfo *info, - gint n) + gint n) { GIRealInfo *rinfo = (GIRealInfo *)info; Header *header = (Header *)rinfo->typelib->data; @@ -767,7 +767,7 @@ g_callable_info_get_arg (GICallableInfo *info, offset = signature_offset (info); return (GIArgInfo *) g_info_new (GI_INFO_TYPE_ARG, (GIBaseInfo*)info, rinfo->typelib, - offset + header->signature_blob_size + n * header->arg_blob_size); + offset + header->signature_blob_size + n * header->arg_blob_size); } /** @@ -1351,7 +1351,7 @@ find_method (GIBaseInfo *base, if (strcmp (name, fname) == 0) return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, - rinfo->typelib, offset); + rinfo->typelib, offset); offset += header->function_blob_size; } diff --git a/girnode.c b/girnode.c index afe391319..456ab7388 100644 --- a/girnode.c +++ b/girnode.c @@ -1644,9 +1644,9 @@ g_ir_node_build_typelib (GIrNode *node, 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->writable = prop->writable; + blob->construct = prop->construct; + blob->construct_only = prop->construct_only; blob->reserved = 0; g_ir_node_build_typelib ((GIrNode *)prop->type, @@ -1860,10 +1860,10 @@ g_ir_node_build_typelib (GIrNode *node, */ *offset += sizeof (ArgBlob) - sizeof (SimpleTypeBlob); - blob->name = write_string (node->name, strings, data, offset2); - blob->in = param->in; - blob->out = param->out; - blob->dipper = param->dipper; + blob->name = write_string (node->name, strings, data, offset2); + blob->in = param->in; + blob->out = param->out; + blob->dipper = param->dipper; blob->allow_none = param->allow_none; blob->optional = param->optional; blob->transfer_ownership = param->transfer; diff --git a/gtypelib.h b/gtypelib.h index 99d4472c8..a69bccf0d 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -556,12 +556,12 @@ typedef struct { * */ typedef struct { - guint8 pointer :1; - guint8 reserved :2; - guint8 tag :5; + guint8 pointer :1; + guint8 reserved :2; + guint8 tag :5; - guint8 reserved2; - guint16 n_types; + guint8 reserved2; + guint16 n_types; SimpleTypeBlob type[]; } ParamTypeBlob; From 14f13c1760058f183d1225402f550bb9695be712 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 25 Mar 2010 23:12:12 -0300 Subject: [PATCH 268/692] Add support for foreign structs Foreign structs are special in the sense that there might be native bindings (for instance PyCairo for PyGI) that provides the same functionallity as the introspected variant. https://bugzilla.gnome.org/show_bug.cgi?id=610357 --- ginfo.c | 9 +++++++++ girepository.h | 1 + girnode.c | 1 + girnode.h | 1 + girparser.c | 4 ++++ gtypelib.h | 5 ++++- 6 files changed, 20 insertions(+), 1 deletion(-) diff --git a/ginfo.c b/ginfo.c index e39361794..724109feb 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1392,6 +1392,15 @@ g_struct_info_get_alignment (GIStructInfo *info) return blob->alignment; } +gboolean +g_struct_info_is_foreign (GIStructInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->foreign; +} + /** * g_struct_info_is_gtype_struct: * @info: GIStructInfo diff --git a/girepository.h b/girepository.h index 083b11c06..cfa5b3906 100644 --- a/girepository.h +++ b/girepository.h @@ -461,6 +461,7 @@ GIFunctionInfo * g_struct_info_find_method (GIStructInfo *info, gsize g_struct_info_get_size (GIStructInfo *info); gsize g_struct_info_get_alignment (GIStructInfo *info); gboolean g_struct_info_is_gtype_struct (GIStructInfo *info); +gboolean g_struct_info_is_foreign (GIStructInfo *info); /* GIRegisteredTypeInfo */ diff --git a/girnode.c b/girnode.c index 456ab7388..1694406da 100644 --- a/girnode.c +++ b/girnode.c @@ -1885,6 +1885,7 @@ g_ir_node_build_typelib (GIrNode *node, GList *members; blob->blob_type = BLOB_TYPE_STRUCT; + blob->foreign = struct_->foreign; blob->deprecated = struct_->deprecated; blob->is_gtype_struct = struct_->is_gtype_struct; blob->reserved = 0; diff --git a/girnode.h b/girnode.h index 148488477..7fe235b89 100644 --- a/girnode.h +++ b/girnode.h @@ -312,6 +312,7 @@ struct _GIrNodeStruct gboolean deprecated; gboolean disguised; gboolean is_gtype_struct; + gboolean foreign; gchar *gtype_name; gchar *gtype_init; diff --git a/girparser.c b/girparser.c index 12c1d9890..5b24604af 100644 --- a/girparser.c +++ b/girparser.c @@ -2201,6 +2201,7 @@ start_struct (GMarkupParseContext *context, const gchar *gtype_name; const gchar *gtype_init; const gchar *gtype_struct; + const gchar *foreign; GIrNodeStruct *struct_; name = find_attribute ("name", attribute_names, attribute_values); @@ -2209,6 +2210,7 @@ start_struct (GMarkupParseContext *context, gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values); gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values); gtype_struct = find_attribute ("glib:is-gtype-struct-for", attribute_names, attribute_values); + foreign = find_attribute ("foreign", attribute_names, attribute_values); if (name == NULL && ctx->node_stack == NULL) { @@ -2242,6 +2244,8 @@ start_struct (GMarkupParseContext *context, struct_->gtype_name = g_strdup (gtype_name); struct_->gtype_init = g_strdup (gtype_init); + struct_->foreign = (g_strcmp0 (foreign, "1") == 0); + if (ctx->node_stack == NULL) ctx->current_module->entries = g_list_append (ctx->current_module->entries, struct_); diff --git a/gtypelib.h b/gtypelib.h index a69bccf0d..14edc9841 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -669,6 +669,8 @@ typedef struct { * @unregistered: If this is set, the type is not registered with GType. * @alignment: The byte boundary that the struct is aligned to in memory * @is_gtype_struct: Whether this structure is the class or interface layout for a GObject + * @foreign: If the type is foreign, eg if it's expected to be overridden by + * a native language binding instead of relying of introspected bindings. * @size: The size of the struct in bytes. * @gtype_name: String name of the associated #GType * @gtype_init: String naming the symbol which gets the runtime #GType @@ -685,7 +687,8 @@ typedef struct { guint16 unregistered : 1; guint16 is_gtype_struct : 1; guint16 alignment : 6; - guint16 reserved : 7; + guint16 foreign : 1; + guint16 reserved : 6; guint32 name; From 24363834ffc87e377125eb524eeeb9e9dd93c469 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Mon, 5 Apr 2010 14:05:52 -0400 Subject: [PATCH 269/692] g_callable_info_prepare_closure: handle mmap permissions error When SELinux or similar is active, a process may not be able to mmap() a segment that is both writable and executable, which would causing g_callable_info_prepare_closure() to fail. Libffi has a workaround for this problem though (it maps the same non-anonymous region twice, once writable and once executable, and returns two separate pointers to it), so use that. https://bugzilla.gnome.org/show_bug.cgi?id=614903 --- girffi.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/girffi.c b/girffi.c index 88cafec90..616f59a2e 100644 --- a/girffi.c +++ b/girffi.c @@ -297,6 +297,11 @@ g_function_invoker_destroy (GIFunctionInvoker *invoker) g_free (invoker->cif.arg_types); } +typedef struct { + ffi_closure ffi_closure; + gpointer writable_self; +} GIClosureWrapper; + /** * g_callable_info_prepare_closure: * @callable_info: a callable info from a typelib @@ -306,11 +311,8 @@ g_function_invoker_destroy (GIFunctionInvoker *invoker) * * Prepares a callback for ffi invocation. * - * Note: this function requires the heap to be executable, which - * might not function properly on systems with SELinux enabled. - * * Return value: the ffi_closure or NULL on error. - * The return value should be freed by calling g_callable_info_prepare_closure(). + * The return value should be freed by calling g_callable_info_free_closure(). */ ffi_closure * g_callable_info_prepare_closure (GICallableInfo *callable_info, @@ -318,21 +320,21 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, GIFFIClosureCallback callback, gpointer user_data) { - ffi_closure *closure; + gpointer exec_ptr; + GIClosureWrapper *closure; ffi_status status; g_return_val_if_fail (callable_info != NULL, FALSE); g_return_val_if_fail (cif != NULL, FALSE); g_return_val_if_fail (callback != NULL, FALSE); - closure = mmap (NULL, sizeof (ffi_closure), - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_ANON | MAP_PRIVATE, -1, sysconf (_SC_PAGE_SIZE)); + closure = ffi_closure_alloc (sizeof (GIClosureWrapper), &exec_ptr); if (!closure) { - g_warning("mmap failed: %s\n", strerror(errno)); + g_warning ("could not allocate closure\n"); return NULL; } + closure->writable_self = closure; status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, g_callable_info_get_n_args (callable_info), @@ -340,27 +342,23 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, g_callable_info_get_ffi_arg_types (callable_info)); if (status != FFI_OK) { - g_warning("ffi_prep_cif failed: %d\n", status); - munmap(closure, sizeof (closure)); + g_warning ("ffi_prep_cif failed: %d\n", status); + ffi_closure_free (closure); return NULL; } - status = ffi_prep_closure (closure, cif, callback, user_data); + status = ffi_prep_closure (&closure->ffi_closure, cif, callback, user_data); if (status != FFI_OK) { g_warning ("ffi_prep_closure failed: %d\n", status); - munmap(closure, sizeof (closure)); + ffi_closure_free (closure); return NULL; } - if (mprotect(closure, sizeof (closure), PROT_READ | PROT_EXEC) == -1) - { - g_warning ("ffi_prep_closure failed: %s\n", strerror(errno)); - munmap(closure, sizeof (closure)); - return NULL; - } - - return closure; + /* Return exec_ptr, which points to the same underlying memory as + * closure, but via an executable-non-writable mapping. + */ + return exec_ptr; } /** @@ -374,5 +372,7 @@ void g_callable_info_free_closure (GICallableInfo *callable_info, ffi_closure *closure) { - munmap(closure, sizeof (closure)); + GIClosureWrapper *wrapper = (GIClosureWrapper *)closure; + + ffi_closure_free (wrapper->writable_self); } From 611929ec55dbfb55eb6757bad16a5f43bb3fb2c0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 18 Mar 2010 17:46:56 -0400 Subject: [PATCH 270/692] [giroffsets] Also update this code for change to signed enumeration values --- giroffsets.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/giroffsets.c b/giroffsets.c index ab9bde0b4..7a5e70116 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -67,7 +67,7 @@ static void compute_enum_storage_type (GIrNodeEnum *enum_node) { GList *l; - guint32 max_value = 0; + gint32 max_value = 0; int width; if (enum_node->storage_type != GI_TYPE_TAG_VOID) /* already done */ @@ -77,7 +77,7 @@ compute_enum_storage_type (GIrNodeEnum *enum_node) { GIrNodeValue *value = l->data; if (value->value > max_value) - max_value = value->value; + max_value = value->value; } if (max_value < 128) From 6545640515ebc407b5721279062314e26b46f295 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 7 Apr 2010 15:20:48 -0400 Subject: [PATCH 271/692] Revert "g_callable_info_prepare_closure: handle mmap permissions error" This reverts commit ed8634ddf73a56cb1935fd87254b3c6c04352893. This commit caused crashes in gjs/gnome-shell, which we're still trying to track down. See: http://bugzilla.gnome.org/615078 --- girffi.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/girffi.c b/girffi.c index 616f59a2e..88cafec90 100644 --- a/girffi.c +++ b/girffi.c @@ -297,11 +297,6 @@ g_function_invoker_destroy (GIFunctionInvoker *invoker) g_free (invoker->cif.arg_types); } -typedef struct { - ffi_closure ffi_closure; - gpointer writable_self; -} GIClosureWrapper; - /** * g_callable_info_prepare_closure: * @callable_info: a callable info from a typelib @@ -311,8 +306,11 @@ typedef struct { * * Prepares a callback for ffi invocation. * + * Note: this function requires the heap to be executable, which + * might not function properly on systems with SELinux enabled. + * * Return value: the ffi_closure or NULL on error. - * The return value should be freed by calling g_callable_info_free_closure(). + * The return value should be freed by calling g_callable_info_prepare_closure(). */ ffi_closure * g_callable_info_prepare_closure (GICallableInfo *callable_info, @@ -320,21 +318,21 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, GIFFIClosureCallback callback, gpointer user_data) { - gpointer exec_ptr; - GIClosureWrapper *closure; + ffi_closure *closure; ffi_status status; g_return_val_if_fail (callable_info != NULL, FALSE); g_return_val_if_fail (cif != NULL, FALSE); g_return_val_if_fail (callback != NULL, FALSE); - closure = ffi_closure_alloc (sizeof (GIClosureWrapper), &exec_ptr); + closure = mmap (NULL, sizeof (ffi_closure), + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, sysconf (_SC_PAGE_SIZE)); if (!closure) { - g_warning ("could not allocate closure\n"); + g_warning("mmap failed: %s\n", strerror(errno)); return NULL; } - closure->writable_self = closure; status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, g_callable_info_get_n_args (callable_info), @@ -342,23 +340,27 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, g_callable_info_get_ffi_arg_types (callable_info)); if (status != FFI_OK) { - g_warning ("ffi_prep_cif failed: %d\n", status); - ffi_closure_free (closure); + g_warning("ffi_prep_cif failed: %d\n", status); + munmap(closure, sizeof (closure)); return NULL; } - status = ffi_prep_closure (&closure->ffi_closure, cif, callback, user_data); + status = ffi_prep_closure (closure, cif, callback, user_data); if (status != FFI_OK) { g_warning ("ffi_prep_closure failed: %d\n", status); - ffi_closure_free (closure); + munmap(closure, sizeof (closure)); return NULL; } - /* Return exec_ptr, which points to the same underlying memory as - * closure, but via an executable-non-writable mapping. - */ - return exec_ptr; + if (mprotect(closure, sizeof (closure), PROT_READ | PROT_EXEC) == -1) + { + g_warning ("ffi_prep_closure failed: %s\n", strerror(errno)); + munmap(closure, sizeof (closure)); + return NULL; + } + + return closure; } /** @@ -372,7 +374,5 @@ void g_callable_info_free_closure (GICallableInfo *callable_info, ffi_closure *closure) { - GIClosureWrapper *wrapper = (GIClosureWrapper *)closure; - - ffi_closure_free (wrapper->writable_self); + munmap(closure, sizeof (closure)); } From 9d2fd90f0aecdeabc22133dc6722209956a19520 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Wed, 7 Apr 2010 17:48:52 -0400 Subject: [PATCH 272/692] Correctly use ffi_closure_alloc(), fixing mmap permissions error This restores the reverted-commit ed8634d: Author: Dan Winship Date: Mon Apr 5 14:05:52 2010 -0400 g_callable_info_prepare_closure: handle mmap permissions error When SELinux or similar is active, a process may not be able to mmap() a segment that is both writable and executable, which would causing g_callable_info_prepare_closure() to fail. Libffi has a workaround for this problem though (it maps the same non-anonymous region twice, once writable and once executable, and returns two separate pointers to it), so use that. But with an added fix, when using ffi_closure_alloc(), we need to use ffi_prep_closure_loc() so we can pass in the executable address of the trampoline separately from the writable address, rather than the deprecated ffi_prep_closure(). https://bugzilla.gnome.org/show_bug.cgi?id=615105 --- girffi.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/girffi.c b/girffi.c index 88cafec90..3f0b67058 100644 --- a/girffi.c +++ b/girffi.c @@ -297,6 +297,11 @@ g_function_invoker_destroy (GIFunctionInvoker *invoker) g_free (invoker->cif.arg_types); } +typedef struct { + ffi_closure ffi_closure; + gpointer writable_self; +} GIClosureWrapper; + /** * g_callable_info_prepare_closure: * @callable_info: a callable info from a typelib @@ -306,11 +311,8 @@ g_function_invoker_destroy (GIFunctionInvoker *invoker) * * Prepares a callback for ffi invocation. * - * Note: this function requires the heap to be executable, which - * might not function properly on systems with SELinux enabled. - * * Return value: the ffi_closure or NULL on error. - * The return value should be freed by calling g_callable_info_prepare_closure(). + * The return value should be freed by calling g_callable_info_free_closure(). */ ffi_closure * g_callable_info_prepare_closure (GICallableInfo *callable_info, @@ -318,21 +320,21 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, GIFFIClosureCallback callback, gpointer user_data) { - ffi_closure *closure; + gpointer exec_ptr; + GIClosureWrapper *closure; ffi_status status; g_return_val_if_fail (callable_info != NULL, FALSE); g_return_val_if_fail (cif != NULL, FALSE); g_return_val_if_fail (callback != NULL, FALSE); - closure = mmap (NULL, sizeof (ffi_closure), - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_ANON | MAP_PRIVATE, -1, sysconf (_SC_PAGE_SIZE)); + closure = ffi_closure_alloc (sizeof (GIClosureWrapper), &exec_ptr); if (!closure) { - g_warning("mmap failed: %s\n", strerror(errno)); + g_warning ("could not allocate closure\n"); return NULL; } + closure->writable_self = closure; status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, g_callable_info_get_n_args (callable_info), @@ -340,27 +342,23 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, g_callable_info_get_ffi_arg_types (callable_info)); if (status != FFI_OK) { - g_warning("ffi_prep_cif failed: %d\n", status); - munmap(closure, sizeof (closure)); + g_warning ("ffi_prep_cif failed: %d\n", status); + ffi_closure_free (closure); return NULL; } - status = ffi_prep_closure (closure, cif, callback, user_data); + status = ffi_prep_closure_loc (&closure->ffi_closure, cif, callback, user_data, exec_ptr); if (status != FFI_OK) { g_warning ("ffi_prep_closure failed: %d\n", status); - munmap(closure, sizeof (closure)); + ffi_closure_free (closure); return NULL; } - if (mprotect(closure, sizeof (closure), PROT_READ | PROT_EXEC) == -1) - { - g_warning ("ffi_prep_closure failed: %s\n", strerror(errno)); - munmap(closure, sizeof (closure)); - return NULL; - } - - return closure; + /* Return exec_ptr, which points to the same underlying memory as + * closure, but via an executable-non-writable mapping. + */ + return exec_ptr; } /** @@ -374,5 +372,7 @@ void g_callable_info_free_closure (GICallableInfo *callable_info, ffi_closure *closure) { - munmap(closure, sizeof (closure)); + GIClosureWrapper *wrapper = (GIClosureWrapper *)closure; + + ffi_closure_free (wrapper->writable_self); } From e12cea0a534b14802dbd591d22ed7f259f91bcc8 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Fri, 30 Apr 2010 18:15:23 +0200 Subject: [PATCH 273/692] Add support for GArrays: add g_type_info_get_array_type() and properly scan GArray args Based on a previous patch by C. Scott Ananian https://bugzilla.gnome.org/show_bug.cgi?id=581687 --- ginfo.c | 17 +++++++++++++++++ girepository.h | 8 ++++++++ girnode.c | 1 + girnode.h | 1 + girparser.c | 44 +++++++++++++++++++++++++++++++------------- gtypelib.h | 8 +++++++- 6 files changed, 65 insertions(+), 14 deletions(-) diff --git a/ginfo.c b/ginfo.c index 724109feb..1d56a22a0 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1093,6 +1093,23 @@ g_type_info_is_zero_terminated (GITypeInfo *info) return FALSE; } +GIArrayType +g_type_info_get_array_type (GITypeInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) + { + ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + g_return_val_if_fail (blob->tag == GI_TYPE_TAG_ARRAY, -1); + + return blob->array_type; + } + + return -1; +} + gint g_type_info_get_n_error_domains (GITypeInfo *info) { diff --git a/girepository.h b/girepository.h index cfa5b3906..9e62ab153 100644 --- a/girepository.h +++ b/girepository.h @@ -383,6 +383,13 @@ typedef enum { * See docs/typelib-format.txt SimpleTypeBlob definition */ } GITypeTag; +typedef enum { + GI_ARRAY_TYPE_C, + GI_ARRAY_TYPE_ARRAY, + GI_ARRAY_TYPE_PTR_ARRAY, + GI_ARRAY_TYPE_BYTE_ARRAY +} GIArrayType; + #define G_TYPE_TAG_IS_BASIC(tag) (tag < GI_TYPE_TAG_ARRAY) const gchar* g_type_tag_to_string (GITypeTag type); @@ -395,6 +402,7 @@ GIBaseInfo * g_type_info_get_interface (GITypeInfo *info); gint g_type_info_get_array_length (GITypeInfo *info); gint g_type_info_get_array_fixed_size(GITypeInfo *info); gboolean g_type_info_is_zero_terminated (GITypeInfo *info); +GIArrayType g_type_info_get_array_type (GITypeInfo *info); gint g_type_info_get_n_error_domains (GITypeInfo *info); GIErrorDomainInfo *g_type_info_get_error_domain (GITypeInfo *info, diff --git a/girnode.c b/girnode.c index 1694406da..6f4a44af9 100644 --- a/girnode.c +++ b/girnode.c @@ -1497,6 +1497,7 @@ g_ir_node_build_typelib (GIrNode *node, array->zero_terminated = type->zero_terminated; array->has_length = type->has_length; array->has_size = type->has_size; + array->array_type = type->array_type; array->reserved2 = 0; if (array->has_length) array->dimensions.length = type->length; diff --git a/girnode.h b/girnode.h index 7fe235b89..5e6cba035 100644 --- a/girnode.h +++ b/girnode.h @@ -138,6 +138,7 @@ struct _GIrNodeType gint length; gboolean has_size; gint size; + gint array_type; GIrNodeType *parameter_type1; GIrNodeType *parameter_type2; diff --git a/girparser.c b/girparser.c index 5b24604af..85f85e219 100644 --- a/girparser.c +++ b/girparser.c @@ -1717,22 +1717,40 @@ start_type (GMarkupParseContext *context, typenode->is_pointer = TRUE; typenode->is_array = TRUE; - zero = find_attribute ("zero-terminated", attribute_names, attribute_values); - len = find_attribute ("length", attribute_names, attribute_values); - size = find_attribute ("fixed-size", attribute_names, attribute_values); + ctype = find_attribute ("c:type", attribute_names, attribute_values); + if (g_str_has_prefix (ctype, "GArray")) { + typenode->array_type = GI_ARRAY_TYPE_ARRAY; + } else if (g_str_has_prefix (ctype, "GByteArray")) { + typenode->array_type = GI_ARRAY_TYPE_BYTE_ARRAY; + } else if (g_str_has_prefix (ctype, "GPtrArray")) { + typenode->array_type = GI_ARRAY_TYPE_PTR_ARRAY; + } else { + typenode->array_type = GI_ARRAY_TYPE_C; + } - typenode->zero_terminated = !(zero && strcmp (zero, "1") != 0); - typenode->has_length = len != NULL; - typenode->length = typenode->has_length ? atoi (len) : -1; + if (typenode->array_type == GI_ARRAY_TYPE_C) { + zero = find_attribute ("zero-terminated", attribute_names, attribute_values); + len = find_attribute ("length", attribute_names, attribute_values); + size = find_attribute ("fixed-size", attribute_names, attribute_values); - typenode->has_size = size != NULL; - typenode->size = typenode->has_size ? atoi (size) : -1; + typenode->has_length = len != NULL; + typenode->length = typenode->has_length ? atoi (len) : -1; - if (zero) - typenode->zero_terminated = strcmp(zero, "1") == 0; - else - /* If neither zero-terminated nor length nor fixed-size is given, assume zero-terminated. */ - typenode->zero_terminated = !(typenode->has_length || typenode->has_size); + typenode->has_size = size != NULL; + typenode->size = typenode->has_size ? atoi (size) : -1; + + if (zero) + typenode->zero_terminated = strcmp(zero, "1") == 0; + else + /* If neither zero-terminated nor length nor fixed-size is given, assume zero-terminated. */ + typenode->zero_terminated = !(typenode->has_length || typenode->has_size); + } else { + typenode->zero_terminated = FALSE; + typenode->has_length = FALSE; + typenode->length = -1; + typenode->has_size = FALSE; + typenode->size = -1; + } } else { diff --git a/gtypelib.h b/gtypelib.h index 14edc9841..820801498 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -524,9 +524,14 @@ typedef struct { * of the array. If both has_length and zero_terminated are set, the * convention is to pass -1 for the length if the array is * zero-terminated. + * @has_size: Indicates that size is the fixed size of the array. + * @array_type: Indicates whether this is a C array, GArray, GPtrArray, or + * GByteArray. If something other than a C array, the length and element size + * are implicit in the structure. * @length: The index of the parameter which is used to pass the length of the * array. The parameter must be an integer type and have the same * direction as this one. + * @size: The fixed size of the array. * @type: The type of the array elements. * * Arrays are passed by reference, thus is_pointer is always 1. @@ -539,7 +544,8 @@ typedef struct { guint16 zero_terminated :1; guint16 has_length :1; guint16 has_size :1; - guint16 reserved2 :5; + guint16 array_type :2; + guint16 reserved2 :3; union { guint16 length; From 1301850f3dab7a91cf2cbee3aed57ea635c7239f Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 3 May 2010 19:17:00 +0200 Subject: [PATCH 274/692] Revert "Add support for GArrays: add g_type_info_get_array_type() and properly scan GArray args" This reverts commit 87291e08b0fd34b62e1ad9811c174108b38311a9. --- ginfo.c | 17 ----------------- girepository.h | 8 -------- girnode.c | 1 - girnode.h | 1 - girparser.c | 44 +++++++++++++------------------------------- gtypelib.h | 8 +------- 6 files changed, 14 insertions(+), 65 deletions(-) diff --git a/ginfo.c b/ginfo.c index 1d56a22a0..724109feb 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1093,23 +1093,6 @@ g_type_info_is_zero_terminated (GITypeInfo *info) return FALSE; } -GIArrayType -g_type_info_get_array_type (GITypeInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) - { - ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - g_return_val_if_fail (blob->tag == GI_TYPE_TAG_ARRAY, -1); - - return blob->array_type; - } - - return -1; -} - gint g_type_info_get_n_error_domains (GITypeInfo *info) { diff --git a/girepository.h b/girepository.h index 9e62ab153..cfa5b3906 100644 --- a/girepository.h +++ b/girepository.h @@ -383,13 +383,6 @@ typedef enum { * See docs/typelib-format.txt SimpleTypeBlob definition */ } GITypeTag; -typedef enum { - GI_ARRAY_TYPE_C, - GI_ARRAY_TYPE_ARRAY, - GI_ARRAY_TYPE_PTR_ARRAY, - GI_ARRAY_TYPE_BYTE_ARRAY -} GIArrayType; - #define G_TYPE_TAG_IS_BASIC(tag) (tag < GI_TYPE_TAG_ARRAY) const gchar* g_type_tag_to_string (GITypeTag type); @@ -402,7 +395,6 @@ GIBaseInfo * g_type_info_get_interface (GITypeInfo *info); gint g_type_info_get_array_length (GITypeInfo *info); gint g_type_info_get_array_fixed_size(GITypeInfo *info); gboolean g_type_info_is_zero_terminated (GITypeInfo *info); -GIArrayType g_type_info_get_array_type (GITypeInfo *info); gint g_type_info_get_n_error_domains (GITypeInfo *info); GIErrorDomainInfo *g_type_info_get_error_domain (GITypeInfo *info, diff --git a/girnode.c b/girnode.c index 6f4a44af9..1694406da 100644 --- a/girnode.c +++ b/girnode.c @@ -1497,7 +1497,6 @@ g_ir_node_build_typelib (GIrNode *node, array->zero_terminated = type->zero_terminated; array->has_length = type->has_length; array->has_size = type->has_size; - array->array_type = type->array_type; array->reserved2 = 0; if (array->has_length) array->dimensions.length = type->length; diff --git a/girnode.h b/girnode.h index 5e6cba035..7fe235b89 100644 --- a/girnode.h +++ b/girnode.h @@ -138,7 +138,6 @@ struct _GIrNodeType gint length; gboolean has_size; gint size; - gint array_type; GIrNodeType *parameter_type1; GIrNodeType *parameter_type2; diff --git a/girparser.c b/girparser.c index 85f85e219..5b24604af 100644 --- a/girparser.c +++ b/girparser.c @@ -1717,40 +1717,22 @@ start_type (GMarkupParseContext *context, typenode->is_pointer = TRUE; typenode->is_array = TRUE; - ctype = find_attribute ("c:type", attribute_names, attribute_values); - if (g_str_has_prefix (ctype, "GArray")) { - typenode->array_type = GI_ARRAY_TYPE_ARRAY; - } else if (g_str_has_prefix (ctype, "GByteArray")) { - typenode->array_type = GI_ARRAY_TYPE_BYTE_ARRAY; - } else if (g_str_has_prefix (ctype, "GPtrArray")) { - typenode->array_type = GI_ARRAY_TYPE_PTR_ARRAY; - } else { - typenode->array_type = GI_ARRAY_TYPE_C; - } + zero = find_attribute ("zero-terminated", attribute_names, attribute_values); + len = find_attribute ("length", attribute_names, attribute_values); + size = find_attribute ("fixed-size", attribute_names, attribute_values); - if (typenode->array_type == GI_ARRAY_TYPE_C) { - zero = find_attribute ("zero-terminated", attribute_names, attribute_values); - len = find_attribute ("length", attribute_names, attribute_values); - size = find_attribute ("fixed-size", attribute_names, attribute_values); + typenode->zero_terminated = !(zero && strcmp (zero, "1") != 0); + typenode->has_length = len != NULL; + typenode->length = typenode->has_length ? atoi (len) : -1; - typenode->has_length = len != NULL; - typenode->length = typenode->has_length ? atoi (len) : -1; + typenode->has_size = size != NULL; + typenode->size = typenode->has_size ? atoi (size) : -1; - typenode->has_size = size != NULL; - typenode->size = typenode->has_size ? atoi (size) : -1; - - if (zero) - typenode->zero_terminated = strcmp(zero, "1") == 0; - else - /* If neither zero-terminated nor length nor fixed-size is given, assume zero-terminated. */ - typenode->zero_terminated = !(typenode->has_length || typenode->has_size); - } else { - typenode->zero_terminated = FALSE; - typenode->has_length = FALSE; - typenode->length = -1; - typenode->has_size = FALSE; - typenode->size = -1; - } + if (zero) + typenode->zero_terminated = strcmp(zero, "1") == 0; + else + /* If neither zero-terminated nor length nor fixed-size is given, assume zero-terminated. */ + typenode->zero_terminated = !(typenode->has_length || typenode->has_size); } else { diff --git a/gtypelib.h b/gtypelib.h index 820801498..14edc9841 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -524,14 +524,9 @@ typedef struct { * of the array. If both has_length and zero_terminated are set, the * convention is to pass -1 for the length if the array is * zero-terminated. - * @has_size: Indicates that size is the fixed size of the array. - * @array_type: Indicates whether this is a C array, GArray, GPtrArray, or - * GByteArray. If something other than a C array, the length and element size - * are implicit in the structure. * @length: The index of the parameter which is used to pass the length of the * array. The parameter must be an integer type and have the same * direction as this one. - * @size: The fixed size of the array. * @type: The type of the array elements. * * Arrays are passed by reference, thus is_pointer is always 1. @@ -544,8 +539,7 @@ typedef struct { guint16 zero_terminated :1; guint16 has_length :1; guint16 has_size :1; - guint16 array_type :2; - guint16 reserved2 :3; + guint16 reserved2 :5; union { guint16 length; From c9213eaea3652a7f1aea3051e42d788839e28e68 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Tue, 4 May 2010 16:57:51 +0200 Subject: [PATCH 275/692] Add support for GArrays: add g_type_info_get_array_type() and properly scan GArray args Based on a previous patch by C. Scott Ananian https://bugzilla.gnome.org/show_bug.cgi?id=581687 --- ginfo.c | 17 +++++++++++++++++ girepository.h | 8 ++++++++ girnode.c | 1 + girnode.h | 1 + girparser.c | 44 +++++++++++++++++++++++++++++++------------- gtypelib.h | 8 +++++++- 6 files changed, 65 insertions(+), 14 deletions(-) diff --git a/ginfo.c b/ginfo.c index 724109feb..1d56a22a0 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1093,6 +1093,23 @@ g_type_info_is_zero_terminated (GITypeInfo *info) return FALSE; } +GIArrayType +g_type_info_get_array_type (GITypeInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) + { + ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + g_return_val_if_fail (blob->tag == GI_TYPE_TAG_ARRAY, -1); + + return blob->array_type; + } + + return -1; +} + gint g_type_info_get_n_error_domains (GITypeInfo *info) { diff --git a/girepository.h b/girepository.h index cfa5b3906..9e62ab153 100644 --- a/girepository.h +++ b/girepository.h @@ -383,6 +383,13 @@ typedef enum { * See docs/typelib-format.txt SimpleTypeBlob definition */ } GITypeTag; +typedef enum { + GI_ARRAY_TYPE_C, + GI_ARRAY_TYPE_ARRAY, + GI_ARRAY_TYPE_PTR_ARRAY, + GI_ARRAY_TYPE_BYTE_ARRAY +} GIArrayType; + #define G_TYPE_TAG_IS_BASIC(tag) (tag < GI_TYPE_TAG_ARRAY) const gchar* g_type_tag_to_string (GITypeTag type); @@ -395,6 +402,7 @@ GIBaseInfo * g_type_info_get_interface (GITypeInfo *info); gint g_type_info_get_array_length (GITypeInfo *info); gint g_type_info_get_array_fixed_size(GITypeInfo *info); gboolean g_type_info_is_zero_terminated (GITypeInfo *info); +GIArrayType g_type_info_get_array_type (GITypeInfo *info); gint g_type_info_get_n_error_domains (GITypeInfo *info); GIErrorDomainInfo *g_type_info_get_error_domain (GITypeInfo *info, diff --git a/girnode.c b/girnode.c index 1694406da..6f4a44af9 100644 --- a/girnode.c +++ b/girnode.c @@ -1497,6 +1497,7 @@ g_ir_node_build_typelib (GIrNode *node, array->zero_terminated = type->zero_terminated; array->has_length = type->has_length; array->has_size = type->has_size; + array->array_type = type->array_type; array->reserved2 = 0; if (array->has_length) array->dimensions.length = type->length; diff --git a/girnode.h b/girnode.h index 7fe235b89..5e6cba035 100644 --- a/girnode.h +++ b/girnode.h @@ -138,6 +138,7 @@ struct _GIrNodeType gint length; gboolean has_size; gint size; + gint array_type; GIrNodeType *parameter_type1; GIrNodeType *parameter_type2; diff --git a/girparser.c b/girparser.c index 5b24604af..125bd171b 100644 --- a/girparser.c +++ b/girparser.c @@ -1717,22 +1717,40 @@ start_type (GMarkupParseContext *context, typenode->is_pointer = TRUE; typenode->is_array = TRUE; - zero = find_attribute ("zero-terminated", attribute_names, attribute_values); - len = find_attribute ("length", attribute_names, attribute_values); - size = find_attribute ("fixed-size", attribute_names, attribute_values); + name = find_attribute ("name", attribute_names, attribute_values); + if (name && strcmp (name, "GLib.Array") == 0) { + typenode->array_type = GI_ARRAY_TYPE_ARRAY; + } else if (name && strcmp (name, "GLib.ByteArray") == 0) { + typenode->array_type = GI_ARRAY_TYPE_BYTE_ARRAY; + } else if (name && strcmp (name, "GLib.PtrArray") == 0) { + typenode->array_type = GI_ARRAY_TYPE_PTR_ARRAY; + } else { + typenode->array_type = GI_ARRAY_TYPE_C; + } - typenode->zero_terminated = !(zero && strcmp (zero, "1") != 0); - typenode->has_length = len != NULL; - typenode->length = typenode->has_length ? atoi (len) : -1; + if (typenode->array_type == GI_ARRAY_TYPE_C) { + zero = find_attribute ("zero-terminated", attribute_names, attribute_values); + len = find_attribute ("length", attribute_names, attribute_values); + size = find_attribute ("fixed-size", attribute_names, attribute_values); - typenode->has_size = size != NULL; - typenode->size = typenode->has_size ? atoi (size) : -1; + typenode->has_length = len != NULL; + typenode->length = typenode->has_length ? atoi (len) : -1; - if (zero) - typenode->zero_terminated = strcmp(zero, "1") == 0; - else - /* If neither zero-terminated nor length nor fixed-size is given, assume zero-terminated. */ - typenode->zero_terminated = !(typenode->has_length || typenode->has_size); + typenode->has_size = size != NULL; + typenode->size = typenode->has_size ? atoi (size) : -1; + + if (zero) + typenode->zero_terminated = strcmp(zero, "1") == 0; + else + /* If neither zero-terminated nor length nor fixed-size is given, assume zero-terminated. */ + typenode->zero_terminated = !(typenode->has_length || typenode->has_size); + } else { + typenode->zero_terminated = FALSE; + typenode->has_length = FALSE; + typenode->length = -1; + typenode->has_size = FALSE; + typenode->size = -1; + } } else { diff --git a/gtypelib.h b/gtypelib.h index 14edc9841..820801498 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -524,9 +524,14 @@ typedef struct { * of the array. If both has_length and zero_terminated are set, the * convention is to pass -1 for the length if the array is * zero-terminated. + * @has_size: Indicates that size is the fixed size of the array. + * @array_type: Indicates whether this is a C array, GArray, GPtrArray, or + * GByteArray. If something other than a C array, the length and element size + * are implicit in the structure. * @length: The index of the parameter which is used to pass the length of the * array. The parameter must be an integer type and have the same * direction as this one. + * @size: The fixed size of the array. * @type: The type of the array elements. * * Arrays are passed by reference, thus is_pointer is always 1. @@ -539,7 +544,8 @@ typedef struct { guint16 zero_terminated :1; guint16 has_length :1; guint16 has_size :1; - guint16 reserved2 :5; + guint16 array_type :2; + guint16 reserved2 :3; union { guint16 length; From 9f4cadec6041bf0ca064721d23f0c1f9c5c7cda0 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 18 May 2010 13:37:51 -0300 Subject: [PATCH 276/692] [girepository] Update gtk-doc syntax Update the gtk-doc syntax to remove a couple of warnings --- ginfo.c | 14 ++++++++------ girepository.c | 2 +- gtypelib.h | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/ginfo.c b/ginfo.c index 1d56a22a0..aab864d2b 100644 --- a/ginfo.c +++ b/ginfo.c @@ -30,7 +30,7 @@ typedef struct _GIRealInfo GIRealInfo; -/** +/* * We just use one structure for all of the info object * types; in general, we should be reading data directly * from the typelib, and not having computed data in @@ -437,7 +437,7 @@ find_first_attribute (GIRealInfo *rinfo) /** * g_base_info_iterate_attributes: * @info: A #GIBaseInfo - * @iter: A #GIAttributeIter structure, must be initialized; see below + * @iterator: A #GIAttributeIter structure, must be initialized; see below * @name: (out) (transfer none): Returned name, must not be freed * @value: (out) (transfer none): Returned name, must not be freed * @@ -469,7 +469,7 @@ find_first_attribute (GIRealInfo *rinfo) */ gboolean g_base_info_iterate_attributes (GIBaseInfo *info, - GIAttributeIter *iter, + GIAttributeIter *iterator, gchar **name, gchar **value) { @@ -480,8 +480,8 @@ g_base_info_iterate_attributes (GIBaseInfo *info, after = (AttributeBlob *) &rinfo->typelib->data[header->attributes + header->n_attributes * header->attribute_blob_size]; - if (iter->data != NULL) - next = (AttributeBlob *) iter->data; + if (iterator->data != NULL) + next = (AttributeBlob *) iterator->data; else next = find_first_attribute (rinfo); @@ -490,7 +490,7 @@ g_base_info_iterate_attributes (GIBaseInfo *info, *name = (gchar*) g_typelib_get_string (rinfo->typelib, next->name); *value = (gchar*) g_typelib_get_string (rinfo->typelib, next->value); - iter->data = next + 1; + iterator->data = next + 1; return TRUE; } @@ -994,6 +994,8 @@ g_type_info_get_param_type (GITypeInfo *info, * this function returns full information about the referenced type. You can then * inspect the type of the returned #GIBaseInfo to further query whether it is * a concrete GObject, a GInterface, a structure, etc. using g_base_info_get_type(). + * + * Returns: a struct representing the interface or %NULL */ GIBaseInfo * g_type_info_get_interface (GITypeInfo *info) diff --git a/girepository.c b/girepository.c index e7004a9dc..d4be01db9 100644 --- a/girepository.c +++ b/girepository.c @@ -856,7 +856,7 @@ g_irepository_get_shared_library (GIRepository *repository, /** * g_irepository_get_c_prefix * @repository: A #GIRepository, may be %NULL for the default - * @namespace: Namespace to inspect + * @namespace_: Namespace to inspect * * This function returns the "C prefix", or the C level namespace * associated with the given introspection namespace. Each C symbol diff --git a/gtypelib.h b/gtypelib.h index 820801498..1ca83c862 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -717,7 +717,7 @@ typedef struct { } StructBlob; /** - * UnionBlob; + * UnionBlob: * @unregistered: If this is set, the type is not registered with GType. * @discriminated: Is set if the union is discriminated * @alignment: The byte boundary that the union is aligned to in memory From 51118b3338545ca47605e6c0cf8bc4b9de58a395 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 18 May 2010 18:10:51 -0300 Subject: [PATCH 277/692] [girepository] Document most of the structs --- girepository.c | 2 +- girepository.h | 300 +++++++++++++++++++++++++++++++++++++++++++++++-- girffi.c | 2 + girffi.h | 7 +- gtypelib.h | 48 ++++++-- 5 files changed, 335 insertions(+), 24 deletions(-) diff --git a/girepository.c b/girepository.c index d4be01db9..684db66e8 100644 --- a/girepository.c +++ b/girepository.c @@ -1149,7 +1149,7 @@ find_namespace_latest (const gchar *namespace, * @repository: (allow-none): Repository, may be %NULL for the default * @namespace_: GI namespace to use, e.g. "Gtk" * @version: (allow-none): Version of namespace, may be %NULL for latest - * @flags: Set of %GIRepositoryLoadFlags, may be %0 + * @flags: Set of %GIRepositoryLoadFlags, may be 0 * @error: a #GError. * * Force the namespace @namespace_ to be loaded if it isn't already. diff --git a/girepository.h b/girepository.h index 9e62ab153..36a1d39cc 100644 --- a/girepository.h +++ b/girepository.h @@ -41,6 +41,7 @@ typedef struct _GIRepositoryPrivate GIRepositoryPrivate; typedef struct _GIBaseInfoStub GIBaseInfo; struct _GIBaseInfoStub { + /* */ gint32 dummy1; gint32 dummy2; gpointer dummy3; @@ -51,27 +52,141 @@ struct _GIBaseInfoStub { gpointer padding[4]; }; +/** + * GICallableInfo: + * + * Represents a callable, either #GIFunctionInfo, #GICallbackInfo or + * #GIVFuncInfo. + */ typedef GIBaseInfo GICallableInfo; + +/** + * GIFunctionInfo: + * + * Represents a function, eg arguments and return value. + */ typedef GIBaseInfo GIFunctionInfo; + +/** + * GICallbackInfo: + * + * Represents a callback, eg arguments and return value. + */ typedef GIBaseInfo GICallbackInfo; + +/** + * GIRegisteredTypeInfo: + * + * Represent a registered type. + */ typedef GIBaseInfo GIRegisteredTypeInfo; + +/** + * GIStructInfo: + * + * Represents a struct. + */ typedef GIBaseInfo GIStructInfo; + +/** + * GIUnionInfo: + * + * Represents a union. + */ typedef GIBaseInfo GIUnionInfo; + +/** + * GIEnumInfo: + * + * Represents an enum or a flag. + */ typedef GIBaseInfo GIEnumInfo; + +/** + * GIObjectInfo: + * + * Represents an object. + */ typedef GIBaseInfo GIObjectInfo; + +/** + * GIInterfaceInfo: + * + * Represents an interface. + */ typedef GIBaseInfo GIInterfaceInfo; + +/** + * GIConstantInfo: + * + * Represents a constant. + */ typedef GIBaseInfo GIConstantInfo; + +/** + * GIValueInfo: + * + * Represents a enum value of a #GIEnumInfo. + */ typedef GIBaseInfo GIValueInfo; + +/** + * GISignalInfo: + * + * Represents a signal. + */ typedef GIBaseInfo GISignalInfo; + +/** + * GIVFuncInfo + * + * Represents a virtual function. + */ typedef GIBaseInfo GIVFuncInfo; + +/** + * GIPropertyInfo: + * + * Represents a property of a #GIObjectInfo or a #GIInterfaceInfo. + */ typedef GIBaseInfo GIPropertyInfo; + +/** + * GIFieldInfo: + * + * Represents a field of a #GIStructInfo or a #GIUnionInfo. + */ typedef GIBaseInfo GIFieldInfo; + +/** + * GIArgInfo: + * + * Represents an argument. + */ typedef GIBaseInfo GIArgInfo; + +/** + * GITypeInfo: + * + * Represents type information, direction, transfer etc. + */ typedef GIBaseInfo GITypeInfo; + +/** + * GIErrorDomainInfo: + * + * Represents a #GError error domain. + */ typedef GIBaseInfo GIErrorDomainInfo; -typedef struct _GIUnresolvedInfo GIUnresolvedInfo; -typedef struct _GTypelib GTypelib; +/** + * GIUnresolvedInfo: + * + * Represents a unresolved type in a typelib. + */ +typedef struct _GIUnresolvedInfo GIUnresolvedInfo; + +typedef struct _GTypelib GTypelib; struct _GIRepository { @@ -86,6 +201,13 @@ struct _GIRepositoryClass GObjectClass parent; }; +/** + * GIRepositoryLoadFlags + * @G_IREPOSITORY_LOAD_FLAG_LAZY: Load the types lazily. + * + * Flags that controlls how a typelib is loaded by + * GIRepositry, used by g_irepository_load_typelib(). + */ typedef enum { G_IREPOSITORY_LOAD_FLAG_LAZY = 1 << 0 @@ -149,6 +271,16 @@ gboolean g_typelib_symbol (GTypelib *typelib, gpointer *symbol); const gchar * g_typelib_get_namespace (GTypelib *typelib); +/** + * GIRepositoryError: + * @G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND: the typelib could not be found. + * @G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH: the namespace does not match the + * requested namespace. + * @G_IREPOSITORY_ERROR_NAMESPACE_VERSION_CONFLICT: the version of the + * typelib does not match the requested version. + * @G_IREPOSITORY_ERROR_LIBRARY_NOT_FOUND: the library used by the typelib + * could not be found. + */ typedef enum { G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, @@ -173,6 +305,32 @@ void gi_cclosure_marshal_generic (GClosure *closure, /* Types of objects registered in the repository */ +/** + * GIInfoType: + * @GI_INFO_TYPE_INVALID: invalid type + * @GI_INFO_TYPE_FUNCTION: function, see #GIFunctionInfo + * @GI_INFO_TYPE_CALLBACK: callback, see #GICallbackInfo + * @GI_INFO_TYPE_STRUCT: struct, see #GIStructInfo + * @GI_INFO_TYPE_BOXED: boxed, see #GIBoxedInfo + * @GI_INFO_TYPE_ENUM: enum, see #GIEnumInfo + * @GI_INFO_TYPE_FLAGS: flags, see #GIEnumInfo + * @GI_INFO_TYPE_OBJECT: object, see #GIObjectInfo + * @GI_INFO_TYPE_INTERFACE: interface, see #GIInterfaceInfo + * @GI_INFO_TYPE_CONSTANT: contant, see #GIConstantInfo + * @GI_INFO_TYPE_ERROR_DOMAIN: error domain for a #GError, see #GIErrorDomainInfo + * @GI_INFO_TYPE_UNION: union, see #GIUnionInfo + * @GI_INFO_TYPE_VALUE: enum value, see #GIValueInfo + * @GI_INFO_TYPE_SIGNAL: signal, see #GISignalInfo + * @GI_INFO_TYPE_VFUNC: virtual function, see #GIVFuncInfo + * @GI_INFO_TYPE_PROPERTY: GObject property, see #GIPropertyInfo + * @GI_INFO_TYPE_FIELD: struct or union field, see #GIFieldInfo + * @GI_INFO_TYPE_ARG: argument of a function or callback, see #GIArgInfo + * @GI_INFO_TYPE_TYPE: type information, see #GITypeInfo + * @GI_INFO_TYPE_UNRESOLVED: unresolved type, a type which is not present in + * the typelib, or any of its dependencies. + * + * The type of a GIBaseInfo struct. + */ typedef enum { GI_INFO_TYPE_INVALID, @@ -200,7 +358,14 @@ typedef enum /* GIBaseInfo */ +/** + * GIAttributeIter: + * + * An opaque structure used to iterate over attributes + * in a #GIBaseInfo struct. + */ typedef struct { + /* */ gpointer data; gpointer data2; gpointer data3; @@ -232,6 +397,17 @@ GIBaseInfo * g_info_new (GIInfoType type, /* GIFunctionInfo */ +/** + * GIFunctionInfoFlags: + * @GI_FUNCTION_IS_METHOD: is a method. + * @GI_FUNCTION_IS_CONSTRUCTOR: is a constructor. + * @GI_FUNCTION_IS_GETTER: is a getter of a #GIPropertyInfo. + * @GI_FUNCTION_IS_SETTER: is a setter of a #GIPropertyInfo. + * @GI_FUNCTION_WRAPS_VFUNC: represents a virtual function. + * @GI_FUNCTION_THROWS: the function may throw an error. + * + * Flags for a #GIFunctionInfo struct. + */ typedef enum { GI_FUNCTION_IS_METHOD = 1 << 0, @@ -275,6 +451,18 @@ typedef union #define G_INVOKE_ERROR (g_invoke_error_quark ()) GQuark g_invoke_error_quark (void); +/** + * GInvokeError: + * @G_INVOKE_ERROR_FAILED: invokation failed, unknown error. + * @G_INVOKE_ERROR_SYMBOL_NOT_FOUND: symbol couldn't be found in any of the + * libraries associated with the typelib of the function. + * @G_INVOKE_ERROR_ARGUMENT_MISMATCH: the arguments provided didn't match + * the expected arguments for the functions type signature. + * + * An error occuring while invoking a function via + * g_function_info_invoke(). + */ + typedef enum { G_INVOKE_ERROR_FAILED, @@ -293,6 +481,16 @@ gboolean g_function_info_invoke (GIFunctionInfo *info, /* GICallableInfo */ +/** + * GITransfer: + * @GI_TRANSFER_NOTHING: transfer nothing to the caller + * @GI_TRANSFER_CONTAINER: transfer the container (eg list, array, + * hashtable), but no the contents to the caller. + * @GI_TRANSFER_EVERYTHING: transfer everything to the caller. + * + * Represent the transfer ownership information of a #GICallableInfo or + * a #GIArgInfo. + */ typedef enum { GI_TRANSFER_NOTHING, GI_TRANSFER_CONTAINER, @@ -313,21 +511,40 @@ void g_callable_info_load_arg (GICallableInfo *info, /* GIArgInfo */ +/** + * GIDirection: + * @GI_DIRECTION_IN: in argument. + * @GI_DIRECTION_OUT: out argument. + * @GI_DIRECTION_INOUT: in and out argument. + * + * The direction of a #GIArgInfo. + */ typedef enum { GI_DIRECTION_IN, GI_DIRECTION_OUT, GI_DIRECTION_INOUT } GIDirection; +/** + * GIScopeType: + * @GI_SCOPE_TYPE_INVALID: The argument is not of callback type. + * @GI_SCOPE_TYPE_CALL: The callback and associated user_data is only + * used during the call to this function. + * @GI_SCOPE_TYPE_ASYNC: The callback and associated user_data is + * only used until the callback is invoked, and the callback. + * is invoked always exactly once. + * @GI_SCOPE_TYPE_NOTIFIED: The callback and and associated + * user_data is used until the caller is notfied via the destroy_notify. + * + * Scope type of a #GIArgInfo representing callback, determines how the + * callback is invoked and is used to decided when the invoke structs + * can be freed. + */ typedef enum { - GI_SCOPE_TYPE_INVALID, /* The argument is not of callback type */ - GI_SCOPE_TYPE_CALL, /* The callback and associated user_data is only used during the - call to this function */ - GI_SCOPE_TYPE_ASYNC, /* The callback and associated user_data is - only used until the callback is invoked, and the callback - is invoked always exactly once. */ - GI_SCOPE_TYPE_NOTIFIED /* The callback and and associated user_data is - used until the caller is notfied via the destroy_notify */ + GI_SCOPE_TYPE_INVALID, + GI_SCOPE_TYPE_CALL, + GI_SCOPE_TYPE_ASYNC, + GI_SCOPE_TYPE_NOTIFIED } GIScopeType; GIDirection g_arg_info_get_direction (GIArgInfo *info); @@ -344,8 +561,42 @@ void g_arg_info_load_type (GIArgInfo *info, GITypeInfo *type); -/* GITypeInfo */ - +/** + * GITypeTag: + * @GI_TYPE_TAG_VOID: void + * @GI_TYPE_TAG_BOOLEAN: boolean + * @GI_TYPE_TAG_INT8: 8-bit signed integer + * @GI_TYPE_TAG_UINT8: 8-bit unsigned integer + * @GI_TYPE_TAG_INT16: 16-bit signed integer + * @GI_TYPE_TAG_UINT16: 16-bit unsigned integer + * @GI_TYPE_TAG_INT32: 32-bit signed integer + * @GI_TYPE_TAG_UINT32: 32-bit unsigned integer + * @GI_TYPE_TAG_INT64: 64-bit signed integer + * @GI_TYPE_TAG_UINT64: 64-bit unsigned integer + * @GI_TYPE_TAG_SHORT: signed short + * @GI_TYPE_TAG_USHORT: unsigned hosrt + * @GI_TYPE_TAG_INT: signed integer + * @GI_TYPE_TAG_UINT: unsigned integer + * @GI_TYPE_TAG_LONG: signed long + * @GI_TYPE_TAG_ULONG: unsigned long + * @GI_TYPE_TAG_SSIZE: ssize_t + * @GI_TYPE_TAG_SIZE: size_t + * @GI_TYPE_TAG_FLOAT: float + * @GI_TYPE_TAG_DOUBLE: double floating point + * @GI_TYPE_TAG_TIME_T: time_t + * @GI_TYPE_TAG_GTYPE: a #GType + * @GI_TYPE_TAG_UTF8: a UTF-8 encoded string + * @GI_TYPE_TAG_FILENAME: a filename, encoded in the same encoding + * as the native filesystem is using. + * @GI_TYPE_TAG_ARRAY: an array + * @GI_TYPE_TAG_INTERFACE: an extended interface object + * @GI_TYPE_TAG_GLIST: a #GList + * @GI_TYPE_TAG_GSLIST: a #GSList + * @GI_TYPE_TAG_GHASH: a #GHashTable + * @GI_TYPE_TAG_ERROR: a #GError + * + * The type tag of a #GITypeInfo. + */ typedef enum { /* Basic types */ GI_TYPE_TAG_VOID = 0, @@ -383,6 +634,15 @@ typedef enum { * See docs/typelib-format.txt SimpleTypeBlob definition */ } GITypeTag; +/** + * GIArrayType: + * @GI_ARRAY_TYPE_C: a C array, char[] for instance + * @GI_ARRAY_TYPE_ARRAY: a @GArray array + * @GI_ARRAY_TYPE_PTR_ARRAY: a #GPtrArray array + * @GI_ARRAY_TYPE_BYTE_ARRAY: a #GByteArray array + * + * The type of array in a #GITypeInfo. + */ typedef enum { GI_ARRAY_TYPE_C, GI_ARRAY_TYPE_ARRAY, @@ -421,6 +681,14 @@ glong g_value_info_get_value (GIValueInfo *info); /* GIFieldInfo */ +/** + * GIFieldInfoFlags: + * @GI_FIELD_IS_READABLE: field is readable. + * @GI_FIELD_IS_WRITABLE: field is writable. + * + * Flags for a #GIFieldInfo. + */ + typedef enum { GI_FIELD_IS_READABLE = 1 << 0, @@ -561,6 +829,14 @@ gboolean g_signal_info_true_stops_emit (GISignalInfo /* GIVFuncInfo */ +/** + * GIVFuncInfoFlags: + * @GI_VFUNC_MUST_CHAIN_UP: chains up to the parent type + * @GI_VFUNC_MUST_OVERRIDE: overrides + * @GI_VFUNC_MUST_NOT_OVERRIDE: does not override + * + * Flags of a #GIVFuncInfo struct. + */ typedef enum { GI_VFUNC_MUST_CHAIN_UP = 1 << 0, diff --git a/girffi.c b/girffi.c index 3f0b67058..6716324ee 100644 --- a/girffi.c +++ b/girffi.c @@ -198,6 +198,8 @@ g_callable_info_get_ffi_return_type (GICallableInfo *callable_info) * A primary intent of this function is that a dynamic structure allocated * by a language binding could contain a #GIFunctionInvoker structure * inside the binding's function mapping. + * + * Returns: %TRUE on success, %FALSE otherwise with @error set. */ gboolean g_function_info_prep_invoker (GIFunctionInfo *info, diff --git a/girffi.h b/girffi.h index 54ce7b58f..56d85a189 100644 --- a/girffi.h +++ b/girffi.h @@ -31,12 +31,17 @@ typedef void (*GIFFIClosureCallback) (ffi_cif *, void **, void *); +/** + * GIFunctionInvoker: + * @cif: the cif + * @native_address: the native adress + */ typedef struct _GIFunctionInvoker GIFunctionInvoker; struct _GIFunctionInvoker { ffi_cif cif; gpointer native_address; - + /* */ gpointer padding[3]; }; diff --git a/gtypelib.h b/gtypelib.h index 1ca83c862..617cb39ff 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -202,6 +202,7 @@ typedef enum { * @nsversion: Offset of the namespace version string in the typelib. * @shared_library: This field is the set of shared libraries associated * with the typelib. The entries are separated by the '|' (pipe) character. + * @c_prefix: The prefix for the function names of the library * @entry_blob_size: The sizes of fixed-size blobs. Recording this information here * allows to write parser which continue to work if the format is * extended by adding new fields to the end of the fixed-size blobs. @@ -234,7 +235,9 @@ typedef struct { gchar magic[16]; guint8 major_version; guint8 minor_version; + /* */ guint16 reserved; + /* */ guint16 n_entries; guint16 n_local_entries; guint32 directory; @@ -269,6 +272,7 @@ typedef struct { guint16 interface_blob_size; guint16 union_blob_size; + /* */ guint16 padding[7]; } Header; @@ -290,8 +294,9 @@ typedef struct { guint16 blob_type; guint16 local : 1; + /* */ guint16 reserved :15; - + /* */ guint32 name; guint32 offset; } DirEntry; @@ -322,16 +327,20 @@ typedef union { struct { + /* */ guint reserved : 8; guint reserved2 :16; + /* */ guint pointer : 1; + /* */ guint reserved3 : 2; + /* */ guint tag : 5; } flags; guint32 offset; } SimpleTypeBlob; -/* +/** * ArgBlob: * @name: A suggested name for the parameter. * @in: The parameter is an input to the function @@ -356,7 +365,7 @@ typedef union * @transfer_container_ownership: For container types, indicates that the * ownership of the container, but not of its contents is transferred. This is typically the case * for out parameters returning lists of statically allocated things. - * @is_return_value: The parameter should be considered the return value of the function. + * @return_value: The parameter should be considered the return value of the function. * Only out parameters can be marked as return value, and there can be * at most one per function call. If an out parameter is marked as * return value, the actual return value of the function should be @@ -386,8 +395,9 @@ typedef struct { guint transfer_container_ownership : 1; guint return_value : 1; guint scope : 3; + /* */ guint reserved :21; - + /* */ gint8 closure; gint8 destroy; @@ -434,8 +444,9 @@ typedef struct { guint16 blob_type; /* 1 */ guint16 deprecated : 1; + /* */ guint16 reserved :15; - + /* */ guint32 name; } CommonBlob; @@ -494,8 +505,9 @@ typedef struct { guint16 blob_type; /* 2 */ guint16 deprecated : 1; + /* */ guint16 reserved :15; - + /* */ guint32 name; guint32 signature; } CallbackBlob; @@ -510,9 +522,13 @@ typedef struct { */ typedef struct { guint8 pointer :1; + /* */ guint8 reserved :2; + /* */ guint8 tag :5; + /* */ guint8 reserved2; + /* */ guint16 interface; } InterfaceTypeBlob; @@ -533,7 +549,6 @@ typedef struct { * direction as this one. * @size: The fixed size of the array. * @type: The type of the array elements. - * * Arrays are passed by reference, thus is_pointer is always 1. */ typedef struct { @@ -618,7 +633,9 @@ typedef struct { */ typedef struct { guint32 deprecated : 1; + /* */ guint32 reserved :31; + /* */ guint32 name; gint32 value; } ValueBlob; @@ -681,9 +698,7 @@ typedef struct { * @gtype_name: String name of the associated #GType * @gtype_init: String naming the symbol which gets the runtime #GType * @n_fields: - * @n_functions: The lengths of the arrays. * @fields: An array of n_fields FieldBlobs. - * @functions: An array of n_functions FunctionBlobs. The described functions * should be considered as methods of the struct. */ typedef struct { @@ -730,7 +745,6 @@ typedef struct { * The value 0xFFFF indicates that the discriminator offset * is unknown. * @discriminator_type: Type of the discriminator - * @discriminator_values: On discriminator value per field * @fields: Array of FieldBlobs describing the alternative branches of the union */ typedef struct { @@ -1040,7 +1054,11 @@ typedef struct { guint32 value; } AttributeBlob; +/** + * GTypelib: + */ struct _GTypelib { + /* */ guchar *data; gsize len; gboolean owns_memory; @@ -1057,6 +1075,16 @@ void g_typelib_check_sanity (void); #define g_typelib_get_string(typelib,offset) ((const gchar*)&(typelib->data)[(offset)]) +/** + * GTypelibError: + * @G_TYPELIB_ERROR_INVALID: the typelib is invalid + * @G_TYPELIB_ERROR_INVALID_HEADER: the typelib header is invalid + * @G_TYPELIB_ERROR_INVALID_DIRECTORY: the typelib directory is invalid + * @G_TYPELIB_ERROR_INVALID_ENTRY: a typelib entry is invalid + * @G_TYPELIB_ERROR_INVALID_BLOB: a typelib blob is invalid + * + * A error set while validating the #GTypelib + */ typedef enum { G_TYPELIB_ERROR_INVALID, From 75c9df12f1e772deb2f338d4e8229e38aef5b884 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 18 May 2010 23:40:24 -0300 Subject: [PATCH 278/692] [GIBaseInfo] Document all functions --- ginfo.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 6 deletions(-) diff --git a/ginfo.c b/ginfo.c index aab864d2b..b24363210 100644 --- a/ginfo.c +++ b/ginfo.c @@ -167,6 +167,46 @@ g_info_from_entry (GIRepository *repository, } /* GIBaseInfo functions */ + +/** + * SECTION:gibaseinfo + * @Short_description: Base struct for all GTypelib structs + * @Title: GIBaseInfo + * + * GIBaseInfo is the common base struct of all other *Info structs + * accessible through the #GIRepository API. + * All other structs can be casted to a #GIBaseInfo, for instance: + * + * Casting a #GIFunctionInfo to #GIBaseInfo + * + * GIFunctionInfo *function_info = ...; + * GIBaseInfo *info = (GIBaseInfo*)function_info; + * + * + * Most #GIRepository APIs returning a #GIBaseInfo is actually creating a new struct, in other + * words, g_base_info_unref() has to be called when done accessing the data. + * GIBaseInfos are normally accessed by calling either + * g_irepository_find_by_name(), g_irepository_find_by_gtype() or g_irepository_get_info(). + * + * + * Getting the Button of the Gtk typelib + * + * GIBaseInfo *button_info = g_irepository_find_by_name(NULL, "Gtk", "Button"); + * ... use button_info ... + * g_base_info_unref(button_info); + * + * + * + */ + +/** + * g_base_info_ref: + * @info: a GIBaseInfo + * + * Increases the reference count of @info. + * + * Returns: the same @info. + */ GIBaseInfo * g_base_info_ref (GIBaseInfo *info) { @@ -178,6 +218,13 @@ g_base_info_ref (GIBaseInfo *info) return info; } +/** + * g_base_info_unref: + * @info: a GIBaseInfo + * + * Decreases the reference count of @info. When its reference count + * drops to 0, the info is freed. + */ void g_base_info_unref (GIBaseInfo *info) { @@ -198,6 +245,14 @@ g_base_info_unref (GIBaseInfo *info) } } +/** + * g_base_info_get_type: + * @info: a GIBaseInfo + * + * Obtains the info type of the GIBaseInfo. + * + * Returns: the info type of @info + */ GIInfoType g_base_info_get_type (GIBaseInfo *info) { @@ -205,6 +260,16 @@ g_base_info_get_type (GIBaseInfo *info) return ((GIRealInfo*)info)->type; } +/** + * g_base_info_get_name: + * @info: a GIBaseInfo + * + * Obtains the name of the @info. What the name represents depends on + * the #GIInfoType of the @info. For instance for #GIFunctionInfo it is + * the name of the function. + * + * Returns: the name of @info or %NULL if it lacks a name. + */ const gchar * g_base_info_get_name (GIBaseInfo *info) { @@ -293,6 +358,14 @@ g_base_info_get_name (GIBaseInfo *info) return NULL; } +/** + * g_base_info_get_namespace: + * @info: a GIBaseInfo + * + * Obtains the namespace of @info. + * + * Returns: the namespace + */ const gchar * g_base_info_get_namespace (GIBaseInfo *info) { @@ -311,6 +384,15 @@ g_base_info_get_namespace (GIBaseInfo *info) return g_typelib_get_string (rinfo->typelib, header->namespace); } +/** + * g_base_info_is_deprecated: + * @info: a GIBaseInfo + * + * Obtains whether the @info is represents a metadata which is + * deprecated or not. + * + * Returns: %TRUE if deprecated, otherwise %FALSE + */ gboolean g_base_info_is_deprecated (GIBaseInfo *info) { @@ -371,8 +453,8 @@ g_base_info_is_deprecated (GIBaseInfo *info) /** * g_base_info_get_attribute: - * @info: A #GIBaseInfo - * @name: A freeform string naming an attribute + * @info: a #GIBaseInfo + * @name: a freeform string naming an attribute * * Retrieve an arbitrary attribute associated with this node. * @@ -495,22 +577,40 @@ g_base_info_iterate_attributes (GIBaseInfo *info, return TRUE; } +/** + * g_base_info_get_container: + * @info: a GIBaseInfo + * + * Obtains the container of the @info. The container is the parent + * GIBaseInfo. For instance, the parent of a #GIFunctionInfo is an + * #GIObjectInfo or #GIInterfaceInfo. + * + * Returns: the container + */ GIBaseInfo * g_base_info_get_container (GIBaseInfo *info) { return ((GIRealInfo*)info)->container; } +/** + * g_base_info_get_typelib: + * @info: a GIBaseInfo + * + * Obtains the typelib this @info belongs to + * + * Returns: the typelib. + */ GTypelib * g_base_info_get_typelib (GIBaseInfo *info) { return ((GIRealInfo*)info)->typelib; } -/* +/** * g_base_info_equal: - * @info1: A #GIBaseInfo - * @info2: A #GIBaseInfo + * @info1: a #GIBaseInfo + * @info2: a #GIBaseInfo * * Compare two #GIBaseInfo. * @@ -518,7 +618,7 @@ g_base_info_get_typelib (GIBaseInfo *info) * different instances of #GIBaseInfo that refers to the same part of the * TypeLib; use this function instead to do #GIBaseInfo comparisons. * - * Return value: TRUE if and only if @info1 equals @info2. + * Returns: TRUE if and only if @info1 equals @info2. */ gboolean g_base_info_equal (GIBaseInfo *info1, GIBaseInfo *info2) From 456379be2999ebf155b1f38412a0707b6817a374 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 19 May 2010 16:17:06 +0100 Subject: [PATCH 279/692] girparser: backtrace_stderr: fix int/ssize_t format mismatch backtrace() is defined in terms of int, which differs from ssize_t on x86-64, and @size is also an int. --- girparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index 125bd171b..0b2366f70 100644 --- a/girparser.c +++ b/girparser.c @@ -287,7 +287,7 @@ backtrace_stderr (void) size = backtrace (array, 50); strings = (char**) backtrace_symbols (array, size); - fprintf (stderr, "--- BACKTRACE (%zd frames) ---\n", size); + fprintf (stderr, "--- BACKTRACE (%d frames) ---\n", size); for (i = 0; i < size; i++) fprintf (stderr, "%s\n", strings[i]); From 3e473d93cab14223e806a21735c072b2ceb0a59a Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Wed, 19 May 2010 13:53:48 -0300 Subject: [PATCH 280/692] [docs] Reference g_module_open instead of dlopen dlopen() is not cross platform, it's better to mention g_module_open everywhere as that's actually what we call internally. --- ginvoke.c | 2 +- gtypelib.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ginvoke.c b/ginvoke.c index 2d4c3f562..bae8da4f5 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -58,7 +58,7 @@ g_invoke_error_quark (void) * argument lists. This function uses dlsym() to obtain a pointer * to the function, so the library or shared object containing the * described function must either be linked to the caller, or must - * have been dlopen()ed before calling this function. + * have been g_module_symbol()ed before calling this function. * * Returns: %TRUE if the function has been invoked, %FALSE if an * error occurred. diff --git a/gtypelib.c b/gtypelib.c index da7e5ee6d..463996c3e 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -1982,7 +1982,7 @@ _g_typelib_do_dlopen (GTypelib *typelib) shlibs = g_strsplit (shlib_str, ",", 0); /* We load all passed libs unconditionally as if the same library is loaded - * again with dlopen(), the same file handle will be returned. See bug: + * again with g_module_open(), the same file handle will be returned. See bug: * http://bugzilla.gnome.org/show_bug.cgi?id=555294 */ for (i = 0; shlibs[i]; i++) @@ -1990,7 +1990,7 @@ _g_typelib_do_dlopen (GTypelib *typelib) GModule *module; /* Glade's autoconnect feature and OpenGL's extension mechanism - * as used by Clutter rely on dlopen(NULL) to work as a means of + * as used by Clutter rely on g_module_open(NULL) to work as a means of * accessing the app's symbols. This keeps us from using * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well; * in general libraries are not expecting multiple copies of From c94b53978864e7c324cbac0601ee23fc74353b34 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Wed, 19 May 2010 13:54:26 -0300 Subject: [PATCH 281/692] [GIFunctionInfo] Document struct and functions --- ginfo.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/ginfo.c b/ginfo.c index b24363210..bf06a6463 100644 --- a/ginfo.c +++ b/ginfo.c @@ -630,6 +630,30 @@ g_base_info_equal (GIBaseInfo *info1, GIBaseInfo *info2) } /* GIFunctionInfo functions */ + +/** + * SECTION:gifunctioninfo + * @Short_description: Struct representing a function + * @Title: GIFunctionInfo + * + * GIFunctionInfo represents a function, method or constructor. + * To find out what kind of entity a #GIFunctionInfo represents, call + * g_function_info_get_flags(). + * + * See also #GICallableInfo for information on how to retreive arguments and + * other metadata. + */ + +/** + * g_function_info_get_symbol: + * @info: a #GIFunctionInfo + * + * Obtains the symbol of the function. The symbol is the name of the + * exported function, suitable to be used as an argument to + * g_module_symbol(). + * + * Returns: the symbol + */ const gchar * g_function_info_get_symbol (GIFunctionInfo *info) { @@ -639,6 +663,14 @@ g_function_info_get_symbol (GIFunctionInfo *info) return g_typelib_get_string (rinfo->typelib, blob->symbol); } +/** + * g_function_info_get_flags: + * @info: a #GIFunctionInfo + * + * Obtains the #GIFunctionInfoFlags for the @info. + * + * Returns: the flags + */ GIFunctionInfoFlags g_function_info_get_flags (GIFunctionInfo *info) { @@ -670,6 +702,17 @@ g_function_info_get_flags (GIFunctionInfo *info) return flags; } +/** + * g_function_info_get_property: + * @info: a #GIFunctionInfo + * + * Obtains the property associated with this #GIFunctionInfo. + * Only #GIFunctionInfo with the flag %GI_FUNCTION_IS_GETTER or + * %GI_FUNCTION_IS_SETTER have a property set. For other cases, + * %NULL will be returned. + * + * Returns: the property or %NULL if not set. + */ GIPropertyInfo * g_function_info_get_property (GIFunctionInfo *info) { @@ -680,6 +723,16 @@ g_function_info_get_property (GIFunctionInfo *info) return g_interface_info_get_property (container, blob->index); } +/** + * g_function_info_get_vfunc: + * @info: a #GIFunctionInfo + * + * Obtains the virtual function associated with this #GIFunctionInfo. + * Only #GIFunctionInfo with the flag %GI_FUNCTION_WRAPS_VFUNC has + * a virtual function set. For other cases, %NULL will be returned. + * + * Returns: the virtual function or %NULL if not set. + */ GIVFuncInfo * g_function_info_get_vfunc (GIFunctionInfo *info) { From cc270b03d65bbe94f2232bccb62b5dcf5d68a74f Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Wed, 19 May 2010 20:57:19 -0300 Subject: [PATCH 282/692] [docs] Make gtk-doc language consistent. Make the language we use in the gtk-doc comments more consistent. Add transfer annotation for all functions returning a struct and mention how they should be freed. --- ginfo.c | 111 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 49 deletions(-) diff --git a/ginfo.c b/ginfo.c index bf06a6463..6dad78204 100644 --- a/ginfo.c +++ b/ginfo.c @@ -201,7 +201,7 @@ g_info_from_entry (GIRepository *repository, /** * g_base_info_ref: - * @info: a GIBaseInfo + * @info: a #GIBaseInfo * * Increases the reference count of @info. * @@ -220,7 +220,7 @@ g_base_info_ref (GIBaseInfo *info) /** * g_base_info_unref: - * @info: a GIBaseInfo + * @info: a #GIBaseInfo * * Decreases the reference count of @info. When its reference count * drops to 0, the info is freed. @@ -247,7 +247,7 @@ g_base_info_unref (GIBaseInfo *info) /** * g_base_info_get_type: - * @info: a GIBaseInfo + * @info: a #GIBaseInfo * * Obtains the info type of the GIBaseInfo. * @@ -262,7 +262,7 @@ g_base_info_get_type (GIBaseInfo *info) /** * g_base_info_get_name: - * @info: a GIBaseInfo + * @info: a #GIBaseInfo * * Obtains the name of the @info. What the name represents depends on * the #GIInfoType of the @info. For instance for #GIFunctionInfo it is @@ -360,7 +360,7 @@ g_base_info_get_name (GIBaseInfo *info) /** * g_base_info_get_namespace: - * @info: a GIBaseInfo + * @info: a #GIBaseInfo * * Obtains the namespace of @info. * @@ -386,12 +386,12 @@ g_base_info_get_namespace (GIBaseInfo *info) /** * g_base_info_is_deprecated: - * @info: a GIBaseInfo + * @info: a #GIBaseInfo * * Obtains whether the @info is represents a metadata which is * deprecated or not. * - * Returns: %TRUE if deprecated, otherwise %FALSE + * Returns: %TRUE if deprecated */ gboolean g_base_info_is_deprecated (GIBaseInfo *info) @@ -458,7 +458,7 @@ g_base_info_is_deprecated (GIBaseInfo *info) * * Retrieve an arbitrary attribute associated with this node. * - * Return value: The value of the attribute, or %NULL if no such attribute exists + * Returns: The value of the attribute, or %NULL if no such attribute exists */ const gchar * g_base_info_get_attribute (GIBaseInfo *info, @@ -518,8 +518,8 @@ find_first_attribute (GIRealInfo *rinfo) /** * g_base_info_iterate_attributes: - * @info: A #GIBaseInfo - * @iterator: A #GIAttributeIter structure, must be initialized; see below + * @info: a #GIBaseInfo + * @iterator: a #GIAttributeIter structure, must be initialized; see below * @name: (out) (transfer none): Returned name, must not be freed * @value: (out) (transfer none): Returned name, must not be freed * @@ -547,7 +547,7 @@ find_first_attribute (GIRealInfo *rinfo) * * * - * Return value: %TRUE if there are more attributes, %FALSE otherwise + * Returns: %TRUE if there are more attributes */ gboolean g_base_info_iterate_attributes (GIBaseInfo *info, @@ -579,13 +579,13 @@ g_base_info_iterate_attributes (GIBaseInfo *info, /** * g_base_info_get_container: - * @info: a GIBaseInfo + * @info: a #GIBaseInfo * * Obtains the container of the @info. The container is the parent * GIBaseInfo. For instance, the parent of a #GIFunctionInfo is an * #GIObjectInfo or #GIInterfaceInfo. * - * Returns: the container + * Returns: (transfer none): the container */ GIBaseInfo * g_base_info_get_container (GIBaseInfo *info) @@ -595,11 +595,11 @@ g_base_info_get_container (GIBaseInfo *info) /** * g_base_info_get_typelib: - * @info: a GIBaseInfo + * @info: a #GIBaseInfo * * Obtains the typelib this @info belongs to * - * Returns: the typelib. + * Returns: (transfer none): the typelib. */ GTypelib * g_base_info_get_typelib (GIBaseInfo *info) @@ -618,7 +618,7 @@ g_base_info_get_typelib (GIBaseInfo *info) * different instances of #GIBaseInfo that refers to the same part of the * TypeLib; use this function instead to do #GIBaseInfo comparisons. * - * Returns: TRUE if and only if @info1 equals @info2. + * Returns: %TRUE if and only if @info1 equals @info2. */ gboolean g_base_info_equal (GIBaseInfo *info1, GIBaseInfo *info2) @@ -711,7 +711,8 @@ g_function_info_get_flags (GIFunctionInfo *info) * %GI_FUNCTION_IS_SETTER have a property set. For other cases, * %NULL will be returned. * - * Returns: the property or %NULL if not set. + * Returns: (transfer full): the property or %NULL if not set. Free it with + * g_base_info_unref() when done. */ GIPropertyInfo * g_function_info_get_property (GIFunctionInfo *info) @@ -731,7 +732,8 @@ g_function_info_get_property (GIFunctionInfo *info) * Only #GIFunctionInfo with the flag %GI_FUNCTION_WRAPS_VFUNC has * a virtual function set. For other cases, %NULL will be returned. * - * Returns: the virtual function or %NULL if not set. + * Returns: (transfer full): the virtual function or %NULL if not set. + * Free it by calling g_base_info_unref() when done. */ GIVFuncInfo * g_function_info_get_vfunc (GIFunctionInfo *info) @@ -798,11 +800,10 @@ g_type_info_init (GIBaseInfo *info, * g_callable_info_get_return_type: * @info: a #GICallableInfo * - * Get the return type of a callable item as - * a #GITypeInfo + * Get the return type of a callable item as a #GITypeInfo. * - * Returns: a #GITypeInfo idexing the TypeBlob for the - * return type of #info + * Returns: (transfer full): the #GITypeInfo. Free the struct by calling + * g_base_info_unref() when done. */ GITypeInfo * g_callable_info_get_return_type (GICallableInfo *info) @@ -843,9 +844,9 @@ g_callable_info_load_return_type (GICallableInfo *info, * g_callable_info_may_return_null: * @info: a #GICallableInfo * - * See if a callable could return NULL. + * See if a callable could return %NULL. * - * Returns: TRUE if callable could return NULL + * Returns: %TRUE if callable could return %NULL */ gboolean g_callable_info_may_return_null (GICallableInfo *info) @@ -863,7 +864,7 @@ g_callable_info_may_return_null (GICallableInfo *info) * See whether the caller owns the return value * of this callable. * - * Returns: TRUE if the caller owns the return value, FALSE otherwise. + * Returns: %TRUE if the caller owns the return value, %FALSE otherwise. */ GITransfer g_callable_info_get_caller_owns (GICallableInfo *info) @@ -907,7 +908,8 @@ g_callable_info_get_n_args (GICallableInfo *info) * * Get information about a particular argument of this callable. * - * Returns: A #GIArgInfo indexing the typelib on the given argument. + * Returns: (transfer full): the #GIArgInfo. Free it with + * g_base_info_unref() when done. */ GIArgInfo * g_callable_info_get_arg (GICallableInfo *info, @@ -1044,9 +1046,12 @@ g_arg_info_get_destroy (GIArgInfo *info) /** * g_arg_info_get_type: - * @info: A #GIArgInfo + * @info: a #GIArgInfo * - * Returns: (transfer full): Information about the type of argument @info + * Obtains the type information for @info. + * + * Returns: (transfer full): the #GIArgInfo, free it with + * g_base_info_unref() when done. */ GITypeInfo * g_arg_info_get_type (GIArgInfo *info) @@ -1058,7 +1063,7 @@ g_arg_info_get_type (GIArgInfo *info) /** * g_arg_info_load_type: - * @info: A #GIArgInfo + * @info: a #GIArgInfo * @type: (out caller-allocates): Initialized with information about type of @info * * Get information about a the type of given argument @info; this @@ -1141,14 +1146,15 @@ g_type_info_get_param_type (GITypeInfo *info, /** * g_type_info_get_interface: - * @info: A #GITypeInfo + * @info: a #GITypeInfo * * For types which have #GI_TYPE_TAG_INTERFACE such as GObjects and boxed values, * this function returns full information about the referenced type. You can then * inspect the type of the returned #GIBaseInfo to further query whether it is * a concrete GObject, a GInterface, a structure, etc. using g_base_info_get_type(). * - * Returns: a struct representing the interface or %NULL + * Returns: (transfer full): the #GIBaseInfo, or %NULL. Free it with + * g_base_info_unref() when done. */ GIBaseInfo * g_type_info_get_interface (GITypeInfo *info) @@ -1575,7 +1581,7 @@ g_struct_info_is_foreign (GIStructInfo *info) /** * g_struct_info_is_gtype_struct: - * @info: GIStructInfo + * @info: a #GIStructInfo * * Return true if this structure represents the "class structure" for some * #GObject or #GInterface. This function is mainly useful to hide this kind of structure @@ -1616,7 +1622,7 @@ g_enum_info_get_value (GIEnumInfo *info, /** * g_enum_info_get_storage_type: - * @info: GIEnumInfo + * @info: a #GIEnumInfo * * Gets the tag of the type used for the enum in the C ABI. This will * will be a signed or unsigned integral type. @@ -1879,16 +1885,19 @@ find_vfunc (GIRealInfo *rinfo, /** * g_object_info_find_vfunc: - * @info: An #GIObjectInfo + * @info: a #GIObjectInfo * @name: The name of a virtual function to find. * - * Locate a virtual function slot with name @name. Note that the namespace + * Locate a virtual function slot with name @name. Note that the namespace * for virtuals is distinct from that of methods; there may or may not be - * a concrete method associated for a virtual. If there is one, it may - * be retrieved using #g_vfunc_info_get_invoker. See the documentation for - * that function for more information on invoking virtuals. + * a concrete method associated for a virtual. If there is one, it may + * be retrieved using g_vfunc_info_get_invoker(), otherwise %NULL will be + * returned. + * See the documentation for g_vfunc_info_get_invoker() for more + * information on invoking virtuals. * - * Return value: (transfer full): A #GIVFuncInfo, or %NULL if none with name @name. + * Returns: (transfer full): the #GIVFuncInfo, or %NULL. Free it with + * g_base_info_unref() when done. */ GIVFuncInfo * g_object_info_find_vfunc (GIObjectInfo *info, @@ -1942,12 +1951,13 @@ g_object_info_get_constant (GIObjectInfo *info, /** * g_object_info_get_class_struct: - * @info: A #GIObjectInfo to query + * @info: a #GIObjectInfo * * Every #GObject has two structures; an instance structure and a class * structure. This function returns the metadata for the class structure. * - * Returns: a #GIStructInfo for the class struct or %NULL if none found. + * Returns: (transfer full): the #GIStructInfo or %NULL. Free with + * g_base_info_unref() when done. */ GIStructInfo * g_object_info_get_class_struct (GIObjectInfo *info) @@ -2112,13 +2122,14 @@ g_interface_info_get_vfunc (GIInterfaceInfo *info, /** * g_interface_info_find_vfunc: - * @info: An #GIObjectInfo + * @info: a #GIObjectInfo * @name: The name of a virtual function to find. * - * Locate a virtual function slot with name @name. See the documentation - * for #g_object_info_find_vfunc for more information on virtuals. + * Locate a virtual function slot with name @name. See the documentation + * for g_object_info_find_vfunc() for more information on virtuals. * - * Return value: (transfer full): A #GIVFuncInfo, or %NULL if none with name @name. + * Returns: (transfer full): the #GIVFuncInfo, or %NULL. Free it with + * g_base_info_unref() when done. */ GIVFuncInfo * g_interface_info_find_vfunc (GIInterfaceInfo *info, @@ -2170,11 +2181,12 @@ g_interface_info_get_constant (GIInterfaceInfo *info, /** * g_interface_info_get_iface_struct: - * @info: A #GIInterfaceInfo to query + * @info: a #GIInterfaceInfo * * Returns the layout C structure associated with this #GInterface. * - * Returns: A #GIStructInfo for the class struct or %NULL if none found. + * Returns: (transfer full): the #GIStructInfo or %NULL. Free it with + * g_base_info_unref() when done. */ GIStructInfo * g_interface_info_get_iface_struct (GIInterfaceInfo *info) @@ -2325,14 +2337,15 @@ g_vfunc_info_get_signal (GIVFuncInfo *info) /** * g_vfunc_info_get_invoker: - * @info: A #GIVFuncInfo + * @info: a #GIVFuncInfo * * If this virtual function has an associated invoker method, this * method will return it. An invoker method is a C entry point. * * Not all virtuals will have invokers. * - * Return value: (transfer full): An invoker function, or %NULL if none known + * Returns: (transfer full): the #GIVFuncInfo or %NULL. Free it with + * g_base_info_unref() when done. */ GIFunctionInfo * g_vfunc_info_get_invoker (GIVFuncInfo *info) From 7e2e37938820f9702a3c770b1458138e3ce73026 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 20 May 2010 11:33:49 -0300 Subject: [PATCH 283/692] [girepository] Use g_slice Use g_slice to allocate instead of g_new(x, 1); It uses a memory pool internally and should be faster, especially for GBaseInfo/GRealInfo, structs which are tiny. --- ginfo.c | 8 ++++---- girepository.c | 6 +++--- girmodule.c | 4 ++-- gtypelib.c | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ginfo.c b/ginfo.c index 6dad78204..a404059c3 100644 --- a/ginfo.c +++ b/ginfo.c @@ -107,7 +107,7 @@ g_info_new_full (GIInfoType type, g_return_val_if_fail (container != NULL || repository != NULL, NULL); - info = g_new (GIRealInfo, 1); + info = g_slice_new (GIRealInfo); g_info_init (info, type, repository, container, typelib, offset); info->ref_count = 1; @@ -149,7 +149,7 @@ g_info_from_entry (GIRepository *repository, { GIUnresolvedInfo *unresolved; - unresolved = g_new0 (GIUnresolvedInfo, 1); + unresolved = g_slice_new0 (GIUnresolvedInfo); unresolved->type = GI_INFO_TYPE_UNRESOLVED; unresolved->ref_count = 1; @@ -159,7 +159,7 @@ g_info_from_entry (GIRepository *repository, unresolved->namespace = namespace; return (GIBaseInfo *)unresolved; - } + } return (GIBaseInfo *)result; } @@ -241,7 +241,7 @@ g_base_info_unref (GIBaseInfo *info) if (rinfo->repository) g_object_unref (rinfo->repository); - g_free (rinfo); + g_slice_free (GIRealInfo, rinfo); } } diff --git a/girepository.c b/girepository.c index 684db66e8..218a954cf 100644 --- a/girepository.c +++ b/girepository.c @@ -1043,7 +1043,7 @@ free_candidate (struct NamespaceVersionCandidadate *candidate) g_mapped_file_unref (candidate->mfile); g_free (candidate->path); g_free (candidate->version); - g_free (candidate); + g_slice_free (struct NamespaceVersionCandidadate, candidate); } static GMappedFile * @@ -1111,7 +1111,7 @@ find_namespace_latest (const gchar *namespace, g_clear_error (&error); continue; } - candidate = g_new0 (struct NamespaceVersionCandidadate, 1); + candidate = g_slice_new0 (struct NamespaceVersionCandidadate); candidate->mfile = mfile; candidate->path_index = index; candidate->path = path; @@ -1134,7 +1134,7 @@ find_namespace_latest (const gchar *namespace, result = elected->mfile; *path_ret = elected->path; *version_ret = elected->version; - g_free (elected); /* just free the container */ + g_slice_free (struct NamespaceVersionCandidadate, elected); /* just free the container */ g_slist_foreach (candidates, (GFunc) free_candidate, NULL); g_slist_free (candidates); } diff --git a/girmodule.c b/girmodule.c index 66efceb26..b380912b5 100644 --- a/girmodule.c +++ b/girmodule.c @@ -37,7 +37,7 @@ g_ir_module_new (const gchar *name, { GIrModule *module; - module = g_new0 (GIrModule, 1); + module = g_slice_new0 (GIrModule); module->name = g_strdup (name); module->version = g_strdup (version); @@ -73,7 +73,7 @@ g_ir_module_free (GIrModule *module) g_hash_table_destroy (module->aliases); g_hash_table_destroy (module->disguised_structures); - g_free (module); + g_slice_free (GIrModule, module); } /** diff --git a/gtypelib.c b/gtypelib.c index 463996c3e..41bbb0ccc 100644 --- a/gtypelib.c +++ b/gtypelib.c @@ -2071,7 +2071,7 @@ g_typelib_new_from_memory (guchar *memory, gsize len) { GTypelib *meta; - meta = g_new0 (GTypelib, 1); + meta = g_slice_new0 (GTypelib); meta->data = memory; meta->len = len; meta->owns_memory = TRUE; @@ -2094,7 +2094,7 @@ g_typelib_new_from_const_memory (const guchar *memory, gsize len) { GTypelib *meta; - meta = g_new0 (GTypelib, 1); + meta = g_slice_new0 (GTypelib); meta->data = (guchar *) memory; meta->len = len; meta->owns_memory = FALSE; @@ -2116,7 +2116,7 @@ g_typelib_new_from_mapped_file (GMappedFile *mfile) { GTypelib *meta; - meta = g_new0 (GTypelib, 1); + meta = g_slice_new0 (GTypelib); meta->mfile = mfile; meta->owns_memory = FALSE; meta->data = (guchar *) g_mapped_file_get_contents (mfile); @@ -2144,7 +2144,7 @@ g_typelib_free (GTypelib *typelib) g_list_foreach (typelib->modules, (GFunc) g_module_close, NULL); g_list_free (typelib->modules); } - g_free (typelib); + g_slice_free (GTypelib, typelib); } const gchar * From 9505b6eb44074d3d24d0a7ede9943fe3bbac7159 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 21 May 2010 18:30:58 -0300 Subject: [PATCH 284/692] [docs] Document GICallableInfo and GIArgInfo Make docs more consistent and also fix a couple of broken links --- ginfo.c | 147 ++++++++++++++++++++++++++++++++++++++++++------- girepository.h | 4 +- 2 files changed, 129 insertions(+), 22 deletions(-) diff --git a/ginfo.c b/ginfo.c index a404059c3..309988519 100644 --- a/ginfo.c +++ b/ginfo.c @@ -249,7 +249,7 @@ g_base_info_unref (GIBaseInfo *info) * g_base_info_get_type: * @info: a #GIBaseInfo * - * Obtains the info type of the GIBaseInfo. + * Obtain the info type of the GIBaseInfo. * * Returns: the info type of @info */ @@ -264,7 +264,7 @@ g_base_info_get_type (GIBaseInfo *info) * g_base_info_get_name: * @info: a #GIBaseInfo * - * Obtains the name of the @info. What the name represents depends on + * Obtain the name of the @info. What the name represents depends on * the #GIInfoType of the @info. For instance for #GIFunctionInfo it is * the name of the function. * @@ -362,7 +362,7 @@ g_base_info_get_name (GIBaseInfo *info) * g_base_info_get_namespace: * @info: a #GIBaseInfo * - * Obtains the namespace of @info. + * Obtain the namespace of @info. * * Returns: the namespace */ @@ -388,7 +388,7 @@ g_base_info_get_namespace (GIBaseInfo *info) * g_base_info_is_deprecated: * @info: a #GIBaseInfo * - * Obtains whether the @info is represents a metadata which is + * Obtain whether the @info is represents a metadata which is * deprecated or not. * * Returns: %TRUE if deprecated @@ -581,7 +581,7 @@ g_base_info_iterate_attributes (GIBaseInfo *info, * g_base_info_get_container: * @info: a #GIBaseInfo * - * Obtains the container of the @info. The container is the parent + * Obtain the container of the @info. The container is the parent * GIBaseInfo. For instance, the parent of a #GIFunctionInfo is an * #GIObjectInfo or #GIInterfaceInfo. * @@ -597,7 +597,7 @@ g_base_info_get_container (GIBaseInfo *info) * g_base_info_get_typelib: * @info: a #GIBaseInfo * - * Obtains the typelib this @info belongs to + * Obtain the typelib this @info belongs to * * Returns: (transfer none): the typelib. */ @@ -648,7 +648,7 @@ g_base_info_equal (GIBaseInfo *info1, GIBaseInfo *info2) * g_function_info_get_symbol: * @info: a #GIFunctionInfo * - * Obtains the symbol of the function. The symbol is the name of the + * Obtain the symbol of the function. The symbol is the name of the * exported function, suitable to be used as an argument to * g_module_symbol(). * @@ -667,7 +667,7 @@ g_function_info_get_symbol (GIFunctionInfo *info) * g_function_info_get_flags: * @info: a #GIFunctionInfo * - * Obtains the #GIFunctionInfoFlags for the @info. + * Obtain the #GIFunctionInfoFlags for the @info. * * Returns: the flags */ @@ -706,7 +706,7 @@ g_function_info_get_flags (GIFunctionInfo *info) * g_function_info_get_property: * @info: a #GIFunctionInfo * - * Obtains the property associated with this #GIFunctionInfo. + * Obtain the property associated with this #GIFunctionInfo. * Only #GIFunctionInfo with the flag %GI_FUNCTION_IS_GETTER or * %GI_FUNCTION_IS_SETTER have a property set. For other cases, * %NULL will be returned. @@ -728,7 +728,7 @@ g_function_info_get_property (GIFunctionInfo *info) * g_function_info_get_vfunc: * @info: a #GIFunctionInfo * - * Obtains the virtual function associated with this #GIFunctionInfo. + * Obtain the virtual function associated with this #GIFunctionInfo. * Only #GIFunctionInfo with the flag %GI_FUNCTION_WRAPS_VFUNC has * a virtual function set. For other cases, %NULL will be returned. * @@ -746,6 +746,20 @@ g_function_info_get_vfunc (GIFunctionInfo *info) } /* GICallableInfo functions */ + +/** + * SECTION:gicallableinfo + * @Short_description: Struct representing a callable + * @Title: GICallableInfo + * + * GICallableInfo represents an entity which is callable. + * Currently a function (#GIFunctionInfo), virtual function, + * (#GIVirtualFunc) or callback (#GICallbackInfo). + * + * A callable has a list of arguments (#GIArgInfo), a return type, + * direction and a flag which decides if it returns null. + * + */ static guint32 signature_offset (GICallableInfo *info) { @@ -800,7 +814,7 @@ g_type_info_init (GIBaseInfo *info, * g_callable_info_get_return_type: * @info: a #GICallableInfo * - * Get the return type of a callable item as a #GITypeInfo. + * Obtain the return type of a callable item as a #GITypeInfo. * * Returns: (transfer full): the #GITypeInfo. Free the struct by calling * g_base_info_unref() when done. @@ -822,7 +836,7 @@ g_callable_info_get_return_type (GICallableInfo *info) * @info: a #GICallableInfo * @type: (out caller-allocates): Initialized with return type of @info * - * Get information about a return value of callable; this + * Obtain information about a return value of callable; this * function is a variant of g_callable_info_get_return_type() designed for stack * allocation. * @@ -861,8 +875,8 @@ g_callable_info_may_return_null (GICallableInfo *info) * g_callable_info_get_caller_owns: * @info: a #GICallableInfo * - * See whether the caller owns the return value - * of this callable. + * See whether the caller owns the return value of this callable. + * #GITransfer contains a list of possible transfer values. * * Returns: %TRUE if the caller owns the return value, %FALSE otherwise. */ @@ -884,7 +898,7 @@ g_callable_info_get_caller_owns (GICallableInfo *info) * g_callable_info_get_n_args: * @info: a #GICallableInfo * - * Get the number of arguments (both IN and OUT) for this callable. + * Obtain the number of arguments (both IN and OUT) for this callable. * * Returns: The number of arguments this callable expects. */ @@ -906,14 +920,14 @@ g_callable_info_get_n_args (GICallableInfo *info) * @info: a #GICallableInfo * @n: the argument index to fetch * - * Get information about a particular argument of this callable. + * Obtain information about a particular argument of this callable. * * Returns: (transfer full): the #GIArgInfo. Free it with * g_base_info_unref() when done. */ GIArgInfo * g_callable_info_get_arg (GICallableInfo *info, - gint n) + gint n) { GIRealInfo *rinfo = (GIRealInfo *)info; Header *header = (Header *)rinfo->typelib->data; @@ -931,7 +945,7 @@ g_callable_info_get_arg (GICallableInfo *info, * @n: the argument index to fetch * @arg: (out caller-allocates): Initialize with argument number @n * - * Get information about a particular argument of this callable; this + * Obtain information about a particular argument of this callable; this * function is a variant of g_callable_info_get_arg() designed for stack * allocation. * @@ -940,7 +954,7 @@ g_callable_info_get_arg (GICallableInfo *info, void g_callable_info_load_arg (GICallableInfo *info, gint n, - GIArgInfo *arg) + GIArgInfo *arg) { GIRealInfo *rinfo = (GIRealInfo *)info; Header *header = (Header *)rinfo->typelib->data; @@ -953,6 +967,27 @@ g_callable_info_load_arg (GICallableInfo *info, } /* GIArgInfo function */ + +/** + * SECTION:giarginfo + * @Short_description: Struct representing an argument + * @Title: GIArgInfo + * + * GIArgInfo represents an argument. An argument is always + * part of a #GICallableInfo. + * + * + */ + +/** + * g_arg_info_get_direction: + * @info: a #GIArgInfo + * + * Obtain the direction of the argument. Check #GIDirection for possible + * direction values. + * + * Returns: the direction + */ GIDirection g_arg_info_get_direction (GIArgInfo *info) { @@ -967,6 +1002,15 @@ g_arg_info_get_direction (GIArgInfo *info) return GI_DIRECTION_IN; } +/** + * g_arg_info_is_return_value: + * @info: a #GIArgInfo + * + * Obtain if the argument is a return value. It can either be a + * parameter or a return value. + * + * Returns: %TRUE if it is a return value + */ gboolean g_arg_info_is_return_value (GIArgInfo *info) { @@ -976,6 +1020,15 @@ g_arg_info_is_return_value (GIArgInfo *info) return blob->return_value; } +/** + * g_arg_info_is_dipper: + * @info: a #GIArgInfo + * + * Obtain if the argument is a pointer to a struct or object that will + * receive an output of a function. + * + * Returns: %TRUE if it is a dipper argument + */ gboolean g_arg_info_is_dipper (GIArgInfo *info) { @@ -985,6 +1038,14 @@ g_arg_info_is_dipper (GIArgInfo *info) return blob->dipper; } +/** + * g_arg_info_is_optional: + * @info: a #GIArgInfo + * + * Obtain if the argument is optional. + * + * Returns: %TRUE if it is an optional argument + */ gboolean g_arg_info_is_optional (GIArgInfo *info) { @@ -994,6 +1055,14 @@ g_arg_info_is_optional (GIArgInfo *info) return blob->optional; } +/** + * g_arg_info_may_be_null: + * @info: a #GIArgInfo + * + * Obtain if the argument accepts %NULL. + * + * Returns: %TRUE if it accepts %NULL + */ gboolean g_arg_info_may_be_null (GIArgInfo *info) { @@ -1003,6 +1072,15 @@ g_arg_info_may_be_null (GIArgInfo *info) return blob->allow_none; } +/** + * g_arg_info_get_ownership_transfer: + * @info: a #GIArgInfo + * + * Obtain the ownership transfer for this argument. + * #GITransfer contains a list of possible values. + * + * Returns: the transfer + */ GITransfer g_arg_info_get_ownership_transfer (GIArgInfo *info) { @@ -1017,6 +1095,17 @@ g_arg_info_get_ownership_transfer (GIArgInfo *info) return GI_TRANSFER_NOTHING; } +/** + * g_arg_info_get_scope: + * @info: a #GIArgInfo + * + * Obtain the scope type for this argument. The scope type explains + * how a callback is going to be invoked, most importantly when + * the resources required to invoke it can be freed. + * #GIScopeType contains a list of possible values. + * + * Returns: the scope type + */ GIScopeType g_arg_info_get_scope (GIArgInfo *info) { @@ -1026,6 +1115,15 @@ g_arg_info_get_scope (GIArgInfo *info) return blob->scope; } +/** + * g_arg_info_get_closure: + * @info: a #GIArgInfo + * + * Obtains the index of the user data argument. This is only valid + * for arguments which are callbacks. + * + * Returns: index of the user data argument or -1 if there is none + */ gint g_arg_info_get_closure (GIArgInfo *info) { @@ -1035,6 +1133,15 @@ g_arg_info_get_closure (GIArgInfo *info) return blob->closure; } +/** + * g_arg_info_get_destroy: + * @info: a #GIArgInfo + * + * Obtains the index of the #GDestroyNotify argument. This is only valid + * for arguments which are callbacks. + * + * Returns: index of the #GDestroyNotify argument or -1 if there is none + */ gint g_arg_info_get_destroy (GIArgInfo *info) { @@ -1048,7 +1155,7 @@ g_arg_info_get_destroy (GIArgInfo *info) * g_arg_info_get_type: * @info: a #GIArgInfo * - * Obtains the type information for @info. + * Obtain the type information for @info. * * Returns: (transfer full): the #GIArgInfo, free it with * g_base_info_unref() when done. diff --git a/girepository.h b/girepository.h index 36a1d39cc..66afbffaa 100644 --- a/girepository.h +++ b/girepository.h @@ -309,9 +309,9 @@ void gi_cclosure_marshal_generic (GClosure *closure, * GIInfoType: * @GI_INFO_TYPE_INVALID: invalid type * @GI_INFO_TYPE_FUNCTION: function, see #GIFunctionInfo - * @GI_INFO_TYPE_CALLBACK: callback, see #GICallbackInfo + * @GI_INFO_TYPE_CALLBACK: callback, see #GIFunctionInfo * @GI_INFO_TYPE_STRUCT: struct, see #GIStructInfo - * @GI_INFO_TYPE_BOXED: boxed, see #GIBoxedInfo + * @GI_INFO_TYPE_BOXED: boxed, see #GIStructInfo or #GIUnionInfo * @GI_INFO_TYPE_ENUM: enum, see #GIEnumInfo * @GI_INFO_TYPE_FLAGS: flags, see #GIEnumInfo * @GI_INFO_TYPE_OBJECT: object, see #GIObjectInfo From 46d9ef151ecc6d0316ece0b9593dc4f72ae07c5f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 16 Dec 2009 11:47:19 -0500 Subject: [PATCH 285/692] Support (out caller-allocates) People have wanted support for marking (out) on functions of the form: /** * clutter_color_from_pixel: * @pixel: A pixel * @color: (out): Color to initialize with value of @pixel */ void clutter_color_from_pixel (guint32 pixel, ClutterColor *color); Where the caller is supposed to have allocated the argument; the C function just initializes it. This patch adds support for this argument passing style to introspection. In this case, we see the (out), and notice that there's only a single indirection (*) on the argument, and assume that this means (out caller-allocates). https://bugzilla.gnome.org/show_bug.cgi?id=604749 --- ginfo.c | 12 +++++++----- girepository.h | 1 + girnode.c | 2 +- girnode.h | 2 +- girparser.c | 20 +++++++++++++------- gtypelib.h | 6 +++--- 6 files changed, 26 insertions(+), 17 deletions(-) diff --git a/ginfo.c b/ginfo.c index 309988519..48ebe03f7 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1021,21 +1021,23 @@ g_arg_info_is_return_value (GIArgInfo *info) } /** - * g_arg_info_is_dipper: + * g_arg_info_is_caller_allocates: * @info: a #GIArgInfo * * Obtain if the argument is a pointer to a struct or object that will - * receive an output of a function. + * receive an output of a function. The default assumption for + * %GI_DIRECTION_OUT arguments which have allocation is that the + * callee allocates; if this is %TRUE, then the caller must allocate. * - * Returns: %TRUE if it is a dipper argument + * Returns: %TRUE if caller is required to have allocated the argument */ gboolean -g_arg_info_is_dipper (GIArgInfo *info) +g_arg_info_is_caller_allocates (GIArgInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - return blob->dipper; + return blob->caller_allocates; } /** diff --git a/girepository.h b/girepository.h index 66afbffaa..f3225640d 100644 --- a/girepository.h +++ b/girepository.h @@ -551,6 +551,7 @@ GIDirection g_arg_info_get_direction (GIArgInfo *info); gboolean g_arg_info_is_dipper (GIArgInfo *info); gboolean g_arg_info_is_return_value (GIArgInfo *info); gboolean g_arg_info_is_optional (GIArgInfo *info); +gboolean g_arg_info_is_caller_allocates (GIArgInfo *info); gboolean g_arg_info_may_be_null (GIArgInfo *info); GITransfer g_arg_info_get_ownership_transfer (GIArgInfo *info); GIScopeType g_arg_info_get_scope (GIArgInfo *info); diff --git a/girnode.c b/girnode.c index 6f4a44af9..9ff323575 100644 --- a/girnode.c +++ b/girnode.c @@ -1864,7 +1864,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->name = write_string (node->name, strings, data, offset2); blob->in = param->in; blob->out = param->out; - blob->dipper = param->dipper; + blob->caller_allocates = param->caller_allocates; blob->allow_none = param->allow_none; blob->optional = param->optional; blob->transfer_ownership = param->transfer; diff --git a/girnode.h b/girnode.h index 5e6cba035..8c7b14eb1 100644 --- a/girnode.h +++ b/girnode.h @@ -153,7 +153,7 @@ struct _GIrNodeParam gboolean in; gboolean out; - gboolean dipper; + gboolean caller_allocates; gboolean optional; gboolean retval; gboolean allow_none; diff --git a/girparser.c b/girparser.c index 0b2366f70..bf10e44b6 100644 --- a/girparser.c +++ b/girparser.c @@ -881,8 +881,8 @@ start_parameter (GMarkupParseContext *context, const gchar *name; const gchar *direction; const gchar *retval; - const gchar *dipper; const gchar *optional; + const gchar *caller_allocates; const gchar *allow_none; const gchar *transfer; const gchar *scope; @@ -897,9 +897,9 @@ start_parameter (GMarkupParseContext *context, name = find_attribute ("name", attribute_names, attribute_values); direction = find_attribute ("direction", attribute_names, attribute_values); retval = find_attribute ("retval", attribute_names, attribute_values); - dipper = find_attribute ("dipper", attribute_names, attribute_values); optional = find_attribute ("optional", attribute_names, attribute_values); allow_none = find_attribute ("allow-none", attribute_names, attribute_values); + caller_allocates = find_attribute ("caller-allocates", attribute_names, attribute_values); transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); scope = find_attribute ("scope", attribute_names, attribute_values); closure = find_attribute ("closure", attribute_names, attribute_values); @@ -919,16 +919,27 @@ start_parameter (GMarkupParseContext *context, { param->in = FALSE; param->out = TRUE; + if (caller_allocates == NULL) + { + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "caller-allocates attribute required on out parameters"); + return FALSE; + } + param->caller_allocates = strcmp (caller_allocates, "1") == 0; } else if (direction && strcmp (direction, "inout") == 0) { param->in = TRUE; param->out = TRUE; + param->caller_allocates = FALSE; } else { param->in = TRUE; param->out = FALSE; + param->caller_allocates = FALSE; } if (retval && strcmp (retval, "1") == 0) @@ -936,11 +947,6 @@ start_parameter (GMarkupParseContext *context, else param->retval = FALSE; - if (dipper && strcmp (dipper, "1") == 0) - param->dipper = TRUE; - else - param->dipper = FALSE; - if (optional && strcmp (optional, "1") == 0) param->optional = TRUE; else diff --git a/gtypelib.h b/gtypelib.h index 617cb39ff..0524efa13 100644 --- a/gtypelib.h +++ b/gtypelib.h @@ -349,7 +349,7 @@ typedef union * add another level of indirection to the parameter type. Ie if * the type is uint32 in an out parameter, the function actually * takes an uint32*. - * @dipper: The parameter is a pointer to a struct or object that will + * @caller_allocates: The parameter is a pointer to a struct or object that will * receive an output of the function. * @allow_none: Only meaningful for types which are passed as pointers. * For an in parameter, indicates if it is ok to pass NULL in, for @@ -388,7 +388,7 @@ typedef struct { guint in : 1; guint out : 1; - guint dipper : 1; + guint caller_allocates : 1; guint allow_none : 1; guint optional : 1; guint transfer_ownership : 1; @@ -397,7 +397,7 @@ typedef struct { guint scope : 3; /* */ guint reserved :21; - /* */ + gint8 closure; gint8 destroy; From a20c2ad7c294eed37ad48deb7342e11841b5ecbc Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 26 May 2010 13:52:36 -0400 Subject: [PATCH 286/692] [girparser] Don't hard require caller-allocates since it breaks parsing We need to support parsing older .girs for inclusion purposes. (But we should probably have an explicit .gir version, and require the attribute for newer versions) --- girparser.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/girparser.c b/girparser.c index bf10e44b6..341cb5ded 100644 --- a/girparser.c +++ b/girparser.c @@ -920,14 +920,9 @@ start_parameter (GMarkupParseContext *context, param->in = FALSE; param->out = TRUE; if (caller_allocates == NULL) - { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "caller-allocates attribute required on out parameters"); - return FALSE; - } - param->caller_allocates = strcmp (caller_allocates, "1") == 0; + param->caller_allocates = FALSE; + else + param->caller_allocates = strcmp (caller_allocates, "1") == 0; } else if (direction && strcmp (direction, "inout") == 0) { From 23e9949e1decfe5d67e87665b31f8bd5404e51c1 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 26 May 2010 18:14:39 -0400 Subject: [PATCH 287/692] Remove g_arg_info_is_dipper from public API It wasn't useful, the new g_arg_info_is_caller_allocates is. --- girepository.h | 1 - 1 file changed, 1 deletion(-) diff --git a/girepository.h b/girepository.h index f3225640d..8bcce3a53 100644 --- a/girepository.h +++ b/girepository.h @@ -548,7 +548,6 @@ typedef enum { } GIScopeType; GIDirection g_arg_info_get_direction (GIArgInfo *info); -gboolean g_arg_info_is_dipper (GIArgInfo *info); gboolean g_arg_info_is_return_value (GIArgInfo *info); gboolean g_arg_info_is_optional (GIArgInfo *info); gboolean g_arg_info_is_caller_allocates (GIArgInfo *info); From e66f46042db9f0398aac28c2b73375783cbc55c3 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 27 May 2010 23:18:58 -0300 Subject: [PATCH 288/692] [girepository] Add macros for checking struct type Add macros for checking the sub-struct type. These are similar to the standard GObject macros. --- girepository.h | 64 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/girepository.h b/girepository.h index 8bcce3a53..deea9d3f7 100644 --- a/girepository.h +++ b/girepository.h @@ -388,15 +388,19 @@ GIBaseInfo * g_base_info_get_container (GIBaseInfo *info); GTypelib * g_base_info_get_typelib (GIBaseInfo *info); gboolean g_base_info_equal (GIBaseInfo *info1, GIBaseInfo *info2); +gboolean g_base_info_is_a (GIBaseInfo *info, + GIInfoType type); GIBaseInfo * g_info_new (GIInfoType type, GIBaseInfo *container, GTypelib *typelib, guint32 offset); - /* GIFunctionInfo */ +#define GI_IS_FUNCTION_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FUNCTION) + /** * GIFunctionInfoFlags: * @GI_FUNCTION_IS_METHOD: is a method. @@ -481,6 +485,12 @@ gboolean g_function_info_invoke (GIFunctionInfo *info, /* GICallableInfo */ +#define GI_IS_CALLABLE_INFO(info) \ + ((g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FUNCTION) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_CALLBACK) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_SIGNAL) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_VFUNC)) + /** * GITransfer: * @GI_TRANSFER_NOTHING: transfer nothing to the caller @@ -511,6 +521,9 @@ void g_callable_info_load_arg (GICallableInfo *info, /* GIArgInfo */ +#define GI_IS_ARG_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ARG) + /** * GIDirection: * @GI_DIRECTION_IN: in argument. @@ -560,6 +573,10 @@ GITypeInfo * g_arg_info_get_type (GIArgInfo *info); void g_arg_info_load_type (GIArgInfo *info, GITypeInfo *type); +/* GITypeInfo */ + +#define GI_IS_TYPE_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_TYPE) /** * GITypeTag: @@ -670,17 +687,26 @@ GIErrorDomainInfo *g_type_info_get_error_domain (GITypeInfo *info, /* GIErrorDomainInfo */ +#define GI_IS_ERROR_DOMAIN_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ERROR_DOMAIN) + const gchar * g_error_domain_info_get_quark (GIErrorDomainInfo *info); GIInterfaceInfo * g_error_domain_info_get_codes (GIErrorDomainInfo *info); /* GIValueInfo */ +#define GI_IS_VALUE_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_VALUE) + glong g_value_info_get_value (GIValueInfo *info); /* GIFieldInfo */ +#define GI_IS_FIELD_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FIELD) + /** * GIFieldInfoFlags: * @GI_FIELD_IS_READABLE: field is readable. @@ -708,6 +734,10 @@ gboolean g_field_info_set_field (GIFieldInfo *field_info, const GArgument *value); /* GIUnionInfo */ + +#define GI_IS_UNION_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_UNION) + gint g_union_info_get_n_fields (GIUnionInfo *info); GIFieldInfo * g_union_info_get_field (GIUnionInfo *info, gint n); @@ -726,6 +756,10 @@ gsize g_union_info_get_alignment (GIUnionInfo *info); /* GIStructInfo */ + +#define GI_IS_STRUCT_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_STRUCT) + gint g_struct_info_get_n_fields (GIStructInfo *info); GIFieldInfo * g_struct_info_get_field (GIStructInfo *info, gint n); @@ -741,12 +775,22 @@ gboolean g_struct_info_is_foreign (GIStructInfo *info); /* GIRegisteredTypeInfo */ +#define GI_IS_REGISTERED_TYPE_INFO(info) \ + ((g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ENUM) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_INTERFACE) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_OBJECT) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_STRUCT) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_UNION)) + const gchar * g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info); const gchar * g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info); GType g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info); /* GIEnumInfo */ +#define GI_IS_ENUM_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ENUM) + gint g_enum_info_get_n_values (GIEnumInfo *info); GIValueInfo * g_enum_info_get_value (GIEnumInfo *info, gint n); @@ -754,6 +798,9 @@ GITypeTag g_enum_info_get_storage_type (GIEnumInfo *in /* GIObjectInfo */ +#define GI_IS_OBJECT_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_OBJECT) + const gchar * g_object_info_get_type_name (GIObjectInfo *info); const gchar * g_object_info_get_type_init (GIObjectInfo *info); gboolean g_object_info_get_abstract (GIObjectInfo *info); @@ -788,6 +835,9 @@ GIStructInfo * g_object_info_get_class_struct (GIObjectInfo *in /* GIInterfaceInfo */ +#define GI_IS_INTERFACE_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_INTERFACE) + gint g_interface_info_get_n_prerequisites (GIInterfaceInfo *info); GIBaseInfo * g_interface_info_get_prerequisite (GIInterfaceInfo *info, gint n); @@ -816,12 +866,18 @@ GIStructInfo * g_interface_info_get_iface_struct (GIInterfaceInfo *in /* GIPropertyInfo */ +#define GI_IS_PROPERTY_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_PROPERTY) + GParamFlags g_property_info_get_flags (GIPropertyInfo *info); GITypeInfo * g_property_info_get_type (GIPropertyInfo *info); /* GISignalInfo */ +#define GI_IS_SIGNAL_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_SIGNAL) + GSignalFlags g_signal_info_get_flags (GISignalInfo *info); GIVFuncInfo * g_signal_info_get_class_closure (GISignalInfo *info); gboolean g_signal_info_true_stops_emit (GISignalInfo *info); @@ -829,6 +885,9 @@ gboolean g_signal_info_true_stops_emit (GISignalInfo /* GIVFuncInfo */ +#define GI_IS_VFUNC_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_VFUNC) + /** * GIVFuncInfoFlags: * @GI_VFUNC_MUST_CHAIN_UP: chains up to the parent type @@ -852,6 +911,9 @@ GIFunctionInfo * g_vfunc_info_get_invoker (GIVFuncInfo /* GIConstantInfo */ +#define GI_IS_CONSTANT_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_CONSTANT) + GITypeInfo * g_constant_info_get_type (GIConstantInfo *info); gint g_constant_info_get_value (GIConstantInfo *info, GArgument *value); From 27c9f77335af5ba20d23d93415c444d3f836311c Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 27 May 2010 23:24:42 -0300 Subject: [PATCH 289/692] [girepository] Check types function/callable/arg Check the info types for functions, callable and args. Verifies that the right type is sent in --- ginfo.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 128 insertions(+), 23 deletions(-) diff --git a/ginfo.c b/ginfo.c index 48ebe03f7..a104b9af1 100644 --- a/ginfo.c +++ b/ginfo.c @@ -657,8 +657,14 @@ g_base_info_equal (GIBaseInfo *info1, GIBaseInfo *info2) const gchar * g_function_info_get_symbol (GIFunctionInfo *info) { - GIRealInfo *rinfo = (GIRealInfo *)info; - FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; + GIRealInfo *rinfo; + FunctionBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_FUNCTION_INFO (info), NULL); + + rinfo = (GIRealInfo *)info; + blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; return g_typelib_get_string (rinfo->typelib, blob->symbol); } @@ -675,8 +681,14 @@ GIFunctionInfoFlags g_function_info_get_flags (GIFunctionInfo *info) { GIFunctionInfoFlags flags; - GIRealInfo *rinfo = (GIRealInfo *)info; - FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; + GIRealInfo *rinfo; + FunctionBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_FUNCTION_INFO (info), -1); + + rinfo = (GIRealInfo *)info; + blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; flags = 0; @@ -717,9 +729,16 @@ g_function_info_get_flags (GIFunctionInfo *info) GIPropertyInfo * g_function_info_get_property (GIFunctionInfo *info) { - GIRealInfo *rinfo = (GIRealInfo *)info; - FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; - GIInterfaceInfo *container = (GIInterfaceInfo *)rinfo->container; + GIRealInfo *rinfo; + FunctionBlob *blob; + GIInterfaceInfo *container; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_FUNCTION_INFO (info), NULL); + + rinfo = (GIRealInfo *)info; + blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; + container = (GIInterfaceInfo *)rinfo->container; return g_interface_info_get_property (container, blob->index); } @@ -738,9 +757,16 @@ g_function_info_get_property (GIFunctionInfo *info) GIVFuncInfo * g_function_info_get_vfunc (GIFunctionInfo *info) { - GIRealInfo *rinfo = (GIRealInfo*)info; - FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; - GIInterfaceInfo *container = (GIInterfaceInfo *)rinfo->container; + GIRealInfo *rinfo; + FunctionBlob *blob; + GIInterfaceInfo *container; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_FUNCTION_INFO (info), NULL); + + rinfo = (GIRealInfo *)info; + blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; + container = (GIInterfaceInfo *)rinfo->container; return g_interface_info_get_vfunc (container, blob->index); } @@ -825,6 +851,9 @@ g_callable_info_get_return_type (GICallableInfo *info) GIRealInfo *rinfo = (GIRealInfo *)info; guint32 offset; + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), NULL); + offset = signature_offset (info); return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, offset); @@ -849,6 +878,9 @@ g_callable_info_load_return_type (GICallableInfo *info, GIRealInfo *rinfo = (GIRealInfo *)info; guint32 offset; + g_return_if_fail (info != NULL); + g_return_if_fail (GI_IS_CALLABLE_INFO (info)); + offset = signature_offset (info); g_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, offset); @@ -866,7 +898,12 @@ gboolean g_callable_info_may_return_null (GICallableInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - SignatureBlob *blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)]; + SignatureBlob *blob; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), FALSE); + + blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)]; return blob->may_return_null; } @@ -884,7 +921,12 @@ GITransfer g_callable_info_get_caller_owns (GICallableInfo *info) { GIRealInfo *rinfo = (GIRealInfo*) info; - SignatureBlob *blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)]; + SignatureBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), -1); + + blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)]; if (blob->caller_owns_return_value) return GI_TRANSFER_EVERYTHING; @@ -909,6 +951,9 @@ g_callable_info_get_n_args (GICallableInfo *info) gint offset; SignatureBlob *blob; + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), -1); + offset = signature_offset (info); blob = (SignatureBlob *)&rinfo->typelib->data[offset]; @@ -930,10 +975,14 @@ g_callable_info_get_arg (GICallableInfo *info, gint n) { GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; + Header *header; gint offset; + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), NULL); + offset = signature_offset (info); + header = (Header *)rinfo->typelib->data; return (GIArgInfo *) g_info_new (GI_INFO_TYPE_ARG, (GIBaseInfo*)info, rinfo->typelib, offset + header->signature_blob_size + n * header->arg_blob_size); @@ -957,10 +1006,14 @@ g_callable_info_load_arg (GICallableInfo *info, GIArgInfo *arg) { GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; + Header *header; gint offset; + g_return_if_fail (info != NULL); + g_return_if_fail (GI_IS_CALLABLE_INFO (info)); + offset = signature_offset (info); + header = (Header *)rinfo->typelib->data; g_info_init ((GIRealInfo*)arg, GI_INFO_TYPE_ARG, rinfo->repository, (GIBaseInfo*)info, rinfo->typelib, offset + header->signature_blob_size + n * header->arg_blob_size); @@ -992,7 +1045,12 @@ GIDirection g_arg_info_get_direction (GIArgInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_ARG_INFO (info), -1); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->in && blob->out) return GI_DIRECTION_INOUT; @@ -1015,7 +1073,12 @@ gboolean g_arg_info_is_return_value (GIArgInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->return_value; } @@ -1035,7 +1098,12 @@ gboolean g_arg_info_is_caller_allocates (GIArgInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->caller_allocates; } @@ -1052,7 +1120,12 @@ gboolean g_arg_info_is_optional (GIArgInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->optional; } @@ -1069,7 +1142,12 @@ gboolean g_arg_info_may_be_null (GIArgInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->allow_none; } @@ -1087,7 +1165,12 @@ GITransfer g_arg_info_get_ownership_transfer (GIArgInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_ARG_INFO (info), -1); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->transfer_ownership) return GI_TRANSFER_EVERYTHING; @@ -1112,7 +1195,12 @@ GIScopeType g_arg_info_get_scope (GIArgInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_ARG_INFO (info), -1); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->scope; } @@ -1130,7 +1218,12 @@ gint g_arg_info_get_closure (GIArgInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_ARG_INFO (info), -1); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->closure; } @@ -1148,7 +1241,12 @@ gint g_arg_info_get_destroy (GIArgInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_ARG_INFO (info), -1); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->destroy; } @@ -1167,6 +1265,9 @@ g_arg_info_get_type (GIArgInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_ARG_INFO (info), NULL); + return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type)); } @@ -1186,6 +1287,10 @@ g_arg_info_load_type (GIArgInfo *info, GITypeInfo *type) { GIRealInfo *rinfo = (GIRealInfo*) info; + + g_return_if_fail (info != NULL); + g_return_if_fail (GI_IS_ARG_INFO (info)); + g_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type)); } From a8eff27124ec05af78d3850d2d97281b23be9127 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 28 May 2010 08:49:49 -0300 Subject: [PATCH 290/692] Remove leftover function --- girepository.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/girepository.h b/girepository.h index deea9d3f7..f6e4d9eb2 100644 --- a/girepository.h +++ b/girepository.h @@ -388,9 +388,6 @@ GIBaseInfo * g_base_info_get_container (GIBaseInfo *info); GTypelib * g_base_info_get_typelib (GIBaseInfo *info); gboolean g_base_info_equal (GIBaseInfo *info1, GIBaseInfo *info2); -gboolean g_base_info_is_a (GIBaseInfo *info, - GIInfoType type); - GIBaseInfo * g_info_new (GIInfoType type, GIBaseInfo *container, GTypelib *typelib, From c2b89be46ea475904511c2da4d0000444c8c6ca0 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 28 May 2010 13:47:48 -0300 Subject: [PATCH 291/692] [GITypeInfo] Document and check type Document GITypeInfo and check the info type in all functions. --- ginfo.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 160 insertions(+), 11 deletions(-) diff --git a/ginfo.c b/ginfo.c index a104b9af1..7d07bac61 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1209,7 +1209,7 @@ g_arg_info_get_scope (GIArgInfo *info) * g_arg_info_get_closure: * @info: a #GIArgInfo * - * Obtains the index of the user data argument. This is only valid + * Obtain the index of the user data argument. This is only valid * for arguments which are callbacks. * * Returns: index of the user data argument or -1 if there is none @@ -1276,7 +1276,7 @@ g_arg_info_get_type (GIArgInfo *info) * @info: a #GIArgInfo * @type: (out caller-allocates): Initialized with information about type of @info * - * Get information about a the type of given argument @info; this + * Obtain information about a the type of given argument @info; this * function is a variant of g_arg_info_get_type() designed for stack * allocation. * @@ -1295,11 +1295,42 @@ g_arg_info_load_type (GIArgInfo *info, } /* GITypeInfo functions */ + +/** + * SECTION:gitypeinfo + * @Short_description: Struct representing a type + * @Title: GITypeInfo + * + * GITypeInfo represents a type. You can retrieve a type info from + * an argument (see #GIArgInfo), a functions return value (see #GIFunctionInfo), + * a field (see #GIFieldInfo), a property (see #GIPropertyInfo), a constant + * (see #GIConstantInfo) or for a union discriminator (see #GIUnionInfo). + * + * A type can either be a of a basic type which is a standard C primitive + * type or an interface type. For interface types you need to call + * g_type_info_get_interface() to get a reference to the base info for that + * interface. + * + */ + +/** + * g_type_info_is_pointer: + * @info: a #GITypeInfo + * + * Obtain if the type is passed as a reference. + * + * Returns: %TRUE if it is a pointer + */ gboolean g_type_info_is_pointer (GITypeInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), FALSE); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (type->flags.reserved == 0 && type->flags.reserved2 == 0) return type->flags.pointer; @@ -1311,11 +1342,25 @@ g_type_info_is_pointer (GITypeInfo *info) } } +/** + * g_type_info_get_tag: + * @info: a #GITypeInfo + * + * Obtain the type tag for the type. See #GITypeTag for a list + * of type tags. + * + * Returns: the type tag + */ GITypeTag g_type_info_get_tag (GITypeInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, GI_TYPE_TAG_BOOLEAN); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), GI_TYPE_TAG_BOOLEAN); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (rinfo->type_is_embedded) return GI_TYPE_TAG_INTERFACE; @@ -1329,12 +1374,26 @@ g_type_info_get_tag (GITypeInfo *info) } } +/** + * g_type_info_get_param_type: + * @info: a #GITypeInfo + * @n: index of the parameter + * + * Obtain the parameter type @n. + * + * Returns: the param type info + */ GITypeInfo * g_type_info_get_param_type (GITypeInfo *info, gint n) { GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), NULL); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { @@ -1375,6 +1434,9 @@ g_type_info_get_interface (GITypeInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), NULL); + /* For embedded types, the given offset is a pointer to the actual blob, * after the end of the field. In that case we know it's a "subclass" of * CommonBlob, so use that to determine the info type. @@ -1411,11 +1473,25 @@ g_type_info_get_interface (GITypeInfo *info) return NULL; } +/** + * g_type_info_get_array_length: + * @info: a #GITypeInfo + * + * Obtain the array length of the type. The type tag must be a + * #GI_TYPE_TAG_ARRAY or -1 will returned. + * + * Returns: the array length, or -1 if the type is not an array + */ gint g_type_info_get_array_length (GITypeInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), -1); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { @@ -1431,11 +1507,25 @@ g_type_info_get_array_length (GITypeInfo *info) return -1; } +/** + * g_type_info_get_array_fixed_size: + * @info: a #GITypeInfo + * + * Obtain the fixed array size of the type. The type tag must be a + * #GI_TYPE_TAG_ARRAY or -1 will returned. + * + * Returns: the size or -1 if it's not an array + */ gint g_type_info_get_array_fixed_size (GITypeInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), 0); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { @@ -1451,11 +1541,25 @@ g_type_info_get_array_fixed_size (GITypeInfo *info) return -1; } +/** + * g_type_info_is_zero_terminated: + * @info: a #GITypeInfo + * + * Obtain if the last element of the array is %NULL. The type tag must be a + * #GI_TYPE_TAG_ARRAY or %FALSE will returned. + * + * Returns: %TRUE if zero terminated + */ gboolean g_type_info_is_zero_terminated (GITypeInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), FALSE); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { @@ -1468,11 +1572,26 @@ g_type_info_is_zero_terminated (GITypeInfo *info) return FALSE; } +/** + * g_type_info_get_array_type: + * @info: a #GITypeInfo + * + * Obtain the array type for this type. See #GIArrayType for a list of + * possible values. If the type tag of this type is not array, -1 will be + * returned. + * + * Returns: the array type or -1 + */ GIArrayType g_type_info_get_array_type (GITypeInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), -1); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { @@ -1485,11 +1604,25 @@ g_type_info_get_array_type (GITypeInfo *info) return -1; } +/** + * g_type_info_get_n_error_domains: + * @info: a #GITypeInfo + * + * Obtain the number of error domains for this type. The type tag + * must be a #GI_TYPE_TAG_ERROR or -1 will be returned. + * + * Returns: number of error domains or -1 + */ gint g_type_info_get_n_error_domains (GITypeInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), 0); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { @@ -1502,12 +1635,28 @@ g_type_info_get_n_error_domains (GITypeInfo *info) return 0; } +/** + * g_type_info_get_error_domain: + * @info: a #GITypeInfo + * @n: index of error domain + * + * Obtain the error domains at index @n for this type. The type tag + * must be a #GI_TYPE_TAG_ERROR or -1 will be returned. + * + * Returns: (transfer full): the error domain or %NULL if type tag is wrong, + * free the struct withg_base_info_unref() when done. + */ GIErrorDomainInfo * g_type_info_get_error_domain (GITypeInfo *info, gint n) { GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), NULL); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) { From 3bab700cd4ffcce4f7a2c2dfb44d204eaeedfd8c Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 28 May 2010 20:49:39 -0300 Subject: [PATCH 292/692] [doc] Document GIErrorDomainInfo methods --- ginfo.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/ginfo.c b/ginfo.c index 7d07bac61..cad4635b3 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1644,7 +1644,7 @@ g_type_info_get_n_error_domains (GITypeInfo *info) * must be a #GI_TYPE_TAG_ERROR or -1 will be returned. * * Returns: (transfer full): the error domain or %NULL if type tag is wrong, - * free the struct withg_base_info_unref() when done. + * free the struct with g_base_info_unref() when done. */ GIErrorDomainInfo * g_type_info_get_error_domain (GITypeInfo *info, @@ -1673,20 +1673,61 @@ g_type_info_get_error_domain (GITypeInfo *info, /* GIErrorDomainInfo functions */ + +/** + * SECTION:gierrordomaininfo + * @Short_description: Struct representing an error domain + * @Title: GIErrorDomainInfo + * + * A GIErrorDomainInfo struct represents a domain of a #GError. + * An error domain is associated with a #GQuark and contains a pointer + * to an enum with all the error codes. + */ + +/** + * g_error_domain_info_get_quark: + * @info: a #GIErrorDomainInfo + * + * Obtain a string representing the quark for this error domain. + * %NULL will be returned if the type tag is wrong or if a quark is + * missing in the typelib. + * + * Returns: the quark represented as a string or %NULL + */ const gchar * g_error_domain_info_get_quark (GIErrorDomainInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ErrorDomainBlob *blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset]; + ErrorDomainBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_ERROR_DOMAIN_INFO (info), NULL); + + blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset]; return g_typelib_get_string (rinfo->typelib, blob->get_quark); } +/** + * g_error_domain_info_get_codes: + * @info: a #GIErrorDomainInfo + * + * Obtain the enum containing all the error codes for this error domain. + * The return value will have a #GIInfoType of %GI_INFO_TYPE_ERROR_DOMAIN + * + * Returns: (transfer full): the error domain or %NULL if type tag is wrong, + * free the struct with g_base_info_unref() when done. + */ GIInterfaceInfo * g_error_domain_info_get_codes (GIErrorDomainInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ErrorDomainBlob *blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset]; + ErrorDomainBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_ERROR_DOMAIN_INFO (info), NULL); + + blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset]; return (GIInterfaceInfo *) g_info_from_entry (rinfo->repository, rinfo->typelib, blob->error_codes); From a6c822d505d03f5c74ac60a2d41d272993d21640 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 28 May 2010 20:49:54 -0300 Subject: [PATCH 293/692] [build] Remove gcov support It's been broken for some time, remove it instead of letting it bitrot. --- Makefile.am | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index 770dceb7f..b7b1a9751 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,3 @@ -include $(top_srcdir)/gcov.mak - -GCOVSOURCES = $(libgirepository_1_0_la_SOURCES) - girepodir = $(includedir)/gobject-introspection-1.0/ girepo_HEADERS = girepository.h girffi.h From 81a263edfe53f9900b30f626dcac047ba9064311 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 30 May 2010 21:55:45 -0300 Subject: [PATCH 294/692] [info] Fix-up prototype indentation --- ginfo.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ginfo.c b/ginfo.c index cad4635b3..0d2c0e589 100644 --- a/ginfo.c +++ b/ginfo.c @@ -550,10 +550,10 @@ find_first_attribute (GIRealInfo *rinfo) * Returns: %TRUE if there are more attributes */ gboolean -g_base_info_iterate_attributes (GIBaseInfo *info, - GIAttributeIter *iterator, - gchar **name, - gchar **value) +g_base_info_iterate_attributes (GIBaseInfo *info, + GIAttributeIter *iterator, + gchar **name, + gchar **value) { GIRealInfo *rinfo = (GIRealInfo *)info; Header *header = (Header *)rinfo->typelib->data; @@ -1283,7 +1283,7 @@ g_arg_info_get_type (GIArgInfo *info) * The initialized @type must not be referenced after @info is deallocated. */ void -g_arg_info_load_type (GIArgInfo *info, +g_arg_info_load_type (GIArgInfo *info, GITypeInfo *type) { GIRealInfo *rinfo = (GIRealInfo*) info; @@ -1385,7 +1385,7 @@ g_type_info_get_tag (GITypeInfo *info) */ GITypeInfo * g_type_info_get_param_type (GITypeInfo *info, - gint n) + gint n) { GIRealInfo *rinfo = (GIRealInfo *)info; SimpleTypeBlob *type; From 58ac4f880a7c3e6bea8bab0a79154aa722211dc6 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 30 May 2010 21:55:55 -0300 Subject: [PATCH 295/692] [ginfo] Document enum and enum values Document GIEnumInfo and GIValueInfo --- ginfo.c | 163 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 117 insertions(+), 46 deletions(-) diff --git a/ginfo.c b/ginfo.c index 0d2c0e589..198bf6e0d 100644 --- a/ginfo.c +++ b/ginfo.c @@ -1734,17 +1734,132 @@ g_error_domain_info_get_codes (GIErrorDomainInfo *info) } -/* GIValueInfo functions */ +/* GIEnumInfo and GIValueInfo functions */ + +/** + * SECTION:gienuminfo + * @Short_description: Structs representing an enumeration and its values + * @Title: GIEnumInfo + * + * A GIEnumInfo represents an enumeration and a GIValueInfo struct represents a value + * of an enumeration. The GIEnumInfo contains a set of values and a type + * The GIValueInfo is fetched by calling g_enum_info_get_value() on a #GIEnumInfo. + */ + +/** +* g_enum_info_get_n_values: +* @info: a #GIEnumInfo +* +* Obtain the number of values this enumeration contains. +* +* Returns: the number of enumeration values +*/ +gint +g_enum_info_get_n_values (GIEnumInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + EnumBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_ENUM_INFO (info), 0); + + blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_values; +} + +/** + * g_enum_info_get_value: + * @info: a #GIEnumInfo + * @n: index of value to fetch + * + * Obtain a value for this enumeration. + * + * Returns: (transfer full): the enumeration value or %NULL if type tag is wrong, + * free the struct with g_base_info_unref() when done. + */ +GIValueInfo * +g_enum_info_get_value (GIEnumInfo *info, + gint n) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header; + gint offset; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_ENUM_INFO (info), NULL); + + header = (Header *)rinfo->typelib->data; + offset = rinfo->offset + header->enum_blob_size + + n * header->value_blob_size; + + return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, (GIBaseInfo*)info, rinfo->typelib, offset); +} + +/** + * g_enum_info_get_storage_type: + * @info: a #GIEnumInfo + * + * Obtain the tag of the type used for the enum in the C ABI. This will + * will be a signed or unsigned integral type. + + * Note that in the current implementation the width of the type is + * computed correctly, but the signed or unsigned nature of the type + * may not match the sign of the type used by the C compiler. + * + * Return Value: the storage type for the enumeration + */ +GITypeTag +g_enum_info_get_storage_type (GIEnumInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + EnumBlob *blob; + + g_return_val_if_fail (info != NULL, GI_TYPE_TAG_BOOLEAN); + g_return_val_if_fail (GI_IS_ENUM_INFO (info), GI_TYPE_TAG_BOOLEAN); + + blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->storage_type; +} + +/** + * g_value_info_get_value: + * @info: a #GIValueInfo + * + * Obtain the enumeration value of the #GIValueInfo. + * + * Returns: the enumeration value + */ glong g_value_info_get_value (GIValueInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ValueBlob *blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset]; + ValueBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_VALUE_INFO (info), -1); + + blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset]; return (glong)blob->value; } /* GIFieldInfo functions */ + +/** + * SECTION:gifieldinfo + * @Short_description: Struct representing a struct or union field + * @Title: GIFieldInfo + * + * A GIFieldInfo struct represents a field of a struct (see #GIStructInfo), + * union (see #GIUnionInfo) or an object (see #GIObjectInfo). The GIFieldInfo + * is fetched by calling g_struct_info_get_field(), g_union_info_get_field() + * or g_object_info_get_value(). + * A field has a size, type and a struct offset asssociated and a set of flags, + * which is currently #GI_FIELD_IS_READABLE or #GI_FIELD_IS_WRITABLE. + */ + GIFieldInfoFlags g_field_info_get_flags (GIFieldInfo *info) { @@ -2002,50 +2117,6 @@ g_struct_info_is_gtype_struct (GIStructInfo *info) return blob->is_gtype_struct; } -gint -g_enum_info_get_n_values (GIEnumInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - EnumBlob *blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_values; -} - -GIValueInfo * -g_enum_info_get_value (GIEnumInfo *info, - gint n) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - gint offset; - - offset = rinfo->offset + header->enum_blob_size - + n * header->value_blob_size; - return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, (GIBaseInfo*)info, rinfo->typelib, offset); -} - -/** - * g_enum_info_get_storage_type: - * @info: a #GIEnumInfo - * - * Gets the tag of the type used for the enum in the C ABI. This will - * will be a signed or unsigned integral type. - - * Note that in the current implementation the width of the type is - * computed correctly, but the signed or unsigned nature of the type - * may not match the sign of the type used by the C compiler. - * - * Return Value: the storage type for the enumeration - */ -GITypeTag -g_enum_info_get_storage_type (GIEnumInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - EnumBlob *blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->storage_type; -} - /* GIObjectInfo functions */ GIObjectInfo * g_object_info_get_parent (GIObjectInfo *info) From 7a383b6126aac8e54b45c9e91e401fe0a95ec78f Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 30 May 2010 21:56:25 -0300 Subject: [PATCH 296/692] [girepository] Correct GI_IS_ENUM_INFO macro A GIEnumInfo represents either an enum or a set of flags --- girepository.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/girepository.h b/girepository.h index f6e4d9eb2..30e9b83d8 100644 --- a/girepository.h +++ b/girepository.h @@ -786,7 +786,8 @@ GType g_registered_type_info_get_g_type (GIRegisteredTypeInf /* GIEnumInfo */ #define GI_IS_ENUM_INFO(info) \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ENUM) + ((g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ENUM) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FLAGS)) gint g_enum_info_get_n_values (GIEnumInfo *info); GIValueInfo * g_enum_info_get_value (GIEnumInfo *info, From 67126e38d4b0180369fbf0183b460a10258b110f Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Mon, 31 May 2010 17:41:45 -0300 Subject: [PATCH 297/692] [girepository] Split out GIBaseInfo Split out GIBaseInfo to a separate source file. Move out definitions to gibaseinfo.h/gitypelib.h/gitypes.h and girepository-private.h Install gibaseinfo.h/gitypelib.h and gitypes.h as well, but require users to include girepository.h --- Makefile.am | 9 +- gibaseinfo.c | 591 +++++++++++++++++++++++++++++++++++++ gibaseinfo.h | 88 ++++++ ginfo.c | 642 ++--------------------------------------- girepository-private.h | 84 ++++++ girepository.h | 259 +---------------- gitypelib.h | 53 ++++ gitypes.h | 225 +++++++++++++++ 8 files changed, 1075 insertions(+), 876 deletions(-) create mode 100644 gibaseinfo.c create mode 100644 gibaseinfo.h create mode 100644 girepository-private.h create mode 100644 gitypelib.h create mode 100644 gitypes.h diff --git a/Makefile.am b/Makefile.am index b7b1a9751..ac95ed661 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,10 @@ girepodir = $(includedir)/gobject-introspection-1.0/ -girepo_HEADERS = girepository.h girffi.h +girepo_HEADERS = \ + gibaseinfo.h \ + girepository.h \ + girffi.h \ + gitypelib.h \ + gitypes.h lib_LTLIBRARIES = libgirepository-1.0.la noinst_LTLIBRARIES = libgirepository-parser.la @@ -7,10 +12,12 @@ noinst_LTLIBRARIES = libgirepository-parser.la libgirepository_1_0_la_SOURCES = \ gdump.c \ gfield.c \ + gibaseinfo.c \ ginfo.c \ ginfo.h \ ginvoke.c \ girepository.c \ + girepository-private.h \ girffi.c \ girffi.h \ girffi-private.h \ diff --git a/gibaseinfo.c b/gibaseinfo.c new file mode 100644 index 000000000..006dd8f55 --- /dev/null +++ b/gibaseinfo.c @@ -0,0 +1,591 @@ +/* GObject introspection: Repository implementation + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 + +#include "gtypelib.h" +#include "ginfo.h" +#include "girepository-private.h" + +#define INVALID_REFCOUNT 0x7FFFFFFF + +/* info creation */ +GIBaseInfo * +g_info_new_full (GIInfoType type, + GIRepository *repository, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset) +{ + GIRealInfo *info; + + g_return_val_if_fail (container != NULL || repository != NULL, NULL); + + info = g_slice_new (GIRealInfo); + + _g_info_init (info, type, repository, container, typelib, offset); + info->ref_count = 1; + + if (container && ((GIRealInfo *) container)->ref_count != INVALID_REFCOUNT) + g_base_info_ref (info->container); + + g_object_ref (info->repository); + + return (GIBaseInfo*)info; +} + +GIBaseInfo * +g_info_new (GIInfoType type, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset) +{ + return g_info_new_full (type, ((GIRealInfo*)container)->repository, container, typelib, offset); +} + +void +_g_info_init (GIRealInfo *info, + GIInfoType type, + GIRepository *repository, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset) +{ + memset (info, 0, sizeof (GIRealInfo)); + + /* Invalid refcount used to flag stack-allocated infos */ + info->ref_count = INVALID_REFCOUNT; + info->type = type; + + info->typelib = typelib; + info->offset = offset; + + if (container) + info->container = container; + + g_assert (G_IS_IREPOSITORY (repository)); + info->repository = repository; +} + +GIBaseInfo * +_g_info_from_entry (GIRepository *repository, + GTypelib *typelib, + guint16 index) +{ + GIBaseInfo *result; + DirEntry *entry = g_typelib_get_dir_entry (typelib, index); + + if (entry->local) + result = g_info_new_full (entry->blob_type, repository, NULL, typelib, entry->offset); + else + { + const gchar *namespace = g_typelib_get_string (typelib, entry->offset); + const gchar *name = g_typelib_get_string (typelib, entry->name); + + result = g_irepository_find_by_name (repository, namespace, name); + if (result == NULL) + { + GIUnresolvedInfo *unresolved; + + unresolved = g_slice_new0 (GIUnresolvedInfo); + + unresolved->type = GI_INFO_TYPE_UNRESOLVED; + unresolved->ref_count = 1; + unresolved->repository = g_object_ref (repository); + unresolved->container = NULL; + unresolved->name = name; + unresolved->namespace = namespace; + + return (GIBaseInfo *)unresolved; + } + return (GIBaseInfo *)result; + } + + return (GIBaseInfo *)result; +} + +/* GIBaseInfo functions */ + +/** + * SECTION:gibaseinfo + * @Short_description: Base struct for all GTypelib structs + * @Title: GIBaseInfo + * + * GIBaseInfo is the common base struct of all other *Info structs + * accessible through the #GIRepository API. + * All other structs can be casted to a #GIBaseInfo, for instance: + * + * Casting a #GIFunctionInfo to #GIBaseInfo + * + * GIFunctionInfo *function_info = ...; + * GIBaseInfo *info = (GIBaseInfo*)function_info; + * + * + * Most #GIRepository APIs returning a #GIBaseInfo is actually creating a new struct, in other + * words, g_base_info_unref() has to be called when done accessing the data. + * GIBaseInfos are normally accessed by calling either + * g_irepository_find_by_name(), g_irepository_find_by_gtype() or g_irepository_get_info(). + * + * + * Getting the Button of the Gtk typelib + * + * GIBaseInfo *button_info = g_irepository_find_by_name(NULL, "Gtk", "Button"); + * ... use button_info ... + * g_base_info_unref(button_info); + * + * + * + */ + +/** + * g_base_info_ref: + * @info: a #GIBaseInfo + * + * Increases the reference count of @info. + * + * Returns: the same @info. + */ +GIBaseInfo * +g_base_info_ref (GIBaseInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo*)info; + + g_assert (rinfo->ref_count != INVALID_REFCOUNT); + ((GIRealInfo*)info)->ref_count++; + + return info; +} + +/** + * g_base_info_unref: + * @info: a #GIBaseInfo + * + * Decreases the reference count of @info. When its reference count + * drops to 0, the info is freed. + */ +void +g_base_info_unref (GIBaseInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo*)info; + + g_assert (rinfo->ref_count > 0 && rinfo->ref_count != INVALID_REFCOUNT); + rinfo->ref_count--; + + if (!rinfo->ref_count) + { + if (rinfo->container && ((GIRealInfo *) rinfo->container)->ref_count != INVALID_REFCOUNT) + g_base_info_unref (rinfo->container); + + if (rinfo->repository) + g_object_unref (rinfo->repository); + + g_slice_free (GIRealInfo, rinfo); + } +} + +/** + * g_base_info_get_type: + * @info: a #GIBaseInfo + * + * Obtain the info type of the GIBaseInfo. + * + * Returns: the info type of @info + */ +GIInfoType +g_base_info_get_type (GIBaseInfo *info) +{ + + return ((GIRealInfo*)info)->type; +} + +/** + * g_base_info_get_name: + * @info: a #GIBaseInfo + * + * Obtain the name of the @info. What the name represents depends on + * the #GIInfoType of the @info. For instance for #GIFunctionInfo it is + * the name of the function. + * + * Returns: the name of @info or %NULL if it lacks a name. + */ +const gchar * +g_base_info_get_name (GIBaseInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo*)info; + g_assert (rinfo->ref_count > 0); + switch (rinfo->type) + { + case GI_INFO_TYPE_FUNCTION: + case GI_INFO_TYPE_CALLBACK: + case GI_INFO_TYPE_STRUCT: + case GI_INFO_TYPE_BOXED: + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + case GI_INFO_TYPE_OBJECT: + case GI_INFO_TYPE_INTERFACE: + case GI_INFO_TYPE_CONSTANT: + case GI_INFO_TYPE_ERROR_DOMAIN: + case GI_INFO_TYPE_UNION: + { + CommonBlob *blob = (CommonBlob *)&rinfo->typelib->data[rinfo->offset]; + + return g_typelib_get_string (rinfo->typelib, blob->name); + } + break; + + case GI_INFO_TYPE_VALUE: + { + ValueBlob *blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset]; + + return g_typelib_get_string (rinfo->typelib, blob->name); + } + break; + + case GI_INFO_TYPE_SIGNAL: + { + SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; + + return g_typelib_get_string (rinfo->typelib, blob->name); + } + break; + + case GI_INFO_TYPE_PROPERTY: + { + PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset]; + + return g_typelib_get_string (rinfo->typelib, blob->name); + } + break; + + case GI_INFO_TYPE_VFUNC: + { + VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; + + return g_typelib_get_string (rinfo->typelib, blob->name); + } + break; + + case GI_INFO_TYPE_FIELD: + { + FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; + + return g_typelib_get_string (rinfo->typelib, blob->name); + } + break; + + case GI_INFO_TYPE_ARG: + { + ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + + return g_typelib_get_string (rinfo->typelib, blob->name); + } + break; + case GI_INFO_TYPE_UNRESOLVED: + { + GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info; + + return unresolved->name; + } + break; + case GI_INFO_TYPE_TYPE: + default: ; + g_assert_not_reached (); + /* unnamed */ + } + + return NULL; +} + +/** + * g_base_info_get_namespace: + * @info: a #GIBaseInfo + * + * Obtain the namespace of @info. + * + * Returns: the namespace + */ +const gchar * +g_base_info_get_namespace (GIBaseInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo*) info; + Header *header = (Header *)rinfo->typelib->data; + + g_assert (rinfo->ref_count > 0); + + if (rinfo->type == GI_INFO_TYPE_UNRESOLVED) + { + GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info; + + return unresolved->namespace; + } + + return g_typelib_get_string (rinfo->typelib, header->namespace); +} + +/** + * g_base_info_is_deprecated: + * @info: a #GIBaseInfo + * + * Obtain whether the @info is represents a metadata which is + * deprecated or not. + * + * Returns: %TRUE if deprecated + */ +gboolean +g_base_info_is_deprecated (GIBaseInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo*) info; + switch (rinfo->type) + { + case GI_INFO_TYPE_FUNCTION: + case GI_INFO_TYPE_CALLBACK: + case GI_INFO_TYPE_STRUCT: + case GI_INFO_TYPE_BOXED: + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + case GI_INFO_TYPE_OBJECT: + case GI_INFO_TYPE_INTERFACE: + case GI_INFO_TYPE_CONSTANT: + case GI_INFO_TYPE_ERROR_DOMAIN: + { + CommonBlob *blob = (CommonBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->deprecated; + } + break; + + case GI_INFO_TYPE_VALUE: + { + ValueBlob *blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->deprecated; + } + break; + + case GI_INFO_TYPE_SIGNAL: + { + SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->deprecated; + } + break; + + case GI_INFO_TYPE_PROPERTY: + { + PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->deprecated; + } + break; + + case GI_INFO_TYPE_VFUNC: + case GI_INFO_TYPE_FIELD: + case GI_INFO_TYPE_ARG: + case GI_INFO_TYPE_TYPE: + default: ; + /* no deprecation flag for these */ + } + + return FALSE; +} + +/** + * g_base_info_get_attribute: + * @info: a #GIBaseInfo + * @name: a freeform string naming an attribute + * + * Retrieve an arbitrary attribute associated with this node. + * + * Returns: The value of the attribute, or %NULL if no such attribute exists + */ +const gchar * +g_base_info_get_attribute (GIBaseInfo *info, + const gchar *name) +{ + GIAttributeIter iter = { 0, }; + gchar *curname, *curvalue; + while (g_base_info_iterate_attributes (info, &iter, &curname, &curvalue)) + { + if (strcmp (name, curname) == 0) + return (const gchar*) curvalue; + } + + return NULL; +} + +static int +cmp_attribute (const void *av, + const void *bv) +{ + const AttributeBlob *a = av; + const AttributeBlob *b = bv; + + if (a->offset < b->offset) + return -1; + else if (a->offset == b->offset) + return 0; + else + return 1; +} + +static AttributeBlob * +find_first_attribute (GIRealInfo *rinfo) +{ + Header *header = (Header *)rinfo->typelib->data; + AttributeBlob blob, *first, *res, *previous; + + blob.offset = rinfo->offset; + + first = (AttributeBlob *) &rinfo->typelib->data[header->attributes]; + + res = bsearch (&blob, first, header->n_attributes, + header->attribute_blob_size, cmp_attribute); + + if (res == NULL) + return NULL; + + previous = res - 1; + while (previous >= first && previous->offset == rinfo->offset) + { + res = previous; + previous = res - 1; + } + + return res; +} + +/** + * g_base_info_iterate_attributes: + * @info: a #GIBaseInfo + * @iterator: a #GIAttributeIter structure, must be initialized; see below + * @name: (out) (transfer none): Returned name, must not be freed + * @value: (out) (transfer none): Returned name, must not be freed + * + * Iterate over all attributes associated with this node. The iterator + * structure is typically stack allocated, and must have its first + * member initialized to %NULL. + * + * Both the @name and @value should be treated as constants + * and must not be freed. + * + * + * Iterating over attributes + * + * void + * print_attributes (GIBaseInfo *info) + * { + * GIAttributeIter iter = { 0, }; + * char *name; + * char *value; + * while (g_base_info_iterate_attributes (info, &iter, &name, &value)) + * { + * g_print ("attribute name: %s value: %s", name, value); + * } + * } + * + * + * + * Returns: %TRUE if there are more attributes + */ +gboolean +g_base_info_iterate_attributes (GIBaseInfo *info, + GIAttributeIter *iterator, + gchar **name, + gchar **value) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + AttributeBlob *next, *after; + + after = (AttributeBlob *) &rinfo->typelib->data[header->attributes + + header->n_attributes * header->attribute_blob_size]; + + if (iterator->data != NULL) + next = (AttributeBlob *) iterator->data; + else + next = find_first_attribute (rinfo); + + if (next == NULL || next->offset != rinfo->offset || next >= after) + return FALSE; + + *name = (gchar*) g_typelib_get_string (rinfo->typelib, next->name); + *value = (gchar*) g_typelib_get_string (rinfo->typelib, next->value); + iterator->data = next + 1; + + return TRUE; +} + +/** + * g_base_info_get_container: + * @info: a #GIBaseInfo + * + * Obtain the container of the @info. The container is the parent + * GIBaseInfo. For instance, the parent of a #GIFunctionInfo is an + * #GIObjectInfo or #GIInterfaceInfo. + * + * Returns: (transfer none): the container + */ +GIBaseInfo * +g_base_info_get_container (GIBaseInfo *info) +{ + return ((GIRealInfo*)info)->container; +} + +/** + * g_base_info_get_typelib: + * @info: a #GIBaseInfo + * + * Obtain the typelib this @info belongs to + * + * Returns: (transfer none): the typelib. + */ +GTypelib * +g_base_info_get_typelib (GIBaseInfo *info) +{ + return ((GIRealInfo*)info)->typelib; +} + +/** + * g_base_info_equal: + * @info1: a #GIBaseInfo + * @info2: a #GIBaseInfo + * + * Compare two #GIBaseInfo. + * + * Using pointer comparison is not practical since many functions return + * different instances of #GIBaseInfo that refers to the same part of the + * TypeLib; use this function instead to do #GIBaseInfo comparisons. + * + * Returns: %TRUE if and only if @info1 equals @info2. + */ +gboolean +g_base_info_equal (GIBaseInfo *info1, GIBaseInfo *info2) +{ + /* Compare the TypeLib pointers, which are mmapped. */ + GIRealInfo *rinfo1 = (GIRealInfo*)info1; + GIRealInfo *rinfo2 = (GIRealInfo*)info2; + return rinfo1->typelib->data + rinfo1->offset == rinfo2->typelib->data + rinfo2->offset; +} + diff --git a/gibaseinfo.h b/gibaseinfo.h new file mode 100644 index 000000000..f4bd731cd --- /dev/null +++ b/gibaseinfo.h @@ -0,0 +1,88 @@ +/* GObject introspection: GIBaseInfo + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GIBASEINFO_H__ +#define __GIBASEINFO_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include +#include + +G_BEGIN_DECLS + +struct _GIBaseInfoStub { + /* */ + gint32 dummy1; + gint32 dummy2; + gpointer dummy3; + gpointer dummy4; + gpointer dummy5; + guint32 dummy6; + guint32 dummy7; + gpointer padding[4]; +}; + +/* GIBaseInfo */ + +/** + * GIAttributeIter: + * + * An opaque structure used to iterate over attributes + * in a #GIBaseInfo struct. + */ +typedef struct { + /* */ + gpointer data; + gpointer data2; + gpointer data3; + gpointer data4; +} GIAttributeIter; + +GIBaseInfo * g_base_info_ref (GIBaseInfo *info); +void g_base_info_unref (GIBaseInfo *info); +GIInfoType g_base_info_get_type (GIBaseInfo *info); +const gchar * g_base_info_get_name (GIBaseInfo *info); +const gchar * g_base_info_get_namespace (GIBaseInfo *info); +gboolean g_base_info_is_deprecated (GIBaseInfo *info); +const gchar * g_base_info_get_attribute (GIBaseInfo *info, + const gchar *name); +gboolean g_base_info_iterate_attributes (GIBaseInfo *info, + GIAttributeIter *iterator, + char **name, + char **value); +GIBaseInfo * g_base_info_get_container (GIBaseInfo *info); +GTypelib * g_base_info_get_typelib (GIBaseInfo *info); +gboolean g_base_info_equal (GIBaseInfo *info1, + GIBaseInfo *info2); +GIBaseInfo * g_info_new (GIInfoType type, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset); + + +G_END_DECLS + +#endif /* __GIBASEINFO_H__ */ + diff --git a/ginfo.c b/ginfo.c index 198bf6e0d..70482a5aa 100644 --- a/ginfo.c +++ b/ginfo.c @@ -27,607 +27,7 @@ #include "gtypelib.h" #include "ginfo.h" - -typedef struct _GIRealInfo GIRealInfo; - -/* - * We just use one structure for all of the info object - * types; in general, we should be reading data directly - * from the typelib, and not having computed data in - * per-type structures. - */ -struct _GIRealInfo -{ - /* Keep this part in sync with GIUnresolvedInfo below */ - gint32 type; - gint32 ref_count; - GIRepository *repository; - GIBaseInfo *container; - - /* Resolved specific */ - - GTypelib *typelib; - guint32 offset; - - guint32 type_is_embedded : 1; /* Used by GITypeInfo */ - guint32 reserved : 31; - - gpointer reserved2[4]; -}; - -struct _GIUnresolvedInfo -{ - /* Keep this part in sync with GIBaseInfo above */ - gint32 type; - gint32 ref_count; - GIRepository *repository; - GIBaseInfo *container; - - /* Unresolved specific */ - - const gchar *name; - const gchar *namespace; -}; - -#define INVALID_REFCOUNT 0x7FFFFFFF - -static void -g_info_init (GIRealInfo *info, - GIInfoType type, - GIRepository *repository, - GIBaseInfo *container, - GTypelib *typelib, - guint32 offset) -{ - memset (info, 0, sizeof (GIRealInfo)); - - /* Invalid refcount used to flag stack-allocated infos */ - info->ref_count = INVALID_REFCOUNT; - info->type = type; - - info->typelib = typelib; - info->offset = offset; - - if (container) - info->container = container; - - g_assert (G_IS_IREPOSITORY (repository)); - info->repository = repository; -} - -/* info creation */ -GIBaseInfo * -g_info_new_full (GIInfoType type, - GIRepository *repository, - GIBaseInfo *container, - GTypelib *typelib, - guint32 offset) -{ - GIRealInfo *info; - - g_return_val_if_fail (container != NULL || repository != NULL, NULL); - - info = g_slice_new (GIRealInfo); - - g_info_init (info, type, repository, container, typelib, offset); - info->ref_count = 1; - - if (container && ((GIRealInfo *) container)->ref_count != INVALID_REFCOUNT) - g_base_info_ref (info->container); - - g_object_ref (info->repository); - - return (GIBaseInfo*)info; -} - -GIBaseInfo * -g_info_new (GIInfoType type, - GIBaseInfo *container, - GTypelib *typelib, - guint32 offset) -{ - return g_info_new_full (type, ((GIRealInfo*)container)->repository, container, typelib, offset); -} - -static GIBaseInfo * -g_info_from_entry (GIRepository *repository, - GTypelib *typelib, - guint16 index) -{ - GIBaseInfo *result; - DirEntry *entry = g_typelib_get_dir_entry (typelib, index); - - if (entry->local) - result = g_info_new_full (entry->blob_type, repository, NULL, typelib, entry->offset); - else - { - const gchar *namespace = g_typelib_get_string (typelib, entry->offset); - const gchar *name = g_typelib_get_string (typelib, entry->name); - - result = g_irepository_find_by_name (repository, namespace, name); - if (result == NULL) - { - GIUnresolvedInfo *unresolved; - - unresolved = g_slice_new0 (GIUnresolvedInfo); - - unresolved->type = GI_INFO_TYPE_UNRESOLVED; - unresolved->ref_count = 1; - unresolved->repository = g_object_ref (repository); - unresolved->container = NULL; - unresolved->name = name; - unresolved->namespace = namespace; - - return (GIBaseInfo *)unresolved; - } - return (GIBaseInfo *)result; - } - - return (GIBaseInfo *)result; -} - -/* GIBaseInfo functions */ - -/** - * SECTION:gibaseinfo - * @Short_description: Base struct for all GTypelib structs - * @Title: GIBaseInfo - * - * GIBaseInfo is the common base struct of all other *Info structs - * accessible through the #GIRepository API. - * All other structs can be casted to a #GIBaseInfo, for instance: - * - * Casting a #GIFunctionInfo to #GIBaseInfo - * - * GIFunctionInfo *function_info = ...; - * GIBaseInfo *info = (GIBaseInfo*)function_info; - * - * - * Most #GIRepository APIs returning a #GIBaseInfo is actually creating a new struct, in other - * words, g_base_info_unref() has to be called when done accessing the data. - * GIBaseInfos are normally accessed by calling either - * g_irepository_find_by_name(), g_irepository_find_by_gtype() or g_irepository_get_info(). - * - * - * Getting the Button of the Gtk typelib - * - * GIBaseInfo *button_info = g_irepository_find_by_name(NULL, "Gtk", "Button"); - * ... use button_info ... - * g_base_info_unref(button_info); - * - * - * - */ - -/** - * g_base_info_ref: - * @info: a #GIBaseInfo - * - * Increases the reference count of @info. - * - * Returns: the same @info. - */ -GIBaseInfo * -g_base_info_ref (GIBaseInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo*)info; - - g_assert (rinfo->ref_count != INVALID_REFCOUNT); - ((GIRealInfo*)info)->ref_count++; - - return info; -} - -/** - * g_base_info_unref: - * @info: a #GIBaseInfo - * - * Decreases the reference count of @info. When its reference count - * drops to 0, the info is freed. - */ -void -g_base_info_unref (GIBaseInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo*)info; - - g_assert (rinfo->ref_count > 0 && rinfo->ref_count != INVALID_REFCOUNT); - rinfo->ref_count--; - - if (!rinfo->ref_count) - { - if (rinfo->container && ((GIRealInfo *) rinfo->container)->ref_count != INVALID_REFCOUNT) - g_base_info_unref (rinfo->container); - - if (rinfo->repository) - g_object_unref (rinfo->repository); - - g_slice_free (GIRealInfo, rinfo); - } -} - -/** - * g_base_info_get_type: - * @info: a #GIBaseInfo - * - * Obtain the info type of the GIBaseInfo. - * - * Returns: the info type of @info - */ -GIInfoType -g_base_info_get_type (GIBaseInfo *info) -{ - - return ((GIRealInfo*)info)->type; -} - -/** - * g_base_info_get_name: - * @info: a #GIBaseInfo - * - * Obtain the name of the @info. What the name represents depends on - * the #GIInfoType of the @info. For instance for #GIFunctionInfo it is - * the name of the function. - * - * Returns: the name of @info or %NULL if it lacks a name. - */ -const gchar * -g_base_info_get_name (GIBaseInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo*)info; - g_assert (rinfo->ref_count > 0); - switch (rinfo->type) - { - case GI_INFO_TYPE_FUNCTION: - case GI_INFO_TYPE_CALLBACK: - case GI_INFO_TYPE_STRUCT: - case GI_INFO_TYPE_BOXED: - case GI_INFO_TYPE_ENUM: - case GI_INFO_TYPE_FLAGS: - case GI_INFO_TYPE_OBJECT: - case GI_INFO_TYPE_INTERFACE: - case GI_INFO_TYPE_CONSTANT: - case GI_INFO_TYPE_ERROR_DOMAIN: - case GI_INFO_TYPE_UNION: - { - CommonBlob *blob = (CommonBlob *)&rinfo->typelib->data[rinfo->offset]; - - return g_typelib_get_string (rinfo->typelib, blob->name); - } - break; - - case GI_INFO_TYPE_VALUE: - { - ValueBlob *blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset]; - - return g_typelib_get_string (rinfo->typelib, blob->name); - } - break; - - case GI_INFO_TYPE_SIGNAL: - { - SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; - - return g_typelib_get_string (rinfo->typelib, blob->name); - } - break; - - case GI_INFO_TYPE_PROPERTY: - { - PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset]; - - return g_typelib_get_string (rinfo->typelib, blob->name); - } - break; - - case GI_INFO_TYPE_VFUNC: - { - VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; - - return g_typelib_get_string (rinfo->typelib, blob->name); - } - break; - - case GI_INFO_TYPE_FIELD: - { - FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; - - return g_typelib_get_string (rinfo->typelib, blob->name); - } - break; - - case GI_INFO_TYPE_ARG: - { - ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - - return g_typelib_get_string (rinfo->typelib, blob->name); - } - break; - case GI_INFO_TYPE_UNRESOLVED: - { - GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info; - - return unresolved->name; - } - break; - case GI_INFO_TYPE_TYPE: - default: ; - g_assert_not_reached (); - /* unnamed */ - } - - return NULL; -} - -/** - * g_base_info_get_namespace: - * @info: a #GIBaseInfo - * - * Obtain the namespace of @info. - * - * Returns: the namespace - */ -const gchar * -g_base_info_get_namespace (GIBaseInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo*) info; - Header *header = (Header *)rinfo->typelib->data; - - g_assert (rinfo->ref_count > 0); - - if (rinfo->type == GI_INFO_TYPE_UNRESOLVED) - { - GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info; - - return unresolved->namespace; - } - - return g_typelib_get_string (rinfo->typelib, header->namespace); -} - -/** - * g_base_info_is_deprecated: - * @info: a #GIBaseInfo - * - * Obtain whether the @info is represents a metadata which is - * deprecated or not. - * - * Returns: %TRUE if deprecated - */ -gboolean -g_base_info_is_deprecated (GIBaseInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo*) info; - switch (rinfo->type) - { - case GI_INFO_TYPE_FUNCTION: - case GI_INFO_TYPE_CALLBACK: - case GI_INFO_TYPE_STRUCT: - case GI_INFO_TYPE_BOXED: - case GI_INFO_TYPE_ENUM: - case GI_INFO_TYPE_FLAGS: - case GI_INFO_TYPE_OBJECT: - case GI_INFO_TYPE_INTERFACE: - case GI_INFO_TYPE_CONSTANT: - case GI_INFO_TYPE_ERROR_DOMAIN: - { - CommonBlob *blob = (CommonBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->deprecated; - } - break; - - case GI_INFO_TYPE_VALUE: - { - ValueBlob *blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->deprecated; - } - break; - - case GI_INFO_TYPE_SIGNAL: - { - SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->deprecated; - } - break; - - case GI_INFO_TYPE_PROPERTY: - { - PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->deprecated; - } - break; - - case GI_INFO_TYPE_VFUNC: - case GI_INFO_TYPE_FIELD: - case GI_INFO_TYPE_ARG: - case GI_INFO_TYPE_TYPE: - default: ; - /* no deprecation flag for these */ - } - - return FALSE; -} - -/** - * g_base_info_get_attribute: - * @info: a #GIBaseInfo - * @name: a freeform string naming an attribute - * - * Retrieve an arbitrary attribute associated with this node. - * - * Returns: The value of the attribute, or %NULL if no such attribute exists - */ -const gchar * -g_base_info_get_attribute (GIBaseInfo *info, - const gchar *name) -{ - GIAttributeIter iter = { 0, }; - gchar *curname, *curvalue; - while (g_base_info_iterate_attributes (info, &iter, &curname, &curvalue)) - { - if (strcmp (name, curname) == 0) - return (const gchar*) curvalue; - } - - return NULL; -} - -static int -cmp_attribute (const void *av, - const void *bv) -{ - const AttributeBlob *a = av; - const AttributeBlob *b = bv; - - if (a->offset < b->offset) - return -1; - else if (a->offset == b->offset) - return 0; - else - return 1; -} - -static AttributeBlob * -find_first_attribute (GIRealInfo *rinfo) -{ - Header *header = (Header *)rinfo->typelib->data; - AttributeBlob blob, *first, *res, *previous; - - blob.offset = rinfo->offset; - - first = (AttributeBlob *) &rinfo->typelib->data[header->attributes]; - - res = bsearch (&blob, first, header->n_attributes, - header->attribute_blob_size, cmp_attribute); - - if (res == NULL) - return NULL; - - previous = res - 1; - while (previous >= first && previous->offset == rinfo->offset) - { - res = previous; - previous = res - 1; - } - - return res; -} - -/** - * g_base_info_iterate_attributes: - * @info: a #GIBaseInfo - * @iterator: a #GIAttributeIter structure, must be initialized; see below - * @name: (out) (transfer none): Returned name, must not be freed - * @value: (out) (transfer none): Returned name, must not be freed - * - * Iterate over all attributes associated with this node. The iterator - * structure is typically stack allocated, and must have its first - * member initialized to %NULL. - * - * Both the @name and @value should be treated as constants - * and must not be freed. - * - * - * Iterating over attributes - * - * void - * print_attributes (GIBaseInfo *info) - * { - * GIAttributeIter iter = { 0, }; - * char *name; - * char *value; - * while (g_base_info_iterate_attributes (info, &iter, &name, &value)) - * { - * g_print ("attribute name: %s value: %s", name, value); - * } - * } - * - * - * - * Returns: %TRUE if there are more attributes - */ -gboolean -g_base_info_iterate_attributes (GIBaseInfo *info, - GIAttributeIter *iterator, - gchar **name, - gchar **value) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - AttributeBlob *next, *after; - - after = (AttributeBlob *) &rinfo->typelib->data[header->attributes + - header->n_attributes * header->attribute_blob_size]; - - if (iterator->data != NULL) - next = (AttributeBlob *) iterator->data; - else - next = find_first_attribute (rinfo); - - if (next == NULL || next->offset != rinfo->offset || next >= after) - return FALSE; - - *name = (gchar*) g_typelib_get_string (rinfo->typelib, next->name); - *value = (gchar*) g_typelib_get_string (rinfo->typelib, next->value); - iterator->data = next + 1; - - return TRUE; -} - -/** - * g_base_info_get_container: - * @info: a #GIBaseInfo - * - * Obtain the container of the @info. The container is the parent - * GIBaseInfo. For instance, the parent of a #GIFunctionInfo is an - * #GIObjectInfo or #GIInterfaceInfo. - * - * Returns: (transfer none): the container - */ -GIBaseInfo * -g_base_info_get_container (GIBaseInfo *info) -{ - return ((GIRealInfo*)info)->container; -} - -/** - * g_base_info_get_typelib: - * @info: a #GIBaseInfo - * - * Obtain the typelib this @info belongs to - * - * Returns: (transfer none): the typelib. - */ -GTypelib * -g_base_info_get_typelib (GIBaseInfo *info) -{ - return ((GIRealInfo*)info)->typelib; -} - -/** - * g_base_info_equal: - * @info1: a #GIBaseInfo - * @info2: a #GIBaseInfo - * - * Compare two #GIBaseInfo. - * - * Using pointer comparison is not practical since many functions return - * different instances of #GIBaseInfo that refers to the same part of the - * TypeLib; use this function instead to do #GIBaseInfo comparisons. - * - * Returns: %TRUE if and only if @info1 equals @info2. - */ -gboolean -g_base_info_equal (GIBaseInfo *info1, GIBaseInfo *info2) -{ - /* Compare the TypeLib pointers, which are mmapped. */ - GIRealInfo *rinfo1 = (GIRealInfo*)info1; - GIRealInfo *rinfo2 = (GIRealInfo*)info2; - return rinfo1->typelib->data + rinfo1->offset == rinfo2->typelib->data + rinfo2->offset; -} +#include "girepository-private.h" /* GIFunctionInfo functions */ @@ -832,8 +232,8 @@ g_type_info_init (GIBaseInfo *info, GIRealInfo *rinfo = (GIRealInfo*)container; SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset]; - g_info_init ((GIRealInfo*)info, GI_INFO_TYPE_TYPE, rinfo->repository, container, typelib, - (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset); + _g_info_init ((GIRealInfo*)info, GI_INFO_TYPE_TYPE, rinfo->repository, container, typelib, + (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset); } /** @@ -1015,8 +415,8 @@ g_callable_info_load_arg (GICallableInfo *info, offset = signature_offset (info); header = (Header *)rinfo->typelib->data; - g_info_init ((GIRealInfo*)arg, GI_INFO_TYPE_ARG, rinfo->repository, (GIBaseInfo*)info, rinfo->typelib, - offset + header->signature_blob_size + n * header->arg_blob_size); + _g_info_init ((GIRealInfo*)arg, GI_INFO_TYPE_ARG, rinfo->repository, (GIBaseInfo*)info, rinfo->typelib, + offset + header->signature_blob_size + n * header->arg_blob_size); } /* GIArgInfo function */ @@ -1466,7 +866,7 @@ g_type_info_get_interface (GITypeInfo *info) InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->tag == GI_TYPE_TAG_INTERFACE) - return g_info_from_entry (rinfo->repository, rinfo->typelib, blob->interface); + return _g_info_from_entry (rinfo->repository, rinfo->typelib, blob->interface); } } @@ -1663,9 +1063,9 @@ g_type_info_get_error_domain (GITypeInfo *info, ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->tag == GI_TYPE_TAG_ERROR) - return (GIErrorDomainInfo *) g_info_from_entry (rinfo->repository, - rinfo->typelib, - blob->domains[n]); + return (GIErrorDomainInfo *) _g_info_from_entry (rinfo->repository, + rinfo->typelib, + blob->domains[n]); } return NULL; @@ -1729,8 +1129,8 @@ g_error_domain_info_get_codes (GIErrorDomainInfo *info) blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset]; - return (GIInterfaceInfo *) g_info_from_entry (rinfo->repository, - rinfo->typelib, blob->error_codes); + return (GIInterfaceInfo *) _g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->error_codes); } @@ -2125,8 +1525,8 @@ g_object_info_get_parent (GIObjectInfo *info) ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->parent) - return (GIObjectInfo *) g_info_from_entry (rinfo->repository, - rinfo->typelib, blob->parent); + return (GIObjectInfo *) _g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->parent); else return NULL; } @@ -2173,8 +1573,8 @@ g_object_info_get_interface (GIObjectInfo *info, GIRealInfo *rinfo = (GIRealInfo *)info; ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - return (GIInterfaceInfo *) g_info_from_entry (rinfo->repository, - rinfo->typelib, blob->interfaces[n]); + return (GIInterfaceInfo *) _g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->interfaces[n]); } gint @@ -2441,8 +1841,8 @@ g_object_info_get_class_struct (GIObjectInfo *info) ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->gtype_struct) - return (GIStructInfo *) g_info_from_entry (rinfo->repository, - rinfo->typelib, blob->gtype_struct); + return (GIStructInfo *) _g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->gtype_struct); else return NULL; } @@ -2464,8 +1864,8 @@ g_interface_info_get_prerequisite (GIInterfaceInfo *info, GIRealInfo *rinfo = (GIRealInfo *)info; InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - return g_info_from_entry (rinfo->repository, - rinfo->typelib, blob->prerequisites[n]); + return _g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->prerequisites[n]); } @@ -2670,8 +2070,8 @@ g_interface_info_get_iface_struct (GIInterfaceInfo *info) InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->gtype_struct) - return (GIStructInfo *) g_info_from_entry (rinfo->repository, - rinfo->typelib, blob->gtype_struct); + return (GIStructInfo *) _g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->gtype_struct); else return NULL; } diff --git a/girepository-private.h b/girepository-private.h new file mode 100644 index 000000000..cb82dc6ec --- /dev/null +++ b/girepository-private.h @@ -0,0 +1,84 @@ +/* -*- Mode: C; c-file-style: "gnu"; -*- */ +/* GObject introspection: Private headers + * + * Copyright (C) 2010 Johan Dahlin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GIREPOSITORY_PRIVATE_H__ +#define __GIREPOSITORY_PRIVATE_H__ + +#include + +#include +#include +#include + +typedef struct _GIRealInfo GIRealInfo; + +/* + * We just use one structure for all of the info object + * types; in general, we should be reading data directly + * from the typelib, and not having computed data in + * per-type structures. + */ +struct _GIRealInfo +{ + /* Keep this part in sync with GIUnresolvedInfo below */ + gint32 type; + gint32 ref_count; + GIRepository *repository; + GIBaseInfo *container; + + /* Resolved specific */ + + GTypelib *typelib; + guint32 offset; + + guint32 type_is_embedded : 1; /* Used by GITypeInfo */ + guint32 reserved : 31; + + gpointer reserved2[4]; +}; + +struct _GIUnresolvedInfo +{ + /* Keep this part in sync with GIBaseInfo above */ + gint32 type; + gint32 ref_count; + GIRepository *repository; + GIBaseInfo *container; + + /* Unresolved specific */ + + const gchar *name; + const gchar *namespace; +}; + +void _g_info_init (GIRealInfo *info, + GIInfoType type, + GIRepository *repository, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset); + +GIBaseInfo * _g_info_from_entry (GIRepository *repository, + GTypelib *typelib, + guint16 index); + + +#endif /* __GIREPOSITORY_PRIVATE_H__ */ diff --git a/girepository.h b/girepository.h index 30e9b83d8..e006b5e08 100644 --- a/girepository.h +++ b/girepository.h @@ -22,8 +22,12 @@ #ifndef __G_IREPOSITORY_H__ #define __G_IREPOSITORY_H__ +#define __GIREPOSITORY_H_INSIDE__ + #include #include +#include +#include G_BEGIN_DECLS @@ -38,156 +42,6 @@ typedef struct _GIRepository GIRepository; typedef struct _GIRepositoryClass GIRepositoryClass; typedef struct _GIRepositoryPrivate GIRepositoryPrivate; -typedef struct _GIBaseInfoStub GIBaseInfo; - -struct _GIBaseInfoStub { - /* */ - gint32 dummy1; - gint32 dummy2; - gpointer dummy3; - gpointer dummy4; - gpointer dummy5; - guint32 dummy6; - guint32 dummy7; - gpointer padding[4]; -}; - -/** - * GICallableInfo: - * - * Represents a callable, either #GIFunctionInfo, #GICallbackInfo or - * #GIVFuncInfo. - */ -typedef GIBaseInfo GICallableInfo; - -/** - * GIFunctionInfo: - * - * Represents a function, eg arguments and return value. - */ -typedef GIBaseInfo GIFunctionInfo; - -/** - * GICallbackInfo: - * - * Represents a callback, eg arguments and return value. - */ -typedef GIBaseInfo GICallbackInfo; - -/** - * GIRegisteredTypeInfo: - * - * Represent a registered type. - */ -typedef GIBaseInfo GIRegisteredTypeInfo; - -/** - * GIStructInfo: - * - * Represents a struct. - */ -typedef GIBaseInfo GIStructInfo; - -/** - * GIUnionInfo: - * - * Represents a union. - */ -typedef GIBaseInfo GIUnionInfo; - -/** - * GIEnumInfo: - * - * Represents an enum or a flag. - */ -typedef GIBaseInfo GIEnumInfo; - -/** - * GIObjectInfo: - * - * Represents an object. - */ -typedef GIBaseInfo GIObjectInfo; - -/** - * GIInterfaceInfo: - * - * Represents an interface. - */ -typedef GIBaseInfo GIInterfaceInfo; - -/** - * GIConstantInfo: - * - * Represents a constant. - */ -typedef GIBaseInfo GIConstantInfo; - -/** - * GIValueInfo: - * - * Represents a enum value of a #GIEnumInfo. - */ -typedef GIBaseInfo GIValueInfo; - -/** - * GISignalInfo: - * - * Represents a signal. - */ -typedef GIBaseInfo GISignalInfo; - -/** - * GIVFuncInfo - * - * Represents a virtual function. - */ -typedef GIBaseInfo GIVFuncInfo; - -/** - * GIPropertyInfo: - * - * Represents a property of a #GIObjectInfo or a #GIInterfaceInfo. - */ -typedef GIBaseInfo GIPropertyInfo; - -/** - * GIFieldInfo: - * - * Represents a field of a #GIStructInfo or a #GIUnionInfo. - */ -typedef GIBaseInfo GIFieldInfo; - -/** - * GIArgInfo: - * - * Represents an argument. - */ -typedef GIBaseInfo GIArgInfo; - -/** - * GITypeInfo: - * - * Represents type information, direction, transfer etc. - */ -typedef GIBaseInfo GITypeInfo; - -/** - * GIErrorDomainInfo: - * - * Represents a #GError error domain. - */ -typedef GIBaseInfo GIErrorDomainInfo; - -/** - * GIUnresolvedInfo: - * - * Represents a unresolved type in a typelib. - */ -typedef struct _GIUnresolvedInfo GIUnresolvedInfo; - -typedef struct _GTypelib GTypelib; - struct _GIRepository { GObject parent; @@ -257,20 +111,6 @@ GOptionGroup * g_irepository_get_option_group (void); gboolean g_irepository_dump (const char *arg, GError **error); -/* Typelib */ - -GTypelib * g_typelib_new_from_memory (guchar *memory, - gsize len); -GTypelib * g_typelib_new_from_const_memory (const guchar *memory, - gsize len); -GTypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile); -void g_typelib_free (GTypelib *typelib); - -gboolean g_typelib_symbol (GTypelib *typelib, - const gchar *symbol_name, - gpointer *symbol); -const gchar * g_typelib_get_namespace (GTypelib *typelib); - /** * GIRepositoryError: * @G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND: the typelib could not be found. @@ -303,96 +143,6 @@ void gi_cclosure_marshal_generic (GClosure *closure, gpointer invocation_hint, gpointer marshal_data); -/* Types of objects registered in the repository */ - -/** - * GIInfoType: - * @GI_INFO_TYPE_INVALID: invalid type - * @GI_INFO_TYPE_FUNCTION: function, see #GIFunctionInfo - * @GI_INFO_TYPE_CALLBACK: callback, see #GIFunctionInfo - * @GI_INFO_TYPE_STRUCT: struct, see #GIStructInfo - * @GI_INFO_TYPE_BOXED: boxed, see #GIStructInfo or #GIUnionInfo - * @GI_INFO_TYPE_ENUM: enum, see #GIEnumInfo - * @GI_INFO_TYPE_FLAGS: flags, see #GIEnumInfo - * @GI_INFO_TYPE_OBJECT: object, see #GIObjectInfo - * @GI_INFO_TYPE_INTERFACE: interface, see #GIInterfaceInfo - * @GI_INFO_TYPE_CONSTANT: contant, see #GIConstantInfo - * @GI_INFO_TYPE_ERROR_DOMAIN: error domain for a #GError, see #GIErrorDomainInfo - * @GI_INFO_TYPE_UNION: union, see #GIUnionInfo - * @GI_INFO_TYPE_VALUE: enum value, see #GIValueInfo - * @GI_INFO_TYPE_SIGNAL: signal, see #GISignalInfo - * @GI_INFO_TYPE_VFUNC: virtual function, see #GIVFuncInfo - * @GI_INFO_TYPE_PROPERTY: GObject property, see #GIPropertyInfo - * @GI_INFO_TYPE_FIELD: struct or union field, see #GIFieldInfo - * @GI_INFO_TYPE_ARG: argument of a function or callback, see #GIArgInfo - * @GI_INFO_TYPE_TYPE: type information, see #GITypeInfo - * @GI_INFO_TYPE_UNRESOLVED: unresolved type, a type which is not present in - * the typelib, or any of its dependencies. - * - * The type of a GIBaseInfo struct. - */ -typedef enum -{ - GI_INFO_TYPE_INVALID, - GI_INFO_TYPE_FUNCTION, - GI_INFO_TYPE_CALLBACK, - GI_INFO_TYPE_STRUCT, - GI_INFO_TYPE_BOXED, - GI_INFO_TYPE_ENUM, /* 5 */ - GI_INFO_TYPE_FLAGS, - GI_INFO_TYPE_OBJECT, - GI_INFO_TYPE_INTERFACE, - GI_INFO_TYPE_CONSTANT, - GI_INFO_TYPE_ERROR_DOMAIN, /* 10 */ - GI_INFO_TYPE_UNION, - GI_INFO_TYPE_VALUE, - GI_INFO_TYPE_SIGNAL, - GI_INFO_TYPE_VFUNC, - GI_INFO_TYPE_PROPERTY, /* 15 */ - GI_INFO_TYPE_FIELD, - GI_INFO_TYPE_ARG, - GI_INFO_TYPE_TYPE, - GI_INFO_TYPE_UNRESOLVED -} GIInfoType; - - -/* GIBaseInfo */ - -/** - * GIAttributeIter: - * - * An opaque structure used to iterate over attributes - * in a #GIBaseInfo struct. - */ -typedef struct { - /* */ - gpointer data; - gpointer data2; - gpointer data3; - gpointer data4; -} GIAttributeIter; - -GIBaseInfo * g_base_info_ref (GIBaseInfo *info); -void g_base_info_unref (GIBaseInfo *info); -GIInfoType g_base_info_get_type (GIBaseInfo *info); -const gchar * g_base_info_get_name (GIBaseInfo *info); -const gchar * g_base_info_get_namespace (GIBaseInfo *info); -gboolean g_base_info_is_deprecated (GIBaseInfo *info); -const gchar * g_base_info_get_attribute (GIBaseInfo *info, - const gchar *name); -gboolean g_base_info_iterate_attributes (GIBaseInfo *info, - GIAttributeIter *iterator, - char **name, - char **value); -GIBaseInfo * g_base_info_get_container (GIBaseInfo *info); -GTypelib * g_base_info_get_typelib (GIBaseInfo *info); -gboolean g_base_info_equal (GIBaseInfo *info1, - GIBaseInfo *info2); -GIBaseInfo * g_info_new (GIInfoType type, - GIBaseInfo *container, - GTypelib *typelib, - guint32 offset); - /* GIFunctionInfo */ #define GI_IS_FUNCTION_INFO(info) \ @@ -919,5 +669,6 @@ gint g_constant_info_get_value (GIConstantInfo G_END_DECLS + #endif /* __G_IREPOSITORY_H__ */ diff --git a/gitypelib.h b/gitypelib.h new file mode 100644 index 000000000..2f74bf6a9 --- /dev/null +++ b/gitypelib.h @@ -0,0 +1,53 @@ +/* GObject introspection: Public typelib API + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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. +..skipping... + * 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 __GITYPELIB_H__ +#define __GITYPELIB_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +typedef struct _GTypelib GTypelib; + +GTypelib * g_typelib_new_from_memory (guchar *memory, + gsize len); +GTypelib * g_typelib_new_from_const_memory (const guchar *memory, + gsize len); +GTypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile); +void g_typelib_free (GTypelib *typelib); + +gboolean g_typelib_symbol (GTypelib *typelib, + const gchar *symbol_name, + gpointer *symbol); +const gchar * g_typelib_get_namespace (GTypelib *typelib); + + +G_END_DECLS + +#endif /* __GITYPELIB_H__ */ + diff --git a/gitypes.h b/gitypes.h new file mode 100644 index 000000000..8951d9178 --- /dev/null +++ b/gitypes.h @@ -0,0 +1,225 @@ +/* GObject introspection: types + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GITYPES_H__ +#define __GITYPES_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +typedef struct _GIBaseInfoStub GIBaseInfo; + +/** + * GICallableInfo: + * + * Represents a callable, either #GIFunctionInfo, #GICallbackInfo or + * #GIVFuncInfo. + */ +typedef GIBaseInfo GICallableInfo; + +/** + * GIFunctionInfo: + * + * Represents a function, eg arguments and return value. + */ +typedef GIBaseInfo GIFunctionInfo; + +/** + * GICallbackInfo: + * + * Represents a callback, eg arguments and return value. + */ +typedef GIBaseInfo GICallbackInfo; + +/** + * GIRegisteredTypeInfo: + * + * Represent a registered type. + */ +typedef GIBaseInfo GIRegisteredTypeInfo; + +/** + * GIStructInfo: + * + * Represents a struct. + */ +typedef GIBaseInfo GIStructInfo; + +/** + * GIUnionInfo: + * + * Represents a union. + */ +typedef GIBaseInfo GIUnionInfo; + +/** + * GIEnumInfo: + * + * Represents an enum or a flag. + */ +typedef GIBaseInfo GIEnumInfo; + +/** + * GIObjectInfo: + * + * Represents an object. + */ +typedef GIBaseInfo GIObjectInfo; + +/** + * GIInterfaceInfo: + * + * Represents an interface. + */ +typedef GIBaseInfo GIInterfaceInfo; + +/** + * GIConstantInfo: + * + * Represents a constant. + */ +typedef GIBaseInfo GIConstantInfo; + +/** + * GIValueInfo: + * + * Represents a enum value of a #GIEnumInfo. + */ +typedef GIBaseInfo GIValueInfo; + +/** + * GISignalInfo: + * + * Represents a signal. + */ +typedef GIBaseInfo GISignalInfo; + +/** + * GIVFuncInfo + * + * Represents a virtual function. + */ +typedef GIBaseInfo GIVFuncInfo; + +/** + * GIPropertyInfo: + * + * Represents a property of a #GIObjectInfo or a #GIInterfaceInfo. + */ +typedef GIBaseInfo GIPropertyInfo; + +/** + * GIFieldInfo: + * + * Represents a field of a #GIStructInfo or a #GIUnionInfo. + */ +typedef GIBaseInfo GIFieldInfo; + +/** + * GIArgInfo: + * + * Represents an argument. + */ +typedef GIBaseInfo GIArgInfo; + +/** + * GITypeInfo: + * + * Represents type information, direction, transfer etc. + */ +typedef GIBaseInfo GITypeInfo; + +/** + * GIErrorDomainInfo: + * + * Represents a #GError error domain. + */ +typedef GIBaseInfo GIErrorDomainInfo; + +/** + * GIUnresolvedInfo: + * + * Represents a unresolved type in a typelib. + */ +typedef struct _GIUnresolvedInfo GIUnresolvedInfo; + +/* Types of objects registered in the repository */ + +/** + * GIInfoType: + * @GI_INFO_TYPE_INVALID: invalid type + * @GI_INFO_TYPE_FUNCTION: function, see #GIFunctionInfo + * @GI_INFO_TYPE_CALLBACK: callback, see #GIFunctionInfo + * @GI_INFO_TYPE_STRUCT: struct, see #GIStructInfo + * @GI_INFO_TYPE_BOXED: boxed, see #GIStructInfo or #GIUnionInfo + * @GI_INFO_TYPE_ENUM: enum, see #GIEnumInfo + * @GI_INFO_TYPE_FLAGS: flags, see #GIEnumInfo + * @GI_INFO_TYPE_OBJECT: object, see #GIObjectInfo + * @GI_INFO_TYPE_INTERFACE: interface, see #GIInterfaceInfo + * @GI_INFO_TYPE_CONSTANT: contant, see #GIConstantInfo + * @GI_INFO_TYPE_ERROR_DOMAIN: error domain for a #GError, see #GIErrorDomainInfo + * @GI_INFO_TYPE_UNION: union, see #GIUnionInfo + * @GI_INFO_TYPE_VALUE: enum value, see #GIValueInfo + * @GI_INFO_TYPE_SIGNAL: signal, see #GISignalInfo + * @GI_INFO_TYPE_VFUNC: virtual function, see #GIVFuncInfo + * @GI_INFO_TYPE_PROPERTY: GObject property, see #GIPropertyInfo + * @GI_INFO_TYPE_FIELD: struct or union field, see #GIFieldInfo + * @GI_INFO_TYPE_ARG: argument of a function or callback, see #GIArgInfo + * @GI_INFO_TYPE_TYPE: type information, see #GITypeInfo + * @GI_INFO_TYPE_UNRESOLVED: unresolved type, a type which is not present in + * the typelib, or any of its dependencies. + * + * The type of a GIBaseInfo struct. + */ +typedef enum +{ + GI_INFO_TYPE_INVALID, + GI_INFO_TYPE_FUNCTION, + GI_INFO_TYPE_CALLBACK, + GI_INFO_TYPE_STRUCT, + GI_INFO_TYPE_BOXED, + GI_INFO_TYPE_ENUM, /* 5 */ + GI_INFO_TYPE_FLAGS, + GI_INFO_TYPE_OBJECT, + GI_INFO_TYPE_INTERFACE, + GI_INFO_TYPE_CONSTANT, + GI_INFO_TYPE_ERROR_DOMAIN, /* 10 */ + GI_INFO_TYPE_UNION, + GI_INFO_TYPE_VALUE, + GI_INFO_TYPE_SIGNAL, + GI_INFO_TYPE_VFUNC, + GI_INFO_TYPE_PROPERTY, /* 15 */ + GI_INFO_TYPE_FIELD, + GI_INFO_TYPE_ARG, + GI_INFO_TYPE_TYPE, + GI_INFO_TYPE_UNRESOLVED +} GIInfoType; + + +G_END_DECLS + +#endif /* __GITYPES_H__ */ + From 64ee6cb5b0174d4d1dd80ef62c56d8f368e2f559 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Mon, 31 May 2010 17:44:46 -0300 Subject: [PATCH 298/692] [gtypelib.ch] Rename to gitypelib.ch Rename gtypelib.h -> gitypelib-internal.h and rename gtypelib.c to gitypelib.c --- Makefile.am | 4 ++-- gibaseinfo.c | 2 +- ginfo.c | 2 +- ginvoke.c | 2 +- girepository.c | 2 +- girmodule.h | 2 +- girnode.c | 2 +- girparser.c | 2 +- gtypelib.h => gitypelib-internal.h | 0 gtypelib.c => gitypelib.c | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) rename gtypelib.h => gitypelib-internal.h (100%) rename gtypelib.c => gitypelib.c (99%) diff --git a/Makefile.am b/Makefile.am index ac95ed661..3bd30103f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,8 +22,8 @@ libgirepository_1_0_la_SOURCES = \ girffi.h \ girffi-private.h \ glib-compat.h \ - gtypelib.c \ - gtypelib.h + gitypelib.c \ + gitypelib-internal.h libgirepository_1_0_la_CPPFLAGS = $(GIREPO_CFLAGS) libgirepository_1_0_la_LIBADD = $(GIREPO_LIBS) diff --git a/gibaseinfo.c b/gibaseinfo.c index 006dd8f55..2f7144927 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -25,7 +25,7 @@ #include #include -#include "gtypelib.h" +#include "gitypelib-internal.h" #include "ginfo.h" #include "girepository-private.h" diff --git a/ginfo.c b/ginfo.c index 70482a5aa..073776301 100644 --- a/ginfo.c +++ b/ginfo.c @@ -25,7 +25,7 @@ #include #include -#include "gtypelib.h" +#include "gitypelib-internal.h" #include "ginfo.h" #include "girepository-private.h" diff --git a/ginvoke.c b/ginvoke.c index bae8da4f5..3de6af415 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -25,7 +25,7 @@ #include "girepository.h" #include "girffi.h" -#include "gtypelib.h" +#include "gitypelib-internal.h" #include "config.h" GQuark diff --git a/girepository.c b/girepository.c index 218a954cf..f06270eb3 100644 --- a/girepository.c +++ b/girepository.c @@ -29,7 +29,7 @@ #include #include #include "girepository.h" -#include "gtypelib.h" +#include "gitypelib-internal.h" #include "ginfo.h" #include "glib-compat.h" diff --git a/girmodule.h b/girmodule.h index 3ebb3eb72..bd3fbf29d 100644 --- a/girmodule.h +++ b/girmodule.h @@ -22,7 +22,7 @@ #define __G_IR_MODULE_H__ #include -#include "gtypelib.h" +#include "gitypelib-internal.h" G_BEGIN_DECLS diff --git a/girnode.c b/girnode.c index 9ff323575..db029989d 100644 --- a/girnode.c +++ b/girnode.c @@ -25,7 +25,7 @@ #include "girmodule.h" #include "girnode.h" -#include "gtypelib.h" +#include "gitypelib-internal.h" static gulong string_count = 0; static gulong unique_string_count = 0; diff --git a/girparser.c b/girparser.c index 341cb5ded..5861c167a 100644 --- a/girparser.c +++ b/girparser.c @@ -26,7 +26,7 @@ #include "girparser.h" #include "girmodule.h" #include "girnode.h" -#include "gtypelib.h" +#include "gitypelib-internal.h" #include "config.h" #if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS) diff --git a/gtypelib.h b/gitypelib-internal.h similarity index 100% rename from gtypelib.h rename to gitypelib-internal.h diff --git a/gtypelib.c b/gitypelib.c similarity index 99% rename from gtypelib.c rename to gitypelib.c index 41bbb0ccc..1b3f882ec 100644 --- a/gtypelib.c +++ b/gitypelib.c @@ -25,7 +25,7 @@ #include #include "config.h" -#include "gtypelib.h" +#include "gitypelib-internal.h" #include "glib-compat.h" typedef struct { From a94a11b5c0ad3e241ee1db1aeee0338186af4760 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Mon, 31 May 2010 17:54:42 -0300 Subject: [PATCH 299/692] [gifunctioninfo] Move out to another file Move out GIFunctionInfo to gifunctioninfo.[ch] --- Makefile.am | 4 +- gifunctioninfo.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++ gifunctioninfo.h | 97 +++++++++++++++++++++++++++ ginfo.c | 142 --------------------------------------- girepository.h | 89 +------------------------ gitypes.h | 25 +++++++ 6 files changed, 296 insertions(+), 230 deletions(-) create mode 100644 gifunctioninfo.c create mode 100644 gifunctioninfo.h diff --git a/Makefile.am b/Makefile.am index 3bd30103f..09fc0ee79 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,7 @@ girepodir = $(includedir)/gobject-introspection-1.0/ girepo_HEADERS = \ gibaseinfo.h \ + gifunctioninfo.h \ girepository.h \ girffi.h \ gitypelib.h \ @@ -12,7 +13,8 @@ noinst_LTLIBRARIES = libgirepository-parser.la libgirepository_1_0_la_SOURCES = \ gdump.c \ gfield.c \ - gibaseinfo.c \ + gibaseinfo.c \ + gifunctioninfo.c \ ginfo.c \ ginfo.h \ ginvoke.c \ diff --git a/gifunctioninfo.c b/gifunctioninfo.c new file mode 100644 index 000000000..30c7ca69f --- /dev/null +++ b/gifunctioninfo.c @@ -0,0 +1,169 @@ +/* GObject introspection: Repository implementation + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 "girepository-private.h" +#include "gitypelib-internal.h" + +/* GIFunctionInfo functions */ + +/** + * SECTION:gifunctioninfo + * @Short_description: Struct representing a function + * @Title: GIFunctionInfo + * + * GIFunctionInfo represents a function, method or constructor. + * To find out what kind of entity a #GIFunctionInfo represents, call + * g_function_info_get_flags(). + * + * See also #GICallableInfo for information on how to retreive arguments and + * other metadata. + */ + +/** + * g_function_info_get_symbol: + * @info: a #GIFunctionInfo + * + * Obtain the symbol of the function. The symbol is the name of the + * exported function, suitable to be used as an argument to + * g_module_symbol(). + * + * Returns: the symbol + */ +const gchar * +g_function_info_get_symbol (GIFunctionInfo *info) +{ + GIRealInfo *rinfo; + FunctionBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_FUNCTION_INFO (info), NULL); + + rinfo = (GIRealInfo *)info; + blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; + + return g_typelib_get_string (rinfo->typelib, blob->symbol); +} + +/** + * g_function_info_get_flags: + * @info: a #GIFunctionInfo + * + * Obtain the #GIFunctionInfoFlags for the @info. + * + * Returns: the flags + */ +GIFunctionInfoFlags +g_function_info_get_flags (GIFunctionInfo *info) +{ + GIFunctionInfoFlags flags; + GIRealInfo *rinfo; + FunctionBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_FUNCTION_INFO (info), -1); + + rinfo = (GIRealInfo *)info; + blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; + + flags = 0; + + /* Make sure we don't flag Constructors as methods */ + if (!blob->constructor && !blob->is_static) + flags = flags | GI_FUNCTION_IS_METHOD; + + if (blob->constructor) + flags = flags | GI_FUNCTION_IS_CONSTRUCTOR; + + if (blob->getter) + flags = flags | GI_FUNCTION_IS_GETTER; + + if (blob->setter) + flags = flags | GI_FUNCTION_IS_SETTER; + + if (blob->wraps_vfunc) + flags = flags | GI_FUNCTION_WRAPS_VFUNC; + + if (blob->throws) + flags = flags | GI_FUNCTION_THROWS; + + return flags; +} + +/** + * g_function_info_get_property: + * @info: a #GIFunctionInfo + * + * Obtain the property associated with this #GIFunctionInfo. + * Only #GIFunctionInfo with the flag %GI_FUNCTION_IS_GETTER or + * %GI_FUNCTION_IS_SETTER have a property set. For other cases, + * %NULL will be returned. + * + * Returns: (transfer full): the property or %NULL if not set. Free it with + * g_base_info_unref() when done. + */ +GIPropertyInfo * +g_function_info_get_property (GIFunctionInfo *info) +{ + GIRealInfo *rinfo; + FunctionBlob *blob; + GIInterfaceInfo *container; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_FUNCTION_INFO (info), NULL); + + rinfo = (GIRealInfo *)info; + blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; + container = (GIInterfaceInfo *)rinfo->container; + + return g_interface_info_get_property (container, blob->index); +} + +/** + * g_function_info_get_vfunc: + * @info: a #GIFunctionInfo + * + * Obtain the virtual function associated with this #GIFunctionInfo. + * Only #GIFunctionInfo with the flag %GI_FUNCTION_WRAPS_VFUNC has + * a virtual function set. For other cases, %NULL will be returned. + * + * Returns: (transfer full): the virtual function or %NULL if not set. + * Free it by calling g_base_info_unref() when done. + */ +GIVFuncInfo * +g_function_info_get_vfunc (GIFunctionInfo *info) +{ + GIRealInfo *rinfo; + FunctionBlob *blob; + GIInterfaceInfo *container; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_FUNCTION_INFO (info), NULL); + + rinfo = (GIRealInfo *)info; + blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; + container = (GIInterfaceInfo *)rinfo->container; + + return g_interface_info_get_vfunc (container, blob->index); +} + diff --git a/gifunctioninfo.h b/gifunctioninfo.h new file mode 100644 index 000000000..92e2089df --- /dev/null +++ b/gifunctioninfo.h @@ -0,0 +1,97 @@ +/* GObject introspection: Functions + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GIFUNCTIONINFO_H__ +#define __GIFUNCTIONINFO_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define GI_IS_FUNCTION_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FUNCTION) + +/** + * GIFunctionInfoFlags: + * @GI_FUNCTION_IS_METHOD: is a method. + * @GI_FUNCTION_IS_CONSTRUCTOR: is a constructor. + * @GI_FUNCTION_IS_GETTER: is a getter of a #GIPropertyInfo. + * @GI_FUNCTION_IS_SETTER: is a setter of a #GIPropertyInfo. + * @GI_FUNCTION_WRAPS_VFUNC: represents a virtual function. + * @GI_FUNCTION_THROWS: the function may throw an error. + * + * Flags for a #GIFunctionInfo struct. + */ +typedef enum +{ + GI_FUNCTION_IS_METHOD = 1 << 0, + GI_FUNCTION_IS_CONSTRUCTOR = 1 << 1, + GI_FUNCTION_IS_GETTER = 1 << 2, + GI_FUNCTION_IS_SETTER = 1 << 3, + GI_FUNCTION_WRAPS_VFUNC = 1 << 4, + GI_FUNCTION_THROWS = 1 << 5 +} GIFunctionInfoFlags; + +const gchar * g_function_info_get_symbol (GIFunctionInfo *info); +GIFunctionInfoFlags g_function_info_get_flags (GIFunctionInfo *info); +GIPropertyInfo * g_function_info_get_property (GIFunctionInfo *info); +GIVFuncInfo * g_function_info_get_vfunc (GIFunctionInfo *info); + +#define G_INVOKE_ERROR (g_invoke_error_quark ()) +GQuark g_invoke_error_quark (void); + +/** + * GInvokeError: + * @G_INVOKE_ERROR_FAILED: invokation failed, unknown error. + * @G_INVOKE_ERROR_SYMBOL_NOT_FOUND: symbol couldn't be found in any of the + * libraries associated with the typelib of the function. + * @G_INVOKE_ERROR_ARGUMENT_MISMATCH: the arguments provided didn't match + * the expected arguments for the functions type signature. + * + * An error occuring while invoking a function via + * g_function_info_invoke(). + */ + +typedef enum +{ + G_INVOKE_ERROR_FAILED, + G_INVOKE_ERROR_SYMBOL_NOT_FOUND, + G_INVOKE_ERROR_ARGUMENT_MISMATCH +} GInvokeError; + +gboolean g_function_info_invoke (GIFunctionInfo *info, + const GArgument *in_args, + int n_in_args, + const GArgument *out_args, + int n_out_args, + GArgument *return_value, + GError **error); + + +G_END_DECLS + + +#endif /* __G_IREPOSITORY_H__ */ + diff --git a/ginfo.c b/ginfo.c index 073776301..0c717cfac 100644 --- a/ginfo.c +++ b/ginfo.c @@ -29,148 +29,6 @@ #include "ginfo.h" #include "girepository-private.h" -/* GIFunctionInfo functions */ - -/** - * SECTION:gifunctioninfo - * @Short_description: Struct representing a function - * @Title: GIFunctionInfo - * - * GIFunctionInfo represents a function, method or constructor. - * To find out what kind of entity a #GIFunctionInfo represents, call - * g_function_info_get_flags(). - * - * See also #GICallableInfo for information on how to retreive arguments and - * other metadata. - */ - -/** - * g_function_info_get_symbol: - * @info: a #GIFunctionInfo - * - * Obtain the symbol of the function. The symbol is the name of the - * exported function, suitable to be used as an argument to - * g_module_symbol(). - * - * Returns: the symbol - */ -const gchar * -g_function_info_get_symbol (GIFunctionInfo *info) -{ - GIRealInfo *rinfo; - FunctionBlob *blob; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_FUNCTION_INFO (info), NULL); - - rinfo = (GIRealInfo *)info; - blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; - - return g_typelib_get_string (rinfo->typelib, blob->symbol); -} - -/** - * g_function_info_get_flags: - * @info: a #GIFunctionInfo - * - * Obtain the #GIFunctionInfoFlags for the @info. - * - * Returns: the flags - */ -GIFunctionInfoFlags -g_function_info_get_flags (GIFunctionInfo *info) -{ - GIFunctionInfoFlags flags; - GIRealInfo *rinfo; - FunctionBlob *blob; - - g_return_val_if_fail (info != NULL, -1); - g_return_val_if_fail (GI_IS_FUNCTION_INFO (info), -1); - - rinfo = (GIRealInfo *)info; - blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; - - flags = 0; - - /* Make sure we don't flag Constructors as methods */ - if (!blob->constructor && !blob->is_static) - flags = flags | GI_FUNCTION_IS_METHOD; - - if (blob->constructor) - flags = flags | GI_FUNCTION_IS_CONSTRUCTOR; - - if (blob->getter) - flags = flags | GI_FUNCTION_IS_GETTER; - - if (blob->setter) - flags = flags | GI_FUNCTION_IS_SETTER; - - if (blob->wraps_vfunc) - flags = flags | GI_FUNCTION_WRAPS_VFUNC; - - if (blob->throws) - flags = flags | GI_FUNCTION_THROWS; - - return flags; -} - -/** - * g_function_info_get_property: - * @info: a #GIFunctionInfo - * - * Obtain the property associated with this #GIFunctionInfo. - * Only #GIFunctionInfo with the flag %GI_FUNCTION_IS_GETTER or - * %GI_FUNCTION_IS_SETTER have a property set. For other cases, - * %NULL will be returned. - * - * Returns: (transfer full): the property or %NULL if not set. Free it with - * g_base_info_unref() when done. - */ -GIPropertyInfo * -g_function_info_get_property (GIFunctionInfo *info) -{ - GIRealInfo *rinfo; - FunctionBlob *blob; - GIInterfaceInfo *container; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_FUNCTION_INFO (info), NULL); - - rinfo = (GIRealInfo *)info; - blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; - container = (GIInterfaceInfo *)rinfo->container; - - return g_interface_info_get_property (container, blob->index); -} - -/** - * g_function_info_get_vfunc: - * @info: a #GIFunctionInfo - * - * Obtain the virtual function associated with this #GIFunctionInfo. - * Only #GIFunctionInfo with the flag %GI_FUNCTION_WRAPS_VFUNC has - * a virtual function set. For other cases, %NULL will be returned. - * - * Returns: (transfer full): the virtual function or %NULL if not set. - * Free it by calling g_base_info_unref() when done. - */ -GIVFuncInfo * -g_function_info_get_vfunc (GIFunctionInfo *info) -{ - GIRealInfo *rinfo; - FunctionBlob *blob; - GIInterfaceInfo *container; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_FUNCTION_INFO (info), NULL); - - rinfo = (GIRealInfo *)info; - blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; - container = (GIInterfaceInfo *)rinfo->container; - - return g_interface_info_get_vfunc (container, blob->index); -} - /* GICallableInfo functions */ /** diff --git a/girepository.h b/girepository.h index e006b5e08..389877c1d 100644 --- a/girepository.h +++ b/girepository.h @@ -27,7 +27,9 @@ #include #include #include +#include #include +#include G_BEGIN_DECLS @@ -143,93 +145,6 @@ void gi_cclosure_marshal_generic (GClosure *closure, gpointer invocation_hint, gpointer marshal_data); -/* GIFunctionInfo */ - -#define GI_IS_FUNCTION_INFO(info) \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FUNCTION) - -/** - * GIFunctionInfoFlags: - * @GI_FUNCTION_IS_METHOD: is a method. - * @GI_FUNCTION_IS_CONSTRUCTOR: is a constructor. - * @GI_FUNCTION_IS_GETTER: is a getter of a #GIPropertyInfo. - * @GI_FUNCTION_IS_SETTER: is a setter of a #GIPropertyInfo. - * @GI_FUNCTION_WRAPS_VFUNC: represents a virtual function. - * @GI_FUNCTION_THROWS: the function may throw an error. - * - * Flags for a #GIFunctionInfo struct. - */ -typedef enum -{ - GI_FUNCTION_IS_METHOD = 1 << 0, - GI_FUNCTION_IS_CONSTRUCTOR = 1 << 1, - GI_FUNCTION_IS_GETTER = 1 << 2, - GI_FUNCTION_IS_SETTER = 1 << 3, - GI_FUNCTION_WRAPS_VFUNC = 1 << 4, - GI_FUNCTION_THROWS = 1 << 5 -} GIFunctionInfoFlags; - -const gchar * g_function_info_get_symbol (GIFunctionInfo *info); -GIFunctionInfoFlags g_function_info_get_flags (GIFunctionInfo *info); -GIPropertyInfo * g_function_info_get_property (GIFunctionInfo *info); -GIVFuncInfo * g_function_info_get_vfunc (GIFunctionInfo *info); - -typedef union -{ - gboolean v_boolean; - gint8 v_int8; - guint8 v_uint8; - gint16 v_int16; - guint16 v_uint16; - gint32 v_int32; - guint32 v_uint32; - gint64 v_int64; - guint64 v_uint64; - gfloat v_float; - gdouble v_double; - gshort v_short; - gushort v_ushort; - gint v_int; - guint v_uint; - glong v_long; - gulong v_ulong; - gssize v_ssize; - gsize v_size; - gchar * v_string; - gpointer v_pointer; -} GArgument; - -#define G_INVOKE_ERROR (g_invoke_error_quark ()) -GQuark g_invoke_error_quark (void); - -/** - * GInvokeError: - * @G_INVOKE_ERROR_FAILED: invokation failed, unknown error. - * @G_INVOKE_ERROR_SYMBOL_NOT_FOUND: symbol couldn't be found in any of the - * libraries associated with the typelib of the function. - * @G_INVOKE_ERROR_ARGUMENT_MISMATCH: the arguments provided didn't match - * the expected arguments for the functions type signature. - * - * An error occuring while invoking a function via - * g_function_info_invoke(). - */ - -typedef enum -{ - G_INVOKE_ERROR_FAILED, - G_INVOKE_ERROR_SYMBOL_NOT_FOUND, - G_INVOKE_ERROR_ARGUMENT_MISMATCH -} GInvokeError; - -gboolean g_function_info_invoke (GIFunctionInfo *info, - const GArgument *in_args, - int n_in_args, - const GArgument *out_args, - int n_out_args, - GArgument *return_value, - GError **error); - - /* GICallableInfo */ #define GI_IS_CALLABLE_INFO(info) \ diff --git a/gitypes.h b/gitypes.h index 8951d9178..a51df08ef 100644 --- a/gitypes.h +++ b/gitypes.h @@ -166,6 +166,31 @@ typedef GIBaseInfo GIErrorDomainInfo; */ typedef struct _GIUnresolvedInfo GIUnresolvedInfo; +typedef union +{ + gboolean v_boolean; + gint8 v_int8; + guint8 v_uint8; + gint16 v_int16; + guint16 v_uint16; + gint32 v_int32; + guint32 v_uint32; + gint64 v_int64; + guint64 v_uint64; + gfloat v_float; + gdouble v_double; + gshort v_short; + gushort v_ushort; + gint v_int; + guint v_uint; + glong v_long; + gulong v_ulong; + gssize v_ssize; + gsize v_size; + gchar * v_string; + gpointer v_pointer; +} GArgument; + /* Types of objects registered in the repository */ /** From 6edee7684cb165b2609a49a47b65767e2c4216cc Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 1 Jun 2010 10:15:12 -0300 Subject: [PATCH 300/692] [girepository] Fix include path We're installing the headers without the girepository/ prefix, so remove that in all internal headers to not break the out of tree scanning. --- gibaseinfo.h | 2 +- gifunctioninfo.h | 2 +- girepository-private.h | 2 +- gitypelib.h | 2 +- gitypes.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gibaseinfo.h b/gibaseinfo.h index f4bd731cd..920b07af7 100644 --- a/gibaseinfo.h +++ b/gibaseinfo.h @@ -23,7 +23,7 @@ #define __GIBASEINFO_H__ #if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) -#error "Only can be included directly." +#error "Only can be included directly." #endif #include diff --git a/gifunctioninfo.h b/gifunctioninfo.h index 92e2089df..b2059a853 100644 --- a/gifunctioninfo.h +++ b/gifunctioninfo.h @@ -23,7 +23,7 @@ #define __GIFUNCTIONINFO_H__ #if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) -#error "Only can be included directly." +#error "Only can be included directly." #endif #include diff --git a/girepository-private.h b/girepository-private.h index cb82dc6ec..f29f8a474 100644 --- a/girepository-private.h +++ b/girepository-private.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include typedef struct _GIRealInfo GIRealInfo; diff --git a/gitypelib.h b/gitypelib.h index 2f74bf6a9..5d5eda5fe 100644 --- a/gitypelib.h +++ b/gitypelib.h @@ -25,7 +25,7 @@ #define __GITYPELIB_H__ #if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) -#error "Only can be included directly." +#error "Only can be included directly." #endif #include diff --git a/gitypes.h b/gitypes.h index a51df08ef..f53700343 100644 --- a/gitypes.h +++ b/gitypes.h @@ -23,7 +23,7 @@ #define __GITYPES_H__ #if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) -#error "Only can be included directly." +#error "Only can be included directly." #endif #include From 6436e013c91630f6ba1893c337bf8d48b2b871d5 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 1 Jun 2010 10:23:46 -0300 Subject: [PATCH 301/692] [girepository] Fix the remaning headers as well --- gibaseinfo.h | 4 ++-- gifunctioninfo.h | 2 +- girepository-private.h | 4 ++-- girepository.h | 8 ++++---- gitypes.h | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gibaseinfo.h b/gibaseinfo.h index 920b07af7..c6175c3ec 100644 --- a/gibaseinfo.h +++ b/gibaseinfo.h @@ -27,8 +27,8 @@ #endif #include -#include -#include +#include +#include G_BEGIN_DECLS diff --git a/gifunctioninfo.h b/gifunctioninfo.h index b2059a853..94b2d6f9a 100644 --- a/gifunctioninfo.h +++ b/gifunctioninfo.h @@ -26,7 +26,7 @@ #error "Only can be included directly." #endif -#include +#include G_BEGIN_DECLS diff --git a/girepository-private.h b/girepository-private.h index f29f8a474..4ded32b86 100644 --- a/girepository-private.h +++ b/girepository-private.h @@ -24,9 +24,9 @@ #include -#include +#include #include -#include +#include typedef struct _GIRealInfo GIRealInfo; diff --git a/girepository.h b/girepository.h index 389877c1d..7ddb70f5a 100644 --- a/girepository.h +++ b/girepository.h @@ -26,10 +26,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include G_BEGIN_DECLS diff --git a/gitypes.h b/gitypes.h index f53700343..49fe017da 100644 --- a/gitypes.h +++ b/gitypes.h @@ -26,7 +26,7 @@ #error "Only can be included directly." #endif -#include +#include G_BEGIN_DECLS From d531541b8af75a4c9469c2eead32be8a57d3c719 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Wed, 2 Jun 2010 19:36:59 +0200 Subject: [PATCH 302/692] Fix marshalling of GStrv. * gir/gimarshallingtests.[hc]: Add a test for GStrv in function args and as struct fields. * girepository/giroffsets.c: Correctly compute the size of structs with array fields * girepository/girparser.c: Set is_pointer to FALSE for arrays with fixed size that are inside structs. * giscanner/glibtransformer.py: Special case GStrv as arrays of utf8. * giscanner/annotationparser.py: Make full transfer the default for arrays of char* returned by functions. https://bugzilla.gnome.org/show_bug.cgi?id=620170 --- giroffsets.c | 10 +++++----- girparser.c | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/giroffsets.c b/giroffsets.c index 7a5e70116..263665ce3 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -232,7 +232,11 @@ get_type_size_alignment (GIrNodeType *type, { ffi_type *type_ffi; - if (type->tag == GI_TYPE_TAG_ARRAY) + if (type->is_pointer) + { + type_ffi = &ffi_type_pointer; + } + else if (type->tag == GI_TYPE_TAG_ARRAY) { gint elt_size, elt_alignment; @@ -250,10 +254,6 @@ get_type_size_alignment (GIrNodeType *type, return TRUE; } - else if (type->is_pointer) - { - type_ffi = &ffi_type_pointer; - } else { if (type->tag == GI_TYPE_TAG_INTERFACE) diff --git a/girparser.c b/girparser.c index 5861c167a..678482c57 100644 --- a/girparser.c +++ b/girparser.c @@ -1745,6 +1745,9 @@ start_type (GMarkupParseContext *context, else /* If neither zero-terminated nor length nor fixed-size is given, assume zero-terminated. */ typenode->zero_terminated = !(typenode->has_length || typenode->has_size); + + if (typenode->has_size && ctx->current_typed->type == G_IR_NODE_FIELD) + typenode->is_pointer = FALSE; } else { typenode->zero_terminated = FALSE; typenode->has_length = FALSE; From 292033c7dcb36b19e67a51d12efcc9c8ea947284 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 5 Jun 2010 12:11:58 -0300 Subject: [PATCH 303/692] [girepository] Move GICallableInfo out of ginfo.ch --- Makefile.am | 3 +- gibaseinfo.c | 41 +++++-- gibaseinfo.h | 1 - gicallableinfo.c | 251 +++++++++++++++++++++++++++++++++++++++ gicallableinfo.h | 54 +++++++++ ginfo.c | 262 ++--------------------------------------- ginfo.h | 42 ------- girepository-private.h | 16 +++ girepository.c | 8 +- girepository.h | 36 +----- gitypes.h | 16 +++ 11 files changed, 384 insertions(+), 346 deletions(-) create mode 100644 gicallableinfo.c create mode 100644 gicallableinfo.h delete mode 100644 ginfo.h diff --git a/Makefile.am b/Makefile.am index 09fc0ee79..b173dba51 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,7 @@ girepodir = $(includedir)/gobject-introspection-1.0/ girepo_HEADERS = \ gibaseinfo.h \ + gicallableinfo.h \ gifunctioninfo.h \ girepository.h \ girffi.h \ @@ -15,8 +16,8 @@ libgirepository_1_0_la_SOURCES = \ gfield.c \ gibaseinfo.c \ gifunctioninfo.c \ + gicallableinfo.c \ ginfo.c \ - ginfo.h \ ginvoke.c \ girepository.c \ girepository-private.h \ diff --git a/gibaseinfo.c b/gibaseinfo.c index 2f7144927..e128a9a4d 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -26,18 +26,17 @@ #include #include "gitypelib-internal.h" -#include "ginfo.h" #include "girepository-private.h" #define INVALID_REFCOUNT 0x7FFFFFFF /* info creation */ GIBaseInfo * -g_info_new_full (GIInfoType type, - GIRepository *repository, - GIBaseInfo *container, - GTypelib *typelib, - guint32 offset) +_g_info_new_full (GIInfoType type, + GIRepository *repository, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset) { GIRealInfo *info; @@ -62,7 +61,7 @@ g_info_new (GIInfoType type, GTypelib *typelib, guint32 offset) { - return g_info_new_full (type, ((GIRealInfo*)container)->repository, container, typelib, offset); + return _g_info_new_full (type, ((GIRealInfo*)container)->repository, container, typelib, offset); } void @@ -98,7 +97,7 @@ _g_info_from_entry (GIRepository *repository, DirEntry *entry = g_typelib_get_dir_entry (typelib, index); if (entry->local) - result = g_info_new_full (entry->blob_type, repository, NULL, typelib, entry->offset); + result = _g_info_new_full (entry->blob_type, repository, NULL, typelib, entry->offset); else { const gchar *namespace = g_typelib_get_string (typelib, entry->offset); @@ -126,6 +125,31 @@ _g_info_from_entry (GIRepository *repository, return (GIBaseInfo *)result; } +GITypeInfo * +_g_type_info_new (GIBaseInfo *container, + GTypelib *typelib, + guint32 offset) +{ + SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset]; + + return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, typelib, + (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset); +} + +void +_g_type_info_init (GIBaseInfo *info, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset) +{ + GIRealInfo *rinfo = (GIRealInfo*)container; + SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset]; + + _g_info_init ((GIRealInfo*)info, GI_INFO_TYPE_TYPE, rinfo->repository, container, typelib, + (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset); +} + + /* GIBaseInfo functions */ /** @@ -589,3 +613,4 @@ g_base_info_equal (GIBaseInfo *info1, GIBaseInfo *info2) return rinfo1->typelib->data + rinfo1->offset == rinfo2->typelib->data + rinfo2->offset; } + diff --git a/gibaseinfo.h b/gibaseinfo.h index c6175c3ec..79f50ce9d 100644 --- a/gibaseinfo.h +++ b/gibaseinfo.h @@ -81,7 +81,6 @@ GIBaseInfo * g_info_new (GIInfoType type, GTypelib *typelib, guint32 offset); - G_END_DECLS #endif /* __GIBASEINFO_H__ */ diff --git a/gicallableinfo.c b/gicallableinfo.c new file mode 100644 index 000000000..5013c5d69 --- /dev/null +++ b/gicallableinfo.c @@ -0,0 +1,251 @@ +/* GObject introspection: Repository implementation + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 "girepository-private.h" +#include "gitypelib-internal.h" + +/* GICallableInfo functions */ + +/** + * SECTION:gicallableinfo + * @Short_description: Struct representing a callable + * @Title: GICallableInfo + * + * GICallableInfo represents an entity which is callable. + * Currently a function (#GIFunctionInfo), virtual function, + * (#GIVirtualFunc) or callback (#GICallbackInfo). + * + * A callable has a list of arguments (#GIArgInfo), a return type, + * direction and a flag which decides if it returns null. + * + */ + +static guint32 +signature_offset (GICallableInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo*)info; + int sigoff = -1; + + switch (rinfo->type) + { + case GI_INFO_TYPE_FUNCTION: + sigoff = G_STRUCT_OFFSET (FunctionBlob, signature); + break; + case GI_INFO_TYPE_VFUNC: + sigoff = G_STRUCT_OFFSET (VFuncBlob, signature); + break; + case GI_INFO_TYPE_CALLBACK: + sigoff = G_STRUCT_OFFSET (CallbackBlob, signature); + break; + case GI_INFO_TYPE_SIGNAL: + sigoff = G_STRUCT_OFFSET (SignalBlob, signature); + break; + } + if (sigoff >= 0) + return *(guint32 *)&rinfo->typelib->data[rinfo->offset + sigoff]; + return 0; +} + +/** + * g_callable_info_get_return_type: + * @info: a #GICallableInfo + * + * Obtain the return type of a callable item as a #GITypeInfo. + * + * Returns: (transfer full): the #GITypeInfo. Free the struct by calling + * g_base_info_unref() when done. + */ +GITypeInfo * +g_callable_info_get_return_type (GICallableInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + guint32 offset; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), NULL); + + offset = signature_offset (info); + + return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, offset); +} + + +/** + * g_callable_info_load_return_type: + * @info: a #GICallableInfo + * @type: (out caller-allocates): Initialized with return type of @info + * + * Obtain information about a return value of callable; this + * function is a variant of g_callable_info_get_return_type() designed for stack + * allocation. + * + * The initialized @type must not be referenced after @info is deallocated. + */ +void +g_callable_info_load_return_type (GICallableInfo *info, + GITypeInfo *type) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + guint32 offset; + + g_return_if_fail (info != NULL); + g_return_if_fail (GI_IS_CALLABLE_INFO (info)); + + offset = signature_offset (info); + + _g_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, offset); +} + +/** + * g_callable_info_may_return_null: + * @info: a #GICallableInfo + * + * See if a callable could return %NULL. + * + * Returns: %TRUE if callable could return %NULL + */ +gboolean +g_callable_info_may_return_null (GICallableInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + SignatureBlob *blob; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), FALSE); + + blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)]; + + return blob->may_return_null; +} + +/** + * g_callable_info_get_caller_owns: + * @info: a #GICallableInfo + * + * See whether the caller owns the return value of this callable. + * #GITransfer contains a list of possible transfer values. + * + * Returns: %TRUE if the caller owns the return value, %FALSE otherwise. + */ +GITransfer +g_callable_info_get_caller_owns (GICallableInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo*) info; + SignatureBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), -1); + + blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)]; + + if (blob->caller_owns_return_value) + return GI_TRANSFER_EVERYTHING; + else if (blob->caller_owns_return_container) + return GI_TRANSFER_CONTAINER; + else + return GI_TRANSFER_NOTHING; +} + +/** + * g_callable_info_get_n_args: + * @info: a #GICallableInfo + * + * Obtain the number of arguments (both IN and OUT) for this callable. + * + * Returns: The number of arguments this callable expects. + */ +gint +g_callable_info_get_n_args (GICallableInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + gint offset; + SignatureBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), -1); + + offset = signature_offset (info); + blob = (SignatureBlob *)&rinfo->typelib->data[offset]; + + return blob->n_arguments; +} + +/** + * g_callable_info_get_arg: + * @info: a #GICallableInfo + * @n: the argument index to fetch + * + * Obtain information about a particular argument of this callable. + * + * Returns: (transfer full): the #GIArgInfo. Free it with + * g_base_info_unref() when done. + */ +GIArgInfo * +g_callable_info_get_arg (GICallableInfo *info, + gint n) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header; + gint offset; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), NULL); + + offset = signature_offset (info); + header = (Header *)rinfo->typelib->data; + + return (GIArgInfo *) g_info_new (GI_INFO_TYPE_ARG, (GIBaseInfo*)info, rinfo->typelib, + offset + header->signature_blob_size + n * header->arg_blob_size); +} + +/** + * g_callable_info_load_arg: + * @info: a #GICallableInfo + * @n: the argument index to fetch + * @arg: (out caller-allocates): Initialize with argument number @n + * + * Obtain information about a particular argument of this callable; this + * function is a variant of g_callable_info_get_arg() designed for stack + * allocation. + * + * The initialized @arg must not be referenced after @info is deallocated. + */ +void +g_callable_info_load_arg (GICallableInfo *info, + gint n, + GIArgInfo *arg) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header; + gint offset; + + g_return_if_fail (info != NULL); + g_return_if_fail (GI_IS_CALLABLE_INFO (info)); + + offset = signature_offset (info); + header = (Header *)rinfo->typelib->data; + + _g_info_init ((GIRealInfo*)arg, GI_INFO_TYPE_ARG, rinfo->repository, (GIBaseInfo*)info, rinfo->typelib, + offset + header->signature_blob_size + n * header->arg_blob_size); +} diff --git a/gicallableinfo.h b/gicallableinfo.h new file mode 100644 index 000000000..c122bd5d2 --- /dev/null +++ b/gicallableinfo.h @@ -0,0 +1,54 @@ +/* GObject introspection: Functions + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GICALLABLEINFO_H__ +#define __GICALLABLEINFO_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define GI_IS_CALLABLE_INFO(info) \ + ((g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FUNCTION) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_CALLBACK) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_SIGNAL) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_VFUNC)) + +GITypeInfo * g_callable_info_get_return_type (GICallableInfo *info); +void g_callable_info_load_return_type (GICallableInfo *info, + GITypeInfo *type); +GITransfer g_callable_info_get_caller_owns (GICallableInfo *info); +gboolean g_callable_info_may_return_null (GICallableInfo *info); +gint g_callable_info_get_n_args (GICallableInfo *info); +GIArgInfo * g_callable_info_get_arg (GICallableInfo *info, + gint n); +void g_callable_info_load_arg (GICallableInfo *info, + gint n, + GIArgInfo *arg); +G_END_DECLS + + +#endif /* __G_IREPOSITORY_H__ */ + diff --git a/ginfo.c b/ginfo.c index 0c717cfac..7a6ecbfe1 100644 --- a/ginfo.c +++ b/ginfo.c @@ -26,256 +26,8 @@ #include #include "gitypelib-internal.h" -#include "ginfo.h" #include "girepository-private.h" -/* GICallableInfo functions */ - -/** - * SECTION:gicallableinfo - * @Short_description: Struct representing a callable - * @Title: GICallableInfo - * - * GICallableInfo represents an entity which is callable. - * Currently a function (#GIFunctionInfo), virtual function, - * (#GIVirtualFunc) or callback (#GICallbackInfo). - * - * A callable has a list of arguments (#GIArgInfo), a return type, - * direction and a flag which decides if it returns null. - * - */ -static guint32 -signature_offset (GICallableInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo*)info; - int sigoff = -1; - - switch (rinfo->type) - { - case GI_INFO_TYPE_FUNCTION: - sigoff = G_STRUCT_OFFSET (FunctionBlob, signature); - break; - case GI_INFO_TYPE_VFUNC: - sigoff = G_STRUCT_OFFSET (VFuncBlob, signature); - break; - case GI_INFO_TYPE_CALLBACK: - sigoff = G_STRUCT_OFFSET (CallbackBlob, signature); - break; - case GI_INFO_TYPE_SIGNAL: - sigoff = G_STRUCT_OFFSET (SignalBlob, signature); - break; - } - if (sigoff >= 0) - return *(guint32 *)&rinfo->typelib->data[rinfo->offset + sigoff]; - return 0; -} - -GITypeInfo * -g_type_info_new (GIBaseInfo *container, - GTypelib *typelib, - guint32 offset) -{ - SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset]; - - return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, typelib, - (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset); -} - -static void -g_type_info_init (GIBaseInfo *info, - GIBaseInfo *container, - GTypelib *typelib, - guint32 offset) -{ - GIRealInfo *rinfo = (GIRealInfo*)container; - SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset]; - - _g_info_init ((GIRealInfo*)info, GI_INFO_TYPE_TYPE, rinfo->repository, container, typelib, - (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset); -} - -/** - * g_callable_info_get_return_type: - * @info: a #GICallableInfo - * - * Obtain the return type of a callable item as a #GITypeInfo. - * - * Returns: (transfer full): the #GITypeInfo. Free the struct by calling - * g_base_info_unref() when done. - */ -GITypeInfo * -g_callable_info_get_return_type (GICallableInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - guint32 offset; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), NULL); - - offset = signature_offset (info); - - return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, offset); -} - - -/** - * g_callable_info_load_return_type: - * @info: a #GICallableInfo - * @type: (out caller-allocates): Initialized with return type of @info - * - * Obtain information about a return value of callable; this - * function is a variant of g_callable_info_get_return_type() designed for stack - * allocation. - * - * The initialized @type must not be referenced after @info is deallocated. - */ -void -g_callable_info_load_return_type (GICallableInfo *info, - GITypeInfo *type) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - guint32 offset; - - g_return_if_fail (info != NULL); - g_return_if_fail (GI_IS_CALLABLE_INFO (info)); - - offset = signature_offset (info); - - g_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, offset); -} - -/** - * g_callable_info_may_return_null: - * @info: a #GICallableInfo - * - * See if a callable could return %NULL. - * - * Returns: %TRUE if callable could return %NULL - */ -gboolean -g_callable_info_may_return_null (GICallableInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - SignatureBlob *blob; - - g_return_val_if_fail (info != NULL, FALSE); - g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), FALSE); - - blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)]; - - return blob->may_return_null; -} - -/** - * g_callable_info_get_caller_owns: - * @info: a #GICallableInfo - * - * See whether the caller owns the return value of this callable. - * #GITransfer contains a list of possible transfer values. - * - * Returns: %TRUE if the caller owns the return value, %FALSE otherwise. - */ -GITransfer -g_callable_info_get_caller_owns (GICallableInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo*) info; - SignatureBlob *blob; - - g_return_val_if_fail (info != NULL, -1); - g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), -1); - - blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)]; - - if (blob->caller_owns_return_value) - return GI_TRANSFER_EVERYTHING; - else if (blob->caller_owns_return_container) - return GI_TRANSFER_CONTAINER; - else - return GI_TRANSFER_NOTHING; -} - -/** - * g_callable_info_get_n_args: - * @info: a #GICallableInfo - * - * Obtain the number of arguments (both IN and OUT) for this callable. - * - * Returns: The number of arguments this callable expects. - */ -gint -g_callable_info_get_n_args (GICallableInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - gint offset; - SignatureBlob *blob; - - g_return_val_if_fail (info != NULL, -1); - g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), -1); - - offset = signature_offset (info); - blob = (SignatureBlob *)&rinfo->typelib->data[offset]; - - return blob->n_arguments; -} - -/** - * g_callable_info_get_arg: - * @info: a #GICallableInfo - * @n: the argument index to fetch - * - * Obtain information about a particular argument of this callable. - * - * Returns: (transfer full): the #GIArgInfo. Free it with - * g_base_info_unref() when done. - */ -GIArgInfo * -g_callable_info_get_arg (GICallableInfo *info, - gint n) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header; - gint offset; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), NULL); - - offset = signature_offset (info); - header = (Header *)rinfo->typelib->data; - - return (GIArgInfo *) g_info_new (GI_INFO_TYPE_ARG, (GIBaseInfo*)info, rinfo->typelib, - offset + header->signature_blob_size + n * header->arg_blob_size); -} - -/** - * g_callable_info_load_arg: - * @info: a #GICallableInfo - * @n: the argument index to fetch - * @arg: (out caller-allocates): Initialize with argument number @n - * - * Obtain information about a particular argument of this callable; this - * function is a variant of g_callable_info_get_arg() designed for stack - * allocation. - * - * The initialized @arg must not be referenced after @info is deallocated. - */ -void -g_callable_info_load_arg (GICallableInfo *info, - gint n, - GIArgInfo *arg) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header; - gint offset; - - g_return_if_fail (info != NULL); - g_return_if_fail (GI_IS_CALLABLE_INFO (info)); - - offset = signature_offset (info); - header = (Header *)rinfo->typelib->data; - - _g_info_init ((GIRealInfo*)arg, GI_INFO_TYPE_ARG, rinfo->repository, (GIBaseInfo*)info, rinfo->typelib, - offset + header->signature_blob_size + n * header->arg_blob_size); -} /* GIArgInfo function */ @@ -526,7 +278,7 @@ g_arg_info_get_type (GIArgInfo *info) g_return_val_if_fail (info != NULL, NULL); g_return_val_if_fail (GI_IS_ARG_INFO (info), NULL); - return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type)); + return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type)); } /** @@ -549,7 +301,7 @@ g_arg_info_load_type (GIArgInfo *info, g_return_if_fail (info != NULL); g_return_if_fail (GI_IS_ARG_INFO (info)); - g_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type)); + _g_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type)); } /* GITypeInfo functions */ @@ -663,7 +415,7 @@ g_type_info_get_param_type (GITypeInfo *info, case GI_TYPE_TAG_GLIST: case GI_TYPE_TAG_GSLIST: case GI_TYPE_TAG_GHASH: - return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, + return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob) * n); break; @@ -1171,7 +923,7 @@ g_field_info_get_type (GIFieldInfo *info) type_info->type_is_embedded = TRUE; } else - return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (FieldBlob, type)); + return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (FieldBlob, type)); return (GIBaseInfo*)type_info; } @@ -1964,7 +1716,7 @@ g_property_info_get_type (GIPropertyInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (PropertyBlob, type)); + return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (PropertyBlob, type)); } @@ -2107,7 +1859,7 @@ g_constant_info_get_type (GIConstantInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 8); + return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 8); } gint @@ -2257,7 +2009,7 @@ g_union_info_get_discriminator_type (GIUnionInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 24); + return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 24); } GIConstantInfo * diff --git a/ginfo.h b/ginfo.h deleted file mode 100644 index 15138cfbb..000000000 --- a/ginfo.h +++ /dev/null @@ -1,42 +0,0 @@ -/* GObject introspection: Typelib info functions - * - * Copyright (C) 2008 Red Hat, Inc - * - * 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 __GIRINFO_H__ -#define __GIRINFO_H__ - -#include "girepository.h" - -G_BEGIN_DECLS - -GITypeInfo * -g_type_info_new (GIBaseInfo *container, - GTypelib *typelib, - guint32 offset); - -GIBaseInfo * -g_info_new_full (GIInfoType type, - GIRepository *repository, - GIBaseInfo *container, - GTypelib *typelib, - guint32 offset); - -G_END_DECLS - -#endif diff --git a/girepository-private.h b/girepository-private.h index 4ded32b86..52fc749a2 100644 --- a/girepository-private.h +++ b/girepository-private.h @@ -80,5 +80,21 @@ GIBaseInfo * _g_info_from_entry (GIRepository *repository, GTypelib *typelib, guint16 index); +GIBaseInfo * _g_info_new_full (GIInfoType type, + GIRepository *repository, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset); + +GITypeInfo * _g_type_info_new (GIBaseInfo *container, + GTypelib *typelib, + guint32 offset); + +void _g_type_info_init (GIBaseInfo *info, + GIBaseInfo *container, + GTypelib *typelib, + guint32 offset); + + #endif /* __GIREPOSITORY_PRIVATE_H__ */ diff --git a/girepository.c b/girepository.c index f06270eb3..66a604eb4 100644 --- a/girepository.c +++ b/girepository.c @@ -30,7 +30,7 @@ #include #include "girepository.h" #include "gitypelib-internal.h" -#include "ginfo.h" +#include "girepository-private.h" #include "glib-compat.h" #include "config.h" @@ -606,9 +606,9 @@ find_interface (gpointer key, if (index != 0) { entry = g_typelib_get_dir_entry (typelib, index); - iface_data->iface = g_info_new_full (entry->blob_type, - iface_data->repo, - NULL, typelib, entry->offset); + iface_data->iface = _g_info_new_full (entry->blob_type, + iface_data->repo, + NULL, typelib, entry->offset); } } diff --git a/girepository.h b/girepository.h index 7ddb70f5a..543dab447 100644 --- a/girepository.h +++ b/girepository.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -145,41 +146,6 @@ void gi_cclosure_marshal_generic (GClosure *closure, gpointer invocation_hint, gpointer marshal_data); -/* GICallableInfo */ - -#define GI_IS_CALLABLE_INFO(info) \ - ((g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FUNCTION) || \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_CALLBACK) || \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_SIGNAL) || \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_VFUNC)) - -/** - * GITransfer: - * @GI_TRANSFER_NOTHING: transfer nothing to the caller - * @GI_TRANSFER_CONTAINER: transfer the container (eg list, array, - * hashtable), but no the contents to the caller. - * @GI_TRANSFER_EVERYTHING: transfer everything to the caller. - * - * Represent the transfer ownership information of a #GICallableInfo or - * a #GIArgInfo. - */ -typedef enum { - GI_TRANSFER_NOTHING, - GI_TRANSFER_CONTAINER, - GI_TRANSFER_EVERYTHING -} GITransfer; - -GITypeInfo * g_callable_info_get_return_type (GICallableInfo *info); -void g_callable_info_load_return_type (GICallableInfo *info, - GITypeInfo *type); -GITransfer g_callable_info_get_caller_owns (GICallableInfo *info); -gboolean g_callable_info_may_return_null (GICallableInfo *info); -gint g_callable_info_get_n_args (GICallableInfo *info); -GIArgInfo * g_callable_info_get_arg (GICallableInfo *info, - gint n); -void g_callable_info_load_arg (GICallableInfo *info, - gint n, - GIArgInfo *arg); /* GIArgInfo */ diff --git a/gitypes.h b/gitypes.h index 49fe017da..424e4ebfb 100644 --- a/gitypes.h +++ b/gitypes.h @@ -243,6 +243,22 @@ typedef enum GI_INFO_TYPE_UNRESOLVED } GIInfoType; +/** + * GITransfer: + * @GI_TRANSFER_NOTHING: transfer nothing to the caller + * @GI_TRANSFER_CONTAINER: transfer the container (eg list, array, + * hashtable), but no the contents to the caller. + * @GI_TRANSFER_EVERYTHING: transfer everything to the caller. + * + * Represent the transfer ownership information of a #GICallableInfo or + * a #GIArgInfo. + */ +typedef enum { + GI_TRANSFER_NOTHING, + GI_TRANSFER_CONTAINER, + GI_TRANSFER_EVERYTHING +} GITransfer; + G_END_DECLS From 968850eaf10b656dd12a65598c57ae072902a483 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 5 Jun 2010 12:39:00 -0300 Subject: [PATCH 304/692] [girepository] Fix a couple of typos --- gibaseinfo.c | 2 +- gicallableinfo.c | 2 +- gicallableinfo.h | 4 ++-- gifunctioninfo.c | 2 +- gifunctioninfo.h | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gibaseinfo.c b/gibaseinfo.c index e128a9a4d..10e5d7c38 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -1,4 +1,4 @@ -/* GObject introspection: Repository implementation +/* GObject introspection: Base struct implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gicallableinfo.c b/gicallableinfo.c index 5013c5d69..da6b50b05 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -1,4 +1,4 @@ -/* GObject introspection: Repository implementation +/* GObject introspection: Callable implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gicallableinfo.h b/gicallableinfo.h index c122bd5d2..479baa2ae 100644 --- a/gicallableinfo.h +++ b/gicallableinfo.h @@ -1,4 +1,4 @@ -/* GObject introspection: Functions +/* GObject introspection: Callable * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. @@ -50,5 +50,5 @@ void g_callable_info_load_arg (GICallableInfo *info, G_END_DECLS -#endif /* __G_IREPOSITORY_H__ */ +#endif /* __GICALLABLEINFO_H__ */ diff --git a/gifunctioninfo.c b/gifunctioninfo.c index 30c7ca69f..07e0ec677 100644 --- a/gifunctioninfo.c +++ b/gifunctioninfo.c @@ -1,4 +1,4 @@ -/* GObject introspection: Repository implementation +/* GObject introspection: Function implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gifunctioninfo.h b/gifunctioninfo.h index 94b2d6f9a..9c47bd16a 100644 --- a/gifunctioninfo.h +++ b/gifunctioninfo.h @@ -1,4 +1,4 @@ -/* GObject introspection: Functions +/* GObject introspection: Function * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. @@ -93,5 +93,5 @@ gboolean g_function_info_invoke (GIFunctionInfo *info, G_END_DECLS -#endif /* __G_IREPOSITORY_H__ */ +#endif /* __GIFUNCTIONINFO_H__ */ From 6d51857f01a15b4c46914dbc253b74dbde834953 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 5 Jun 2010 12:39:21 -0300 Subject: [PATCH 305/692] [gitypes.h] Do not include gibaseinfo.h To avoid cyclic dependencies --- gitypes.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/gitypes.h b/gitypes.h index 424e4ebfb..036ab2be4 100644 --- a/gitypes.h +++ b/gitypes.h @@ -26,8 +26,6 @@ #error "Only can be included directly." #endif -#include - G_BEGIN_DECLS typedef struct _GIBaseInfoStub GIBaseInfo; From 2e91ba3b3ec7f87d5090a9bd839808b3d03bb3fe Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 5 Jun 2010 12:40:15 -0300 Subject: [PATCH 306/692] [girepository] Move GIArgInfo out of ginfo.ch --- Makefile.am | 2 + giarginfo.c | 301 +++++++++++++++++++++++++++++++++++++++++++++++++ giarginfo.h | 50 ++++++++ ginfo.c | 275 -------------------------------------------- girepository.h | 56 +-------- gitypes.h | 35 ++++++ 6 files changed, 389 insertions(+), 330 deletions(-) create mode 100644 giarginfo.c create mode 100644 giarginfo.h diff --git a/Makefile.am b/Makefile.am index b173dba51..07d70d0ac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,6 @@ girepodir = $(includedir)/gobject-introspection-1.0/ girepo_HEADERS = \ + giarginfo.h \ gibaseinfo.h \ gicallableinfo.h \ gifunctioninfo.h \ @@ -14,6 +15,7 @@ noinst_LTLIBRARIES = libgirepository-parser.la libgirepository_1_0_la_SOURCES = \ gdump.c \ gfield.c \ + giarginfo.c \ gibaseinfo.c \ gifunctioninfo.c \ gicallableinfo.c \ diff --git a/giarginfo.c b/giarginfo.c new file mode 100644 index 000000000..40dcd52b5 --- /dev/null +++ b/giarginfo.c @@ -0,0 +1,301 @@ +/* GObject introspection: Argument implementation + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 "gitypelib-internal.h" +#include "girepository-private.h" + + +/* GIArgInfo function */ + +/** + * SECTION:giarginfo + * @Short_description: Struct representing an argument + * @Title: GIArgInfo + * + * GIArgInfo represents an argument. An argument is always + * part of a #GICallableInfo. + * + * + */ + +/** + * g_arg_info_get_direction: + * @info: a #GIArgInfo + * + * Obtain the direction of the argument. Check #GIDirection for possible + * direction values. + * + * Returns: the direction + */ +GIDirection +g_arg_info_get_direction (GIArgInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_ARG_INFO (info), -1); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->in && blob->out) + return GI_DIRECTION_INOUT; + else if (blob->out) + return GI_DIRECTION_OUT; + else + return GI_DIRECTION_IN; +} + +/** + * g_arg_info_is_return_value: + * @info: a #GIArgInfo + * + * Obtain if the argument is a return value. It can either be a + * parameter or a return value. + * + * Returns: %TRUE if it is a return value + */ +gboolean +g_arg_info_is_return_value (GIArgInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->return_value; +} + +/** + * g_arg_info_is_caller_allocates: + * @info: a #GIArgInfo + * + * Obtain if the argument is a pointer to a struct or object that will + * receive an output of a function. The default assumption for + * %GI_DIRECTION_OUT arguments which have allocation is that the + * callee allocates; if this is %TRUE, then the caller must allocate. + * + * Returns: %TRUE if caller is required to have allocated the argument + */ +gboolean +g_arg_info_is_caller_allocates (GIArgInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->caller_allocates; +} + +/** + * g_arg_info_is_optional: + * @info: a #GIArgInfo + * + * Obtain if the argument is optional. + * + * Returns: %TRUE if it is an optional argument + */ +gboolean +g_arg_info_is_optional (GIArgInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->optional; +} + +/** + * g_arg_info_may_be_null: + * @info: a #GIArgInfo + * + * Obtain if the argument accepts %NULL. + * + * Returns: %TRUE if it accepts %NULL + */ +gboolean +g_arg_info_may_be_null (GIArgInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->allow_none; +} + +/** + * g_arg_info_get_ownership_transfer: + * @info: a #GIArgInfo + * + * Obtain the ownership transfer for this argument. + * #GITransfer contains a list of possible values. + * + * Returns: the transfer + */ +GITransfer +g_arg_info_get_ownership_transfer (GIArgInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_ARG_INFO (info), -1); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->transfer_ownership) + return GI_TRANSFER_EVERYTHING; + else if (blob->transfer_container_ownership) + return GI_TRANSFER_CONTAINER; + else + return GI_TRANSFER_NOTHING; +} + +/** + * g_arg_info_get_scope: + * @info: a #GIArgInfo + * + * Obtain the scope type for this argument. The scope type explains + * how a callback is going to be invoked, most importantly when + * the resources required to invoke it can be freed. + * #GIScopeType contains a list of possible values. + * + * Returns: the scope type + */ +GIScopeType +g_arg_info_get_scope (GIArgInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_ARG_INFO (info), -1); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->scope; +} + +/** + * g_arg_info_get_closure: + * @info: a #GIArgInfo + * + * Obtain the index of the user data argument. This is only valid + * for arguments which are callbacks. + * + * Returns: index of the user data argument or -1 if there is none + */ +gint +g_arg_info_get_closure (GIArgInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_ARG_INFO (info), -1); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->closure; +} + +/** + * g_arg_info_get_destroy: + * @info: a #GIArgInfo + * + * Obtains the index of the #GDestroyNotify argument. This is only valid + * for arguments which are callbacks. + * + * Returns: index of the #GDestroyNotify argument or -1 if there is none + */ +gint +g_arg_info_get_destroy (GIArgInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_ARG_INFO (info), -1); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->destroy; +} + +/** + * g_arg_info_get_type: + * @info: a #GIArgInfo + * + * Obtain the type information for @info. + * + * Returns: (transfer full): the #GIArgInfo, free it with + * g_base_info_unref() when done. + */ +GITypeInfo * +g_arg_info_get_type (GIArgInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_ARG_INFO (info), NULL); + + return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type)); +} + +/** + * g_arg_info_load_type: + * @info: a #GIArgInfo + * @type: (out caller-allocates): Initialized with information about type of @info + * + * Obtain information about a the type of given argument @info; this + * function is a variant of g_arg_info_get_type() designed for stack + * allocation. + * + * The initialized @type must not be referenced after @info is deallocated. + */ +void +g_arg_info_load_type (GIArgInfo *info, + GITypeInfo *type) +{ + GIRealInfo *rinfo = (GIRealInfo*) info; + + g_return_if_fail (info != NULL); + g_return_if_fail (GI_IS_ARG_INFO (info)); + + _g_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type)); +} diff --git a/giarginfo.h b/giarginfo.h new file mode 100644 index 000000000..e38d16fe1 --- /dev/null +++ b/giarginfo.h @@ -0,0 +1,50 @@ +/* GObject introspection: Argument + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GIARGINFO_H__ +#define __GIARGINFO_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define GI_IS_ARG_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ARG) + +GIDirection g_arg_info_get_direction (GIArgInfo *info); +gboolean g_arg_info_is_return_value (GIArgInfo *info); +gboolean g_arg_info_is_optional (GIArgInfo *info); +gboolean g_arg_info_is_caller_allocates (GIArgInfo *info); +gboolean g_arg_info_may_be_null (GIArgInfo *info); +GITransfer g_arg_info_get_ownership_transfer (GIArgInfo *info); +GIScopeType g_arg_info_get_scope (GIArgInfo *info); +gint g_arg_info_get_closure (GIArgInfo *info); +gint g_arg_info_get_destroy (GIArgInfo *info); +GITypeInfo * g_arg_info_get_type (GIArgInfo *info); +void g_arg_info_load_type (GIArgInfo *info, + GITypeInfo *type); +G_END_DECLS + +#endif /* __GIARGINFO_H__ */ diff --git a/ginfo.c b/ginfo.c index 7a6ecbfe1..3b55b80a7 100644 --- a/ginfo.c +++ b/ginfo.c @@ -29,281 +29,6 @@ #include "girepository-private.h" -/* GIArgInfo function */ - -/** - * SECTION:giarginfo - * @Short_description: Struct representing an argument - * @Title: GIArgInfo - * - * GIArgInfo represents an argument. An argument is always - * part of a #GICallableInfo. - * - * - */ - -/** - * g_arg_info_get_direction: - * @info: a #GIArgInfo - * - * Obtain the direction of the argument. Check #GIDirection for possible - * direction values. - * - * Returns: the direction - */ -GIDirection -g_arg_info_get_direction (GIArgInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob; - - g_return_val_if_fail (info != NULL, -1); - g_return_val_if_fail (GI_IS_ARG_INFO (info), -1); - - blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->in && blob->out) - return GI_DIRECTION_INOUT; - else if (blob->out) - return GI_DIRECTION_OUT; - else - return GI_DIRECTION_IN; -} - -/** - * g_arg_info_is_return_value: - * @info: a #GIArgInfo - * - * Obtain if the argument is a return value. It can either be a - * parameter or a return value. - * - * Returns: %TRUE if it is a return value - */ -gboolean -g_arg_info_is_return_value (GIArgInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob; - - g_return_val_if_fail (info != NULL, FALSE); - g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE); - - blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->return_value; -} - -/** - * g_arg_info_is_caller_allocates: - * @info: a #GIArgInfo - * - * Obtain if the argument is a pointer to a struct or object that will - * receive an output of a function. The default assumption for - * %GI_DIRECTION_OUT arguments which have allocation is that the - * callee allocates; if this is %TRUE, then the caller must allocate. - * - * Returns: %TRUE if caller is required to have allocated the argument - */ -gboolean -g_arg_info_is_caller_allocates (GIArgInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob; - - g_return_val_if_fail (info != NULL, FALSE); - g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE); - - blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->caller_allocates; -} - -/** - * g_arg_info_is_optional: - * @info: a #GIArgInfo - * - * Obtain if the argument is optional. - * - * Returns: %TRUE if it is an optional argument - */ -gboolean -g_arg_info_is_optional (GIArgInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob; - - g_return_val_if_fail (info != NULL, FALSE); - g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE); - - blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->optional; -} - -/** - * g_arg_info_may_be_null: - * @info: a #GIArgInfo - * - * Obtain if the argument accepts %NULL. - * - * Returns: %TRUE if it accepts %NULL - */ -gboolean -g_arg_info_may_be_null (GIArgInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob; - - g_return_val_if_fail (info != NULL, FALSE); - g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE); - - blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->allow_none; -} - -/** - * g_arg_info_get_ownership_transfer: - * @info: a #GIArgInfo - * - * Obtain the ownership transfer for this argument. - * #GITransfer contains a list of possible values. - * - * Returns: the transfer - */ -GITransfer -g_arg_info_get_ownership_transfer (GIArgInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob; - - g_return_val_if_fail (info != NULL, -1); - g_return_val_if_fail (GI_IS_ARG_INFO (info), -1); - - blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->transfer_ownership) - return GI_TRANSFER_EVERYTHING; - else if (blob->transfer_container_ownership) - return GI_TRANSFER_CONTAINER; - else - return GI_TRANSFER_NOTHING; -} - -/** - * g_arg_info_get_scope: - * @info: a #GIArgInfo - * - * Obtain the scope type for this argument. The scope type explains - * how a callback is going to be invoked, most importantly when - * the resources required to invoke it can be freed. - * #GIScopeType contains a list of possible values. - * - * Returns: the scope type - */ -GIScopeType -g_arg_info_get_scope (GIArgInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob; - - g_return_val_if_fail (info != NULL, -1); - g_return_val_if_fail (GI_IS_ARG_INFO (info), -1); - - blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->scope; -} - -/** - * g_arg_info_get_closure: - * @info: a #GIArgInfo - * - * Obtain the index of the user data argument. This is only valid - * for arguments which are callbacks. - * - * Returns: index of the user data argument or -1 if there is none - */ -gint -g_arg_info_get_closure (GIArgInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob; - - g_return_val_if_fail (info != NULL, -1); - g_return_val_if_fail (GI_IS_ARG_INFO (info), -1); - - blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->closure; -} - -/** - * g_arg_info_get_destroy: - * @info: a #GIArgInfo - * - * Obtains the index of the #GDestroyNotify argument. This is only valid - * for arguments which are callbacks. - * - * Returns: index of the #GDestroyNotify argument or -1 if there is none - */ -gint -g_arg_info_get_destroy (GIArgInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ArgBlob *blob; - - g_return_val_if_fail (info != NULL, -1); - g_return_val_if_fail (GI_IS_ARG_INFO (info), -1); - - blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->destroy; -} - -/** - * g_arg_info_get_type: - * @info: a #GIArgInfo - * - * Obtain the type information for @info. - * - * Returns: (transfer full): the #GIArgInfo, free it with - * g_base_info_unref() when done. - */ -GITypeInfo * -g_arg_info_get_type (GIArgInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_ARG_INFO (info), NULL); - - return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type)); -} - -/** - * g_arg_info_load_type: - * @info: a #GIArgInfo - * @type: (out caller-allocates): Initialized with information about type of @info - * - * Obtain information about a the type of given argument @info; this - * function is a variant of g_arg_info_get_type() designed for stack - * allocation. - * - * The initialized @type must not be referenced after @info is deallocated. - */ -void -g_arg_info_load_type (GIArgInfo *info, - GITypeInfo *type) -{ - GIRealInfo *rinfo = (GIRealInfo*) info; - - g_return_if_fail (info != NULL); - g_return_if_fail (GI_IS_ARG_INFO (info)); - - _g_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type)); -} - /* GITypeInfo functions */ /** diff --git a/girepository.h b/girepository.h index 543dab447..980049eb6 100644 --- a/girepository.h +++ b/girepository.h @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -146,61 +147,6 @@ void gi_cclosure_marshal_generic (GClosure *closure, gpointer invocation_hint, gpointer marshal_data); - -/* GIArgInfo */ - -#define GI_IS_ARG_INFO(info) \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ARG) - -/** - * GIDirection: - * @GI_DIRECTION_IN: in argument. - * @GI_DIRECTION_OUT: out argument. - * @GI_DIRECTION_INOUT: in and out argument. - * - * The direction of a #GIArgInfo. - */ -typedef enum { - GI_DIRECTION_IN, - GI_DIRECTION_OUT, - GI_DIRECTION_INOUT -} GIDirection; - -/** - * GIScopeType: - * @GI_SCOPE_TYPE_INVALID: The argument is not of callback type. - * @GI_SCOPE_TYPE_CALL: The callback and associated user_data is only - * used during the call to this function. - * @GI_SCOPE_TYPE_ASYNC: The callback and associated user_data is - * only used until the callback is invoked, and the callback. - * is invoked always exactly once. - * @GI_SCOPE_TYPE_NOTIFIED: The callback and and associated - * user_data is used until the caller is notfied via the destroy_notify. - * - * Scope type of a #GIArgInfo representing callback, determines how the - * callback is invoked and is used to decided when the invoke structs - * can be freed. - */ -typedef enum { - GI_SCOPE_TYPE_INVALID, - GI_SCOPE_TYPE_CALL, - GI_SCOPE_TYPE_ASYNC, - GI_SCOPE_TYPE_NOTIFIED -} GIScopeType; - -GIDirection g_arg_info_get_direction (GIArgInfo *info); -gboolean g_arg_info_is_return_value (GIArgInfo *info); -gboolean g_arg_info_is_optional (GIArgInfo *info); -gboolean g_arg_info_is_caller_allocates (GIArgInfo *info); -gboolean g_arg_info_may_be_null (GIArgInfo *info); -GITransfer g_arg_info_get_ownership_transfer (GIArgInfo *info); -GIScopeType g_arg_info_get_scope (GIArgInfo *info); -gint g_arg_info_get_closure (GIArgInfo *info); -gint g_arg_info_get_destroy (GIArgInfo *info); -GITypeInfo * g_arg_info_get_type (GIArgInfo *info); -void g_arg_info_load_type (GIArgInfo *info, - GITypeInfo *type); - /* GITypeInfo */ #define GI_IS_TYPE_INFO(info) \ diff --git a/gitypes.h b/gitypes.h index 036ab2be4..6e35489a7 100644 --- a/gitypes.h +++ b/gitypes.h @@ -257,6 +257,41 @@ typedef enum { GI_TRANSFER_EVERYTHING } GITransfer; +/** + * GIDirection: + * @GI_DIRECTION_IN: in argument. + * @GI_DIRECTION_OUT: out argument. + * @GI_DIRECTION_INOUT: in and out argument. + * + * The direction of a #GIArgInfo. + */ +typedef enum { + GI_DIRECTION_IN, + GI_DIRECTION_OUT, + GI_DIRECTION_INOUT +} GIDirection; + +/** + * GIScopeType: + * @GI_SCOPE_TYPE_INVALID: The argument is not of callback type. + * @GI_SCOPE_TYPE_CALL: The callback and associated user_data is only + * used during the call to this function. + * @GI_SCOPE_TYPE_ASYNC: The callback and associated user_data is + * only used until the callback is invoked, and the callback. + * is invoked always exactly once. + * @GI_SCOPE_TYPE_NOTIFIED: The callback and and associated + * user_data is used until the caller is notfied via the destroy_notify. + * + * Scope type of a #GIArgInfo representing callback, determines how the + * callback is invoked and is used to decided when the invoke structs + * can be freed. + */ +typedef enum { + GI_SCOPE_TYPE_INVALID, + GI_SCOPE_TYPE_CALL, + GI_SCOPE_TYPE_ASYNC, + GI_SCOPE_TYPE_NOTIFIED +} GIScopeType; G_END_DECLS From 4d3a528f5da56b78a8caa8a6c80447a357138f64 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 5 Jun 2010 12:59:33 -0300 Subject: [PATCH 307/692] [girepository] Move the enums Move the est of the enums over to gitypes.h --- girepository.h | 118 ------------------------------------------------- gitypes.h | 118 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 118 deletions(-) diff --git a/girepository.h b/girepository.h index 980049eb6..e0647197b 100644 --- a/girepository.h +++ b/girepository.h @@ -152,95 +152,6 @@ void gi_cclosure_marshal_generic (GClosure *closure, #define GI_IS_TYPE_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_TYPE) -/** - * GITypeTag: - * @GI_TYPE_TAG_VOID: void - * @GI_TYPE_TAG_BOOLEAN: boolean - * @GI_TYPE_TAG_INT8: 8-bit signed integer - * @GI_TYPE_TAG_UINT8: 8-bit unsigned integer - * @GI_TYPE_TAG_INT16: 16-bit signed integer - * @GI_TYPE_TAG_UINT16: 16-bit unsigned integer - * @GI_TYPE_TAG_INT32: 32-bit signed integer - * @GI_TYPE_TAG_UINT32: 32-bit unsigned integer - * @GI_TYPE_TAG_INT64: 64-bit signed integer - * @GI_TYPE_TAG_UINT64: 64-bit unsigned integer - * @GI_TYPE_TAG_SHORT: signed short - * @GI_TYPE_TAG_USHORT: unsigned hosrt - * @GI_TYPE_TAG_INT: signed integer - * @GI_TYPE_TAG_UINT: unsigned integer - * @GI_TYPE_TAG_LONG: signed long - * @GI_TYPE_TAG_ULONG: unsigned long - * @GI_TYPE_TAG_SSIZE: ssize_t - * @GI_TYPE_TAG_SIZE: size_t - * @GI_TYPE_TAG_FLOAT: float - * @GI_TYPE_TAG_DOUBLE: double floating point - * @GI_TYPE_TAG_TIME_T: time_t - * @GI_TYPE_TAG_GTYPE: a #GType - * @GI_TYPE_TAG_UTF8: a UTF-8 encoded string - * @GI_TYPE_TAG_FILENAME: a filename, encoded in the same encoding - * as the native filesystem is using. - * @GI_TYPE_TAG_ARRAY: an array - * @GI_TYPE_TAG_INTERFACE: an extended interface object - * @GI_TYPE_TAG_GLIST: a #GList - * @GI_TYPE_TAG_GSLIST: a #GSList - * @GI_TYPE_TAG_GHASH: a #GHashTable - * @GI_TYPE_TAG_ERROR: a #GError - * - * The type tag of a #GITypeInfo. - */ -typedef enum { - /* Basic types */ - GI_TYPE_TAG_VOID = 0, - GI_TYPE_TAG_BOOLEAN = 1, - GI_TYPE_TAG_INT8 = 2, - GI_TYPE_TAG_UINT8 = 3, - GI_TYPE_TAG_INT16 = 4, - GI_TYPE_TAG_UINT16 = 5, - GI_TYPE_TAG_INT32 = 6, - GI_TYPE_TAG_UINT32 = 7, - GI_TYPE_TAG_INT64 = 8, - GI_TYPE_TAG_UINT64 = 9, - GI_TYPE_TAG_SHORT = 10, - GI_TYPE_TAG_USHORT = 11, - GI_TYPE_TAG_INT = 12, - GI_TYPE_TAG_UINT = 13, - GI_TYPE_TAG_LONG = 14, - GI_TYPE_TAG_ULONG = 15, - GI_TYPE_TAG_SSIZE = 16, - GI_TYPE_TAG_SIZE = 17, - GI_TYPE_TAG_FLOAT = 18, - GI_TYPE_TAG_DOUBLE = 19, - GI_TYPE_TAG_TIME_T = 20, - GI_TYPE_TAG_GTYPE = 21, - GI_TYPE_TAG_UTF8 = 22, - GI_TYPE_TAG_FILENAME = 23, - /* Non-basic types */ - GI_TYPE_TAG_ARRAY = 24, - GI_TYPE_TAG_INTERFACE = 25, - GI_TYPE_TAG_GLIST = 26, - GI_TYPE_TAG_GSLIST = 27, - GI_TYPE_TAG_GHASH = 28, - GI_TYPE_TAG_ERROR = 29 - /* Note - there is only room currently for 32 tags. - * See docs/typelib-format.txt SimpleTypeBlob definition */ -} GITypeTag; - -/** - * GIArrayType: - * @GI_ARRAY_TYPE_C: a C array, char[] for instance - * @GI_ARRAY_TYPE_ARRAY: a @GArray array - * @GI_ARRAY_TYPE_PTR_ARRAY: a #GPtrArray array - * @GI_ARRAY_TYPE_BYTE_ARRAY: a #GByteArray array - * - * The type of array in a #GITypeInfo. - */ -typedef enum { - GI_ARRAY_TYPE_C, - GI_ARRAY_TYPE_ARRAY, - GI_ARRAY_TYPE_PTR_ARRAY, - GI_ARRAY_TYPE_BYTE_ARRAY -} GIArrayType; - #define G_TYPE_TAG_IS_BASIC(tag) (tag < GI_TYPE_TAG_ARRAY) const gchar* g_type_tag_to_string (GITypeTag type); @@ -281,20 +192,6 @@ glong g_value_info_get_value (GIValueInfo *info); #define GI_IS_FIELD_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FIELD) -/** - * GIFieldInfoFlags: - * @GI_FIELD_IS_READABLE: field is readable. - * @GI_FIELD_IS_WRITABLE: field is writable. - * - * Flags for a #GIFieldInfo. - */ - -typedef enum -{ - GI_FIELD_IS_READABLE = 1 << 0, - GI_FIELD_IS_WRITABLE = 1 << 1 -} GIFieldInfoFlags; - GIFieldInfoFlags g_field_info_get_flags (GIFieldInfo *info); gint g_field_info_get_size (GIFieldInfo *info); gint g_field_info_get_offset (GIFieldInfo *info); @@ -463,21 +360,6 @@ gboolean g_signal_info_true_stops_emit (GISignalInfo #define GI_IS_VFUNC_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_VFUNC) -/** - * GIVFuncInfoFlags: - * @GI_VFUNC_MUST_CHAIN_UP: chains up to the parent type - * @GI_VFUNC_MUST_OVERRIDE: overrides - * @GI_VFUNC_MUST_NOT_OVERRIDE: does not override - * - * Flags of a #GIVFuncInfo struct. - */ -typedef enum -{ - GI_VFUNC_MUST_CHAIN_UP = 1 << 0, - GI_VFUNC_MUST_OVERRIDE = 1 << 1, - GI_VFUNC_MUST_NOT_OVERRIDE = 1 << 2 -} GIVFuncInfoFlags; - GIVFuncInfoFlags g_vfunc_info_get_flags (GIVFuncInfo *info); gint g_vfunc_info_get_offset (GIVFuncInfo *info); GISignalInfo * g_vfunc_info_get_signal (GIVFuncInfo *info); diff --git a/gitypes.h b/gitypes.h index 6e35489a7..b6986b47b 100644 --- a/gitypes.h +++ b/gitypes.h @@ -295,5 +295,123 @@ typedef enum { G_END_DECLS +/** + * GITypeTag: + * @GI_TYPE_TAG_VOID: void + * @GI_TYPE_TAG_BOOLEAN: boolean + * @GI_TYPE_TAG_INT8: 8-bit signed integer + * @GI_TYPE_TAG_UINT8: 8-bit unsigned integer + * @GI_TYPE_TAG_INT16: 16-bit signed integer + * @GI_TYPE_TAG_UINT16: 16-bit unsigned integer + * @GI_TYPE_TAG_INT32: 32-bit signed integer + * @GI_TYPE_TAG_UINT32: 32-bit unsigned integer + * @GI_TYPE_TAG_INT64: 64-bit signed integer + * @GI_TYPE_TAG_UINT64: 64-bit unsigned integer + * @GI_TYPE_TAG_SHORT: signed short + * @GI_TYPE_TAG_USHORT: unsigned hosrt + * @GI_TYPE_TAG_INT: signed integer + * @GI_TYPE_TAG_UINT: unsigned integer + * @GI_TYPE_TAG_LONG: signed long + * @GI_TYPE_TAG_ULONG: unsigned long + * @GI_TYPE_TAG_SSIZE: ssize_t + * @GI_TYPE_TAG_SIZE: size_t + * @GI_TYPE_TAG_FLOAT: float + * @GI_TYPE_TAG_DOUBLE: double floating point + * @GI_TYPE_TAG_TIME_T: time_t + * @GI_TYPE_TAG_GTYPE: a #GType + * @GI_TYPE_TAG_UTF8: a UTF-8 encoded string + * @GI_TYPE_TAG_FILENAME: a filename, encoded in the same encoding + * as the native filesystem is using. + * @GI_TYPE_TAG_ARRAY: an array + * @GI_TYPE_TAG_INTERFACE: an extended interface object + * @GI_TYPE_TAG_GLIST: a #GList + * @GI_TYPE_TAG_GSLIST: a #GSList + * @GI_TYPE_TAG_GHASH: a #GHashTable + * @GI_TYPE_TAG_ERROR: a #GError + * + * The type tag of a #GITypeInfo. + */ +typedef enum { + /* Basic types */ + GI_TYPE_TAG_VOID = 0, + GI_TYPE_TAG_BOOLEAN = 1, + GI_TYPE_TAG_INT8 = 2, + GI_TYPE_TAG_UINT8 = 3, + GI_TYPE_TAG_INT16 = 4, + GI_TYPE_TAG_UINT16 = 5, + GI_TYPE_TAG_INT32 = 6, + GI_TYPE_TAG_UINT32 = 7, + GI_TYPE_TAG_INT64 = 8, + GI_TYPE_TAG_UINT64 = 9, + GI_TYPE_TAG_SHORT = 10, + GI_TYPE_TAG_USHORT = 11, + GI_TYPE_TAG_INT = 12, + GI_TYPE_TAG_UINT = 13, + GI_TYPE_TAG_LONG = 14, + GI_TYPE_TAG_ULONG = 15, + GI_TYPE_TAG_SSIZE = 16, + GI_TYPE_TAG_SIZE = 17, + GI_TYPE_TAG_FLOAT = 18, + GI_TYPE_TAG_DOUBLE = 19, + GI_TYPE_TAG_TIME_T = 20, + GI_TYPE_TAG_GTYPE = 21, + GI_TYPE_TAG_UTF8 = 22, + GI_TYPE_TAG_FILENAME = 23, + /* Non-basic types */ + GI_TYPE_TAG_ARRAY = 24, + GI_TYPE_TAG_INTERFACE = 25, + GI_TYPE_TAG_GLIST = 26, + GI_TYPE_TAG_GSLIST = 27, + GI_TYPE_TAG_GHASH = 28, + GI_TYPE_TAG_ERROR = 29 + /* Note - there is only room currently for 32 tags. + * See docs/typelib-format.txt SimpleTypeBlob definition */ +} GITypeTag; + +/** + * GIArrayType: + * @GI_ARRAY_TYPE_C: a C array, char[] for instance + * @GI_ARRAY_TYPE_ARRAY: a @GArray array + * @GI_ARRAY_TYPE_PTR_ARRAY: a #GPtrArray array + * @GI_ARRAY_TYPE_BYTE_ARRAY: a #GByteArray array + * + * The type of array in a #GITypeInfo. + */ +typedef enum { + GI_ARRAY_TYPE_C, + GI_ARRAY_TYPE_ARRAY, + GI_ARRAY_TYPE_PTR_ARRAY, + GI_ARRAY_TYPE_BYTE_ARRAY +} GIArrayType; + +/** + * GIFieldInfoFlags: + * @GI_FIELD_IS_READABLE: field is readable. + * @GI_FIELD_IS_WRITABLE: field is writable. + * + * Flags for a #GIFieldInfo. + */ + +typedef enum +{ + GI_FIELD_IS_READABLE = 1 << 0, + GI_FIELD_IS_WRITABLE = 1 << 1 +} GIFieldInfoFlags; + +/** + * GIVFuncInfoFlags: + * @GI_VFUNC_MUST_CHAIN_UP: chains up to the parent type + * @GI_VFUNC_MUST_OVERRIDE: overrides + * @GI_VFUNC_MUST_NOT_OVERRIDE: does not override + * + * Flags of a #GIVFuncInfo struct. + */ +typedef enum +{ + GI_VFUNC_MUST_CHAIN_UP = 1 << 0, + GI_VFUNC_MUST_OVERRIDE = 1 << 1, + GI_VFUNC_MUST_NOT_OVERRIDE = 1 << 2 +} GIVFuncInfoFlags; + #endif /* __GITYPES_H__ */ From edcce0af88206703cf0533d981c569843b46f7ec Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 12:58:13 -0300 Subject: [PATCH 308/692] [girepository] Move GITypeInfo out of ginfo.ch --- Makefile.am | 2 + ginfo.c | 378 ---------------------------------------------- girepository.h | 24 +-- gitypeinfo.c | 403 +++++++++++++++++++++++++++++++++++++++++++++++++ gitypeinfo.h | 57 +++++++ 5 files changed, 463 insertions(+), 401 deletions(-) create mode 100644 gitypeinfo.c create mode 100644 gitypeinfo.h diff --git a/Makefile.am b/Makefile.am index 07d70d0ac..260d05da2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,6 +6,7 @@ girepo_HEADERS = \ gifunctioninfo.h \ girepository.h \ girffi.h \ + gitypeinfo.h \ gitypelib.h \ gitypes.h @@ -27,6 +28,7 @@ libgirepository_1_0_la_SOURCES = \ girffi.h \ girffi-private.h \ glib-compat.h \ + gitypeinfo.c \ gitypelib.c \ gitypelib-internal.h diff --git a/ginfo.c b/ginfo.c index 3b55b80a7..47cbd0086 100644 --- a/ginfo.c +++ b/ginfo.c @@ -29,384 +29,6 @@ #include "girepository-private.h" -/* GITypeInfo functions */ - -/** - * SECTION:gitypeinfo - * @Short_description: Struct representing a type - * @Title: GITypeInfo - * - * GITypeInfo represents a type. You can retrieve a type info from - * an argument (see #GIArgInfo), a functions return value (see #GIFunctionInfo), - * a field (see #GIFieldInfo), a property (see #GIPropertyInfo), a constant - * (see #GIConstantInfo) or for a union discriminator (see #GIUnionInfo). - * - * A type can either be a of a basic type which is a standard C primitive - * type or an interface type. For interface types you need to call - * g_type_info_get_interface() to get a reference to the base info for that - * interface. - * - */ - -/** - * g_type_info_is_pointer: - * @info: a #GITypeInfo - * - * Obtain if the type is passed as a reference. - * - * Returns: %TRUE if it is a pointer - */ -gboolean -g_type_info_is_pointer (GITypeInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type; - - g_return_val_if_fail (info != NULL, FALSE); - g_return_val_if_fail (GI_IS_TYPE_INFO (info), FALSE); - - type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (type->flags.reserved == 0 && type->flags.reserved2 == 0) - return type->flags.pointer; - else - { - InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - return iface->pointer; - } -} - -/** - * g_type_info_get_tag: - * @info: a #GITypeInfo - * - * Obtain the type tag for the type. See #GITypeTag for a list - * of type tags. - * - * Returns: the type tag - */ -GITypeTag -g_type_info_get_tag (GITypeInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type; - - g_return_val_if_fail (info != NULL, GI_TYPE_TAG_BOOLEAN); - g_return_val_if_fail (GI_IS_TYPE_INFO (info), GI_TYPE_TAG_BOOLEAN); - - type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (rinfo->type_is_embedded) - return GI_TYPE_TAG_INTERFACE; - else if (type->flags.reserved == 0 && type->flags.reserved2 == 0) - return type->flags.tag; - else - { - InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - return iface->tag; - } -} - -/** - * g_type_info_get_param_type: - * @info: a #GITypeInfo - * @n: index of the parameter - * - * Obtain the parameter type @n. - * - * Returns: the param type info - */ -GITypeInfo * -g_type_info_get_param_type (GITypeInfo *info, - gint n) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_TYPE_INFO (info), NULL); - - type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) - { - ParamTypeBlob *param = (ParamTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - 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 ((GIBaseInfo*)info, rinfo->typelib, - rinfo->offset + sizeof (ParamTypeBlob) - + sizeof (SimpleTypeBlob) * n); - break; - default: - break; - } - } - - return NULL; -} - -/** - * g_type_info_get_interface: - * @info: a #GITypeInfo - * - * For types which have #GI_TYPE_TAG_INTERFACE such as GObjects and boxed values, - * this function returns full information about the referenced type. You can then - * inspect the type of the returned #GIBaseInfo to further query whether it is - * a concrete GObject, a GInterface, a structure, etc. using g_base_info_get_type(). - * - * Returns: (transfer full): the #GIBaseInfo, or %NULL. Free it with - * g_base_info_unref() when done. - */ -GIBaseInfo * -g_type_info_get_interface (GITypeInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_TYPE_INFO (info), NULL); - - /* For embedded types, the given offset is a pointer to the actual blob, - * after the end of the field. In that case we know it's a "subclass" of - * CommonBlob, so use that to determine the info type. - */ - if (rinfo->type_is_embedded) - { - CommonBlob *common = (CommonBlob *)&rinfo->typelib->data[rinfo->offset]; - GIInfoType info_type; - - switch (common->blob_type) - { - case BLOB_TYPE_CALLBACK: - info_type = GI_INFO_TYPE_CALLBACK; - break; - default: - g_assert_not_reached (); - return NULL; - } - return (GIBaseInfo *) g_info_new (info_type, (GIBaseInfo*)info, rinfo->typelib, - rinfo->offset); - } - else - { - SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) - { - InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->tag == GI_TYPE_TAG_INTERFACE) - return _g_info_from_entry (rinfo->repository, rinfo->typelib, blob->interface); - } - } - - return NULL; -} - -/** - * g_type_info_get_array_length: - * @info: a #GITypeInfo - * - * Obtain the array length of the type. The type tag must be a - * #GI_TYPE_TAG_ARRAY or -1 will returned. - * - * Returns: the array length, or -1 if the type is not an array - */ -gint -g_type_info_get_array_length (GITypeInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type; - - g_return_val_if_fail (info != NULL, -1); - g_return_val_if_fail (GI_IS_TYPE_INFO (info), -1); - - type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) - { - ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->tag == GI_TYPE_TAG_ARRAY) - { - if (blob->has_length) - return blob->dimensions.length; - } - } - - return -1; -} - -/** - * g_type_info_get_array_fixed_size: - * @info: a #GITypeInfo - * - * Obtain the fixed array size of the type. The type tag must be a - * #GI_TYPE_TAG_ARRAY or -1 will returned. - * - * Returns: the size or -1 if it's not an array - */ -gint -g_type_info_get_array_fixed_size (GITypeInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type; - - g_return_val_if_fail (info != NULL, 0); - g_return_val_if_fail (GI_IS_TYPE_INFO (info), 0); - - type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) - { - ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->tag == GI_TYPE_TAG_ARRAY) - { - if (blob->has_size) - return blob->dimensions.size; - } - } - - return -1; -} - -/** - * g_type_info_is_zero_terminated: - * @info: a #GITypeInfo - * - * Obtain if the last element of the array is %NULL. The type tag must be a - * #GI_TYPE_TAG_ARRAY or %FALSE will returned. - * - * Returns: %TRUE if zero terminated - */ -gboolean -g_type_info_is_zero_terminated (GITypeInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type; - - g_return_val_if_fail (info != NULL, FALSE); - g_return_val_if_fail (GI_IS_TYPE_INFO (info), FALSE); - - type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) - { - ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->tag == GI_TYPE_TAG_ARRAY) - return blob->zero_terminated; - } - - return FALSE; -} - -/** - * g_type_info_get_array_type: - * @info: a #GITypeInfo - * - * Obtain the array type for this type. See #GIArrayType for a list of - * possible values. If the type tag of this type is not array, -1 will be - * returned. - * - * Returns: the array type or -1 - */ -GIArrayType -g_type_info_get_array_type (GITypeInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type; - - g_return_val_if_fail (info != NULL, -1); - g_return_val_if_fail (GI_IS_TYPE_INFO (info), -1); - - type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) - { - ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - g_return_val_if_fail (blob->tag == GI_TYPE_TAG_ARRAY, -1); - - return blob->array_type; - } - - return -1; -} - -/** - * g_type_info_get_n_error_domains: - * @info: a #GITypeInfo - * - * Obtain the number of error domains for this type. The type tag - * must be a #GI_TYPE_TAG_ERROR or -1 will be returned. - * - * Returns: number of error domains or -1 - */ -gint -g_type_info_get_n_error_domains (GITypeInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type; - - g_return_val_if_fail (info != NULL, 0); - g_return_val_if_fail (GI_IS_TYPE_INFO (info), 0); - - type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) - { - ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->tag == GI_TYPE_TAG_ERROR) - return blob->n_domains; - } - - return 0; -} - -/** - * g_type_info_get_error_domain: - * @info: a #GITypeInfo - * @n: index of error domain - * - * Obtain the error domains at index @n for this type. The type tag - * must be a #GI_TYPE_TAG_ERROR or -1 will be returned. - * - * Returns: (transfer full): the error domain or %NULL if type tag is wrong, - * free the struct with g_base_info_unref() when done. - */ -GIErrorDomainInfo * -g_type_info_get_error_domain (GITypeInfo *info, - gint n) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_TYPE_INFO (info), NULL); - - type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) - { - ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->tag == GI_TYPE_TAG_ERROR) - return (GIErrorDomainInfo *) _g_info_from_entry (rinfo->repository, - rinfo->typelib, - blob->domains[n]); - } - - return NULL; -} - - /* GIErrorDomainInfo functions */ /** diff --git a/girepository.h b/girepository.h index e0647197b..30a2fdea8 100644 --- a/girepository.h +++ b/girepository.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -147,29 +148,6 @@ void gi_cclosure_marshal_generic (GClosure *closure, gpointer invocation_hint, gpointer marshal_data); -/* GITypeInfo */ - -#define GI_IS_TYPE_INFO(info) \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_TYPE) - -#define G_TYPE_TAG_IS_BASIC(tag) (tag < GI_TYPE_TAG_ARRAY) - -const gchar* g_type_tag_to_string (GITypeTag type); - -gboolean g_type_info_is_pointer (GITypeInfo *info); -GITypeTag g_type_info_get_tag (GITypeInfo *info); -GITypeInfo * g_type_info_get_param_type (GITypeInfo *info, - gint n); -GIBaseInfo * g_type_info_get_interface (GITypeInfo *info); -gint g_type_info_get_array_length (GITypeInfo *info); -gint g_type_info_get_array_fixed_size(GITypeInfo *info); -gboolean g_type_info_is_zero_terminated (GITypeInfo *info); -GIArrayType g_type_info_get_array_type (GITypeInfo *info); - -gint g_type_info_get_n_error_domains (GITypeInfo *info); -GIErrorDomainInfo *g_type_info_get_error_domain (GITypeInfo *info, - gint n); - /* GIErrorDomainInfo */ #define GI_IS_ERROR_DOMAIN_INFO(info) \ diff --git a/gitypeinfo.c b/gitypeinfo.c new file mode 100644 index 000000000..68c3dc108 --- /dev/null +++ b/gitypeinfo.c @@ -0,0 +1,403 @@ +/* GObject introspection: Type implementation + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 "girepository-private.h" +#include "gitypelib-internal.h" + +/** + * SECTION:gitypeinfo + * @Short_description: Struct representing a type + * @Title: GITypeInfo + * + * GITypeInfo represents a type. You can retrieve a type info from + * an argument (see #GIArgInfo), a functions return value (see #GIFunctionInfo), + * a field (see #GIFieldInfo), a property (see #GIPropertyInfo), a constant + * (see #GIConstantInfo) or for a union discriminator (see #GIUnionInfo). + * + * A type can either be a of a basic type which is a standard C primitive + * type or an interface type. For interface types you need to call + * g_type_info_get_interface() to get a reference to the base info for that + * interface. + * + */ + +/** + * g_type_info_is_pointer: + * @info: a #GITypeInfo + * + * Obtain if the type is passed as a reference. + * + * Returns: %TRUE if it is a pointer + */ +gboolean +g_type_info_is_pointer (GITypeInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), FALSE); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (type->flags.reserved == 0 && type->flags.reserved2 == 0) + return type->flags.pointer; + else + { + InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + return iface->pointer; + } +} + +/** + * g_type_info_get_tag: + * @info: a #GITypeInfo + * + * Obtain the type tag for the type. See #GITypeTag for a list + * of type tags. + * + * Returns: the type tag + */ +GITypeTag +g_type_info_get_tag (GITypeInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, GI_TYPE_TAG_BOOLEAN); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), GI_TYPE_TAG_BOOLEAN); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (rinfo->type_is_embedded) + return GI_TYPE_TAG_INTERFACE; + else if (type->flags.reserved == 0 && type->flags.reserved2 == 0) + return type->flags.tag; + else + { + InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + return iface->tag; + } +} + +/** + * g_type_info_get_param_type: + * @info: a #GITypeInfo + * @n: index of the parameter + * + * Obtain the parameter type @n. + * + * Returns: the param type info + */ +GITypeInfo * +g_type_info_get_param_type (GITypeInfo *info, + gint n) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), NULL); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) + { + ParamTypeBlob *param = (ParamTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + 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 ((GIBaseInfo*)info, rinfo->typelib, + rinfo->offset + sizeof (ParamTypeBlob) + + sizeof (SimpleTypeBlob) * n); + break; + default: + break; + } + } + + return NULL; +} + +/** + * g_type_info_get_interface: + * @info: a #GITypeInfo + * + * For types which have #GI_TYPE_TAG_INTERFACE such as GObjects and boxed values, + * this function returns full information about the referenced type. You can then + * inspect the type of the returned #GIBaseInfo to further query whether it is + * a concrete GObject, a GInterface, a structure, etc. using g_base_info_get_type(). + * + * Returns: (transfer full): the #GIBaseInfo, or %NULL. Free it with + * g_base_info_unref() when done. + */ +GIBaseInfo * +g_type_info_get_interface (GITypeInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), NULL); + + /* For embedded types, the given offset is a pointer to the actual blob, + * after the end of the field. In that case we know it's a "subclass" of + * CommonBlob, so use that to determine the info type. + */ + if (rinfo->type_is_embedded) + { + CommonBlob *common = (CommonBlob *)&rinfo->typelib->data[rinfo->offset]; + GIInfoType info_type; + + switch (common->blob_type) + { + case BLOB_TYPE_CALLBACK: + info_type = GI_INFO_TYPE_CALLBACK; + break; + default: + g_assert_not_reached (); + return NULL; + } + return (GIBaseInfo *) g_info_new (info_type, (GIBaseInfo*)info, rinfo->typelib, + rinfo->offset); + } + else + { + SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) + { + InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->tag == GI_TYPE_TAG_INTERFACE) + return _g_info_from_entry (rinfo->repository, rinfo->typelib, blob->interface); + } + } + + return NULL; +} + +/** + * g_type_info_get_array_length: + * @info: a #GITypeInfo + * + * Obtain the array length of the type. The type tag must be a + * #GI_TYPE_TAG_ARRAY or -1 will returned. + * + * Returns: the array length, or -1 if the type is not an array + */ +gint +g_type_info_get_array_length (GITypeInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), -1); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) + { + ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->tag == GI_TYPE_TAG_ARRAY) + { + if (blob->has_length) + return blob->dimensions.length; + } + } + + return -1; +} + +/** + * g_type_info_get_array_fixed_size: + * @info: a #GITypeInfo + * + * Obtain the fixed array size of the type. The type tag must be a + * #GI_TYPE_TAG_ARRAY or -1 will returned. + * + * Returns: the size or -1 if it's not an array + */ +gint +g_type_info_get_array_fixed_size (GITypeInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), 0); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) + { + ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->tag == GI_TYPE_TAG_ARRAY) + { + if (blob->has_size) + return blob->dimensions.size; + } + } + + return -1; +} + +/** + * g_type_info_is_zero_terminated: + * @info: a #GITypeInfo + * + * Obtain if the last element of the array is %NULL. The type tag must be a + * #GI_TYPE_TAG_ARRAY or %FALSE will returned. + * + * Returns: %TRUE if zero terminated + */ +gboolean +g_type_info_is_zero_terminated (GITypeInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), FALSE); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) + { + ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->tag == GI_TYPE_TAG_ARRAY) + return blob->zero_terminated; + } + + return FALSE; +} + +/** + * g_type_info_get_array_type: + * @info: a #GITypeInfo + * + * Obtain the array type for this type. See #GIArrayType for a list of + * possible values. If the type tag of this type is not array, -1 will be + * returned. + * + * Returns: the array type or -1 + */ +GIArrayType +g_type_info_get_array_type (GITypeInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), -1); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) + { + ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + g_return_val_if_fail (blob->tag == GI_TYPE_TAG_ARRAY, -1); + + return blob->array_type; + } + + return -1; +} + +/** + * g_type_info_get_n_error_domains: + * @info: a #GITypeInfo + * + * Obtain the number of error domains for this type. The type tag + * must be a #GI_TYPE_TAG_ERROR or -1 will be returned. + * + * Returns: number of error domains or -1 + */ +gint +g_type_info_get_n_error_domains (GITypeInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), 0); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) + { + ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->tag == GI_TYPE_TAG_ERROR) + return blob->n_domains; + } + + return 0; +} + +/** + * g_type_info_get_error_domain: + * @info: a #GITypeInfo + * @n: index of error domain + * + * Obtain the error domains at index @n for this type. The type tag + * must be a #GI_TYPE_TAG_ERROR or -1 will be returned. + * + * Returns: (transfer full): the error domain or %NULL if type tag is wrong, + * free the struct with g_base_info_unref() when done. + */ +GIErrorDomainInfo * +g_type_info_get_error_domain (GITypeInfo *info, + gint n) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + SimpleTypeBlob *type; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_TYPE_INFO (info), NULL); + + type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) + { + ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->tag == GI_TYPE_TAG_ERROR) + return (GIErrorDomainInfo *) _g_info_from_entry (rinfo->repository, + rinfo->typelib, + blob->domains[n]); + } + + return NULL; +} + + diff --git a/gitypeinfo.h b/gitypeinfo.h new file mode 100644 index 000000000..4d33d31ec --- /dev/null +++ b/gitypeinfo.h @@ -0,0 +1,57 @@ +/* GObject introspection: Type + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GITYPEINFO_H__ +#define __GITYPEINFO_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define GI_IS_TYPE_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_TYPE) + +#define G_TYPE_TAG_IS_BASIC(tag) (tag < GI_TYPE_TAG_ARRAY) + +const gchar* g_type_tag_to_string (GITypeTag type); + +gboolean g_type_info_is_pointer (GITypeInfo *info); +GITypeTag g_type_info_get_tag (GITypeInfo *info); +GITypeInfo * g_type_info_get_param_type (GITypeInfo *info, + gint n); +GIBaseInfo * g_type_info_get_interface (GITypeInfo *info); +gint g_type_info_get_array_length (GITypeInfo *info); +gint g_type_info_get_array_fixed_size(GITypeInfo *info); +gboolean g_type_info_is_zero_terminated (GITypeInfo *info); +GIArrayType g_type_info_get_array_type (GITypeInfo *info); + +gint g_type_info_get_n_error_domains (GITypeInfo *info); +GIErrorDomainInfo *g_type_info_get_error_domain (GITypeInfo *info, + gint n); +G_END_DECLS + + +#endif /* __GITYPEINFO_H__ */ + From dab5e1ddaf60e5abaef4274507f1b03366c4166b Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 13:01:26 -0300 Subject: [PATCH 309/692] [girepository] Move GIErrorDomainInfo out of ginfo.ch --- Makefile.am | 4 ++- gierrordomaininfo.c | 87 +++++++++++++++++++++++++++++++++++++++++++++ gierrordomaininfo.h | 44 +++++++++++++++++++++++ ginfo.c | 62 -------------------------------- girepository.h | 10 +----- 5 files changed, 135 insertions(+), 72 deletions(-) create mode 100644 gierrordomaininfo.c create mode 100644 gierrordomaininfo.h diff --git a/Makefile.am b/Makefile.am index 260d05da2..db5e6d4d0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,6 +3,7 @@ girepo_HEADERS = \ giarginfo.h \ gibaseinfo.h \ gicallableinfo.h \ + gierrordomaininfo.h \ gifunctioninfo.h \ girepository.h \ girffi.h \ @@ -18,8 +19,9 @@ libgirepository_1_0_la_SOURCES = \ gfield.c \ giarginfo.c \ gibaseinfo.c \ - gifunctioninfo.c \ gicallableinfo.c \ + gierrordomaininfo.c \ + gifunctioninfo.c \ ginfo.c \ ginvoke.c \ girepository.c \ diff --git a/gierrordomaininfo.c b/gierrordomaininfo.c new file mode 100644 index 000000000..aa06719ff --- /dev/null +++ b/gierrordomaininfo.c @@ -0,0 +1,87 @@ +/* GObject introspection: ErrorDomain implementation + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 "girepository-private.h" +#include "gitypelib-internal.h" + +/** + * SECTION:gierrordomaininfo + * @Short_description: Struct representing an error domain + * @Title: GIErrorDomainInfo + * + * A GIErrorDomainInfo struct represents a domain of a #GError. + * An error domain is associated with a #GQuark and contains a pointer + * to an enum with all the error codes. + */ + +/** + * g_error_domain_info_get_quark: + * @info: a #GIErrorDomainInfo + * + * Obtain a string representing the quark for this error domain. + * %NULL will be returned if the type tag is wrong or if a quark is + * missing in the typelib. + * + * Returns: the quark represented as a string or %NULL + */ +const gchar * +g_error_domain_info_get_quark (GIErrorDomainInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ErrorDomainBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_ERROR_DOMAIN_INFO (info), NULL); + + blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset]; + + return g_typelib_get_string (rinfo->typelib, blob->get_quark); +} + +/** + * g_error_domain_info_get_codes: + * @info: a #GIErrorDomainInfo + * + * Obtain the enum containing all the error codes for this error domain. + * The return value will have a #GIInfoType of %GI_INFO_TYPE_ERROR_DOMAIN + * + * Returns: (transfer full): the error domain or %NULL if type tag is wrong, + * free the struct with g_base_info_unref() when done. + */ +GIInterfaceInfo * +g_error_domain_info_get_codes (GIErrorDomainInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ErrorDomainBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_ERROR_DOMAIN_INFO (info), NULL); + + blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset]; + + return (GIInterfaceInfo *) _g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->error_codes); +} + + diff --git a/gierrordomaininfo.h b/gierrordomaininfo.h new file mode 100644 index 000000000..9c2968bc1 --- /dev/null +++ b/gierrordomaininfo.h @@ -0,0 +1,44 @@ +/* GObject introspection: Error Domain + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GIERRORDOMAININFO_H__ +#define __GIERRORDOMAININFO_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define GI_IS_ERROR_DOMAIN_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ERROR_DOMAIN) + +const gchar * g_error_domain_info_get_quark (GIErrorDomainInfo *info); +GIInterfaceInfo * g_error_domain_info_get_codes (GIErrorDomainInfo *info); + + +G_END_DECLS + + +#endif /* __GIERRORDOMAININFO_H__ */ + diff --git a/ginfo.c b/ginfo.c index 47cbd0086..3859aab90 100644 --- a/ginfo.c +++ b/ginfo.c @@ -29,68 +29,6 @@ #include "girepository-private.h" -/* GIErrorDomainInfo functions */ - -/** - * SECTION:gierrordomaininfo - * @Short_description: Struct representing an error domain - * @Title: GIErrorDomainInfo - * - * A GIErrorDomainInfo struct represents a domain of a #GError. - * An error domain is associated with a #GQuark and contains a pointer - * to an enum with all the error codes. - */ - -/** - * g_error_domain_info_get_quark: - * @info: a #GIErrorDomainInfo - * - * Obtain a string representing the quark for this error domain. - * %NULL will be returned if the type tag is wrong or if a quark is - * missing in the typelib. - * - * Returns: the quark represented as a string or %NULL - */ -const gchar * -g_error_domain_info_get_quark (GIErrorDomainInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ErrorDomainBlob *blob; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_ERROR_DOMAIN_INFO (info), NULL); - - blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset]; - - return g_typelib_get_string (rinfo->typelib, blob->get_quark); -} - -/** - * g_error_domain_info_get_codes: - * @info: a #GIErrorDomainInfo - * - * Obtain the enum containing all the error codes for this error domain. - * The return value will have a #GIInfoType of %GI_INFO_TYPE_ERROR_DOMAIN - * - * Returns: (transfer full): the error domain or %NULL if type tag is wrong, - * free the struct with g_base_info_unref() when done. - */ -GIInterfaceInfo * -g_error_domain_info_get_codes (GIErrorDomainInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ErrorDomainBlob *blob; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_ERROR_DOMAIN_INFO (info), NULL); - - blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset]; - - return (GIInterfaceInfo *) _g_info_from_entry (rinfo->repository, - rinfo->typelib, blob->error_codes); -} - - /* GIEnumInfo and GIValueInfo functions */ /** diff --git a/girepository.h b/girepository.h index 30a2fdea8..89a66b999 100644 --- a/girepository.h +++ b/girepository.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -148,15 +149,6 @@ void gi_cclosure_marshal_generic (GClosure *closure, gpointer invocation_hint, gpointer marshal_data); -/* GIErrorDomainInfo */ - -#define GI_IS_ERROR_DOMAIN_INFO(info) \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ERROR_DOMAIN) - -const gchar * g_error_domain_info_get_quark (GIErrorDomainInfo *info); -GIInterfaceInfo * g_error_domain_info_get_codes (GIErrorDomainInfo *info); - - /* GIValueInfo */ #define GI_IS_VALUE_INFO(info) \ From bbc69cefaa2a68dd8ebb7f8e04a6e847fd5dabc3 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 13:06:30 -0300 Subject: [PATCH 310/692] [girepository] Move GIEnumInfo out of ginfo.ch --- Makefile.am | 2 + gienuminfo.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++ gienuminfo.h | 51 +++++++++++++++++++ ginfo.c | 112 ---------------------------------------- girepository.h | 19 +------ 5 files changed, 190 insertions(+), 130 deletions(-) create mode 100644 gienuminfo.c create mode 100644 gienuminfo.h diff --git a/Makefile.am b/Makefile.am index db5e6d4d0..836f28a00 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,6 +3,7 @@ girepo_HEADERS = \ giarginfo.h \ gibaseinfo.h \ gicallableinfo.h \ + gienuminfo.h \ gierrordomaininfo.h \ gifunctioninfo.h \ girepository.h \ @@ -20,6 +21,7 @@ libgirepository_1_0_la_SOURCES = \ giarginfo.c \ gibaseinfo.c \ gicallableinfo.c \ + gienuminfo.c \ gierrordomaininfo.c \ gifunctioninfo.c \ ginfo.c \ diff --git a/gienuminfo.c b/gienuminfo.c new file mode 100644 index 000000000..ac8f09249 --- /dev/null +++ b/gienuminfo.c @@ -0,0 +1,136 @@ +/* GObject introspection: Enum implementation + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 "girepository-private.h" +#include "gitypelib-internal.h" + +/** + * SECTION:gienuminfo + * @Short_description: Structs representing an enumeration and its values + * @Title: GIEnumInfo + * + * A GIEnumInfo represents an enumeration and a GIValueInfo struct represents a value + * of an enumeration. The GIEnumInfo contains a set of values and a type + * The GIValueInfo is fetched by calling g_enum_info_get_value() on a #GIEnumInfo. + */ + +/** +* g_enum_info_get_n_values: +* @info: a #GIEnumInfo +* +* Obtain the number of values this enumeration contains. +* +* Returns: the number of enumeration values +*/ +gint +g_enum_info_get_n_values (GIEnumInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + EnumBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_ENUM_INFO (info), 0); + + blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_values; +} + +/** + * g_enum_info_get_value: + * @info: a #GIEnumInfo + * @n: index of value to fetch + * + * Obtain a value for this enumeration. + * + * Returns: (transfer full): the enumeration value or %NULL if type tag is wrong, + * free the struct with g_base_info_unref() when done. + */ +GIValueInfo * +g_enum_info_get_value (GIEnumInfo *info, + gint n) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header; + gint offset; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_ENUM_INFO (info), NULL); + + header = (Header *)rinfo->typelib->data; + offset = rinfo->offset + header->enum_blob_size + + n * header->value_blob_size; + + return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, (GIBaseInfo*)info, rinfo->typelib, offset); +} + +/** + * g_enum_info_get_storage_type: + * @info: a #GIEnumInfo + * + * Obtain the tag of the type used for the enum in the C ABI. This will + * will be a signed or unsigned integral type. + + * Note that in the current implementation the width of the type is + * computed correctly, but the signed or unsigned nature of the type + * may not match the sign of the type used by the C compiler. + * + * Return Value: the storage type for the enumeration + */ +GITypeTag +g_enum_info_get_storage_type (GIEnumInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + EnumBlob *blob; + + g_return_val_if_fail (info != NULL, GI_TYPE_TAG_BOOLEAN); + g_return_val_if_fail (GI_IS_ENUM_INFO (info), GI_TYPE_TAG_BOOLEAN); + + blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->storage_type; +} + +/** + * g_value_info_get_value: + * @info: a #GIValueInfo + * + * Obtain the enumeration value of the #GIValueInfo. + * + * Returns: the enumeration value + */ +glong +g_value_info_get_value (GIValueInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ValueBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_VALUE_INFO (info), -1); + + blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset]; + + return (glong)blob->value; +} + diff --git a/gienuminfo.h b/gienuminfo.h new file mode 100644 index 000000000..211ea6efb --- /dev/null +++ b/gienuminfo.h @@ -0,0 +1,51 @@ +/* GObject introspection: Enum and Enum values + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GIENUMINFO_H__ +#define __GIENUMINFO_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define GI_IS_ENUM_INFO(info) \ + ((g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ENUM) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FLAGS)) + +#define GI_IS_VALUE_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_VALUE) + +gint g_enum_info_get_n_values (GIEnumInfo *info); +GIValueInfo * g_enum_info_get_value (GIEnumInfo *info, + gint n); +GITypeTag g_enum_info_get_storage_type (GIEnumInfo *info); + +glong g_value_info_get_value (GIValueInfo *info); + +G_END_DECLS + + +#endif /* __GIENUMINFO_H__ */ + diff --git a/ginfo.c b/ginfo.c index 3859aab90..5c5d0e4c4 100644 --- a/ginfo.c +++ b/ginfo.c @@ -28,118 +28,6 @@ #include "gitypelib-internal.h" #include "girepository-private.h" - -/* GIEnumInfo and GIValueInfo functions */ - -/** - * SECTION:gienuminfo - * @Short_description: Structs representing an enumeration and its values - * @Title: GIEnumInfo - * - * A GIEnumInfo represents an enumeration and a GIValueInfo struct represents a value - * of an enumeration. The GIEnumInfo contains a set of values and a type - * The GIValueInfo is fetched by calling g_enum_info_get_value() on a #GIEnumInfo. - */ - -/** -* g_enum_info_get_n_values: -* @info: a #GIEnumInfo -* -* Obtain the number of values this enumeration contains. -* -* Returns: the number of enumeration values -*/ -gint -g_enum_info_get_n_values (GIEnumInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - EnumBlob *blob; - - g_return_val_if_fail (info != NULL, 0); - g_return_val_if_fail (GI_IS_ENUM_INFO (info), 0); - - blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_values; -} - -/** - * g_enum_info_get_value: - * @info: a #GIEnumInfo - * @n: index of value to fetch - * - * Obtain a value for this enumeration. - * - * Returns: (transfer full): the enumeration value or %NULL if type tag is wrong, - * free the struct with g_base_info_unref() when done. - */ -GIValueInfo * -g_enum_info_get_value (GIEnumInfo *info, - gint n) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header; - gint offset; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_ENUM_INFO (info), NULL); - - header = (Header *)rinfo->typelib->data; - offset = rinfo->offset + header->enum_blob_size - + n * header->value_blob_size; - - return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, (GIBaseInfo*)info, rinfo->typelib, offset); -} - -/** - * g_enum_info_get_storage_type: - * @info: a #GIEnumInfo - * - * Obtain the tag of the type used for the enum in the C ABI. This will - * will be a signed or unsigned integral type. - - * Note that in the current implementation the width of the type is - * computed correctly, but the signed or unsigned nature of the type - * may not match the sign of the type used by the C compiler. - * - * Return Value: the storage type for the enumeration - */ -GITypeTag -g_enum_info_get_storage_type (GIEnumInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - EnumBlob *blob; - - g_return_val_if_fail (info != NULL, GI_TYPE_TAG_BOOLEAN); - g_return_val_if_fail (GI_IS_ENUM_INFO (info), GI_TYPE_TAG_BOOLEAN); - - blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->storage_type; -} - -/** - * g_value_info_get_value: - * @info: a #GIValueInfo - * - * Obtain the enumeration value of the #GIValueInfo. - * - * Returns: the enumeration value - */ -glong -g_value_info_get_value (GIValueInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ValueBlob *blob; - - g_return_val_if_fail (info != NULL, -1); - g_return_val_if_fail (GI_IS_VALUE_INFO (info), -1); - - blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset]; - - return (glong)blob->value; -} - /* GIFieldInfo functions */ /** diff --git a/girepository.h b/girepository.h index 89a66b999..c9ebca6d9 100644 --- a/girepository.h +++ b/girepository.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -149,13 +150,6 @@ void gi_cclosure_marshal_generic (GClosure *closure, gpointer invocation_hint, gpointer marshal_data); -/* GIValueInfo */ - -#define GI_IS_VALUE_INFO(info) \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_VALUE) - -glong g_value_info_get_value (GIValueInfo *info); - /* GIFieldInfo */ @@ -227,17 +221,6 @@ const gchar * g_registered_type_info_get_type_name (GIRegisteredTypeInf const gchar * g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info); GType g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info); -/* GIEnumInfo */ - -#define GI_IS_ENUM_INFO(info) \ - ((g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ENUM) || \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FLAGS)) - -gint g_enum_info_get_n_values (GIEnumInfo *info); -GIValueInfo * g_enum_info_get_value (GIEnumInfo *info, - gint n); -GITypeTag g_enum_info_get_storage_type (GIEnumInfo *info); - /* GIObjectInfo */ #define GI_IS_OBJECT_INFO(info) \ From 8d2ae7fa902b25267f1fc50a4f2a3904136e4960 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 13:11:23 -0300 Subject: [PATCH 311/692] [girepository] Move GIFieldInfo out of ginfo.ch --- Makefile.am | 2 ++ gifieldinfo.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++ gifieldinfo.h | 52 +++++++++++++++++++++++++++ ginfo.c | 73 ------------------------------------- girepository.h | 19 +--------- 5 files changed, 153 insertions(+), 91 deletions(-) create mode 100644 gifieldinfo.c create mode 100644 gifieldinfo.h diff --git a/Makefile.am b/Makefile.am index 836f28a00..24457c9d3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,6 +5,7 @@ girepo_HEADERS = \ gicallableinfo.h \ gienuminfo.h \ gierrordomaininfo.h \ + gifieldinfo.h \ gifunctioninfo.h \ girepository.h \ girffi.h \ @@ -23,6 +24,7 @@ libgirepository_1_0_la_SOURCES = \ gicallableinfo.c \ gienuminfo.c \ gierrordomaininfo.c \ + gifieldinfo.c \ gifunctioninfo.c \ ginfo.c \ ginvoke.c \ diff --git a/gifieldinfo.c b/gifieldinfo.c new file mode 100644 index 000000000..a04124a06 --- /dev/null +++ b/gifieldinfo.c @@ -0,0 +1,98 @@ +/* GObject introspection: Field implementation + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 "girepository-private.h" +#include "gitypelib-internal.h" + +/** + * SECTION:gifieldinfo + * @Short_description: Struct representing a struct or union field + * @Title: GIFieldInfo + * + * A GIFieldInfo struct represents a field of a struct (see #GIStructInfo), + * union (see #GIUnionInfo) or an object (see #GIObjectInfo). The GIFieldInfo + * is fetched by calling g_struct_info_get_field(), g_union_info_get_field() + * or g_object_info_get_value(). + * A field has a size, type and a struct offset asssociated and a set of flags, + * which is currently #GI_FIELD_IS_READABLE or #GI_FIELD_IS_WRITABLE. + */ + +GIFieldInfoFlags +g_field_info_get_flags (GIFieldInfo *info) +{ + GIFieldInfoFlags flags; + + GIRealInfo *rinfo = (GIRealInfo *)info; + FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; + + flags = 0; + + if (blob->readable) + flags = flags | GI_FIELD_IS_READABLE; + + if (blob->writable) + flags = flags | GI_FIELD_IS_WRITABLE; + + return flags; +} + +gint +g_field_info_get_size (GIFieldInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->bits; +} + +gint +g_field_info_get_offset (GIFieldInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->struct_offset; +} + +GITypeInfo * +g_field_info_get_type (GIFieldInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; + GIRealInfo *type_info; + + if (blob->has_embedded_type) + { + type_info = (GIRealInfo *) g_info_new (GI_INFO_TYPE_TYPE, + (GIBaseInfo*)info, rinfo->typelib, + rinfo->offset + header->field_blob_size); + type_info->type_is_embedded = TRUE; + } + else + return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (FieldBlob, type)); + + return (GIBaseInfo*)type_info; +} + diff --git a/gifieldinfo.h b/gifieldinfo.h new file mode 100644 index 000000000..5d5970be4 --- /dev/null +++ b/gifieldinfo.h @@ -0,0 +1,52 @@ +/* GObject introspection: Field and Field values + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GIFIELDINFO_H__ +#define __GIFIELDINFO_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define GI_IS_FIELD_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FIELD) + +GIFieldInfoFlags g_field_info_get_flags (GIFieldInfo *info); +gint g_field_info_get_size (GIFieldInfo *info); +gint g_field_info_get_offset (GIFieldInfo *info); +GITypeInfo * g_field_info_get_type (GIFieldInfo *info); + +gboolean g_field_info_get_field (GIFieldInfo *field_info, + gpointer mem, + GArgument *value); +gboolean g_field_info_set_field (GIFieldInfo *field_info, + gpointer mem, + const GArgument *value); + +G_END_DECLS + + +#endif /* __GIFIELDINFO_H__ */ + diff --git a/ginfo.c b/ginfo.c index 5c5d0e4c4..825ad5d65 100644 --- a/ginfo.c +++ b/ginfo.c @@ -28,79 +28,6 @@ #include "gitypelib-internal.h" #include "girepository-private.h" -/* GIFieldInfo functions */ - -/** - * SECTION:gifieldinfo - * @Short_description: Struct representing a struct or union field - * @Title: GIFieldInfo - * - * A GIFieldInfo struct represents a field of a struct (see #GIStructInfo), - * union (see #GIUnionInfo) or an object (see #GIObjectInfo). The GIFieldInfo - * is fetched by calling g_struct_info_get_field(), g_union_info_get_field() - * or g_object_info_get_value(). - * A field has a size, type and a struct offset asssociated and a set of flags, - * which is currently #GI_FIELD_IS_READABLE or #GI_FIELD_IS_WRITABLE. - */ - -GIFieldInfoFlags -g_field_info_get_flags (GIFieldInfo *info) -{ - GIFieldInfoFlags flags; - - GIRealInfo *rinfo = (GIRealInfo *)info; - FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; - - flags = 0; - - if (blob->readable) - flags = flags | GI_FIELD_IS_READABLE; - - if (blob->writable) - flags = flags | GI_FIELD_IS_WRITABLE; - - return flags; -} - -gint -g_field_info_get_size (GIFieldInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->bits; -} - -gint -g_field_info_get_offset (GIFieldInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->struct_offset; -} - -GITypeInfo * -g_field_info_get_type (GIFieldInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; - GIRealInfo *type_info; - - if (blob->has_embedded_type) - { - type_info = (GIRealInfo *) g_info_new (GI_INFO_TYPE_TYPE, - (GIBaseInfo*)info, rinfo->typelib, - rinfo->offset + header->field_blob_size); - type_info->type_is_embedded = TRUE; - } - else - return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (FieldBlob, type)); - - return (GIBaseInfo*)type_info; -} - /* GIRegisteredTypeInfo functions */ const gchar * g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info) diff --git a/girepository.h b/girepository.h index c9ebca6d9..d03845937 100644 --- a/girepository.h +++ b/girepository.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -150,24 +151,6 @@ void gi_cclosure_marshal_generic (GClosure *closure, gpointer invocation_hint, gpointer marshal_data); - -/* GIFieldInfo */ - -#define GI_IS_FIELD_INFO(info) \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FIELD) - -GIFieldInfoFlags g_field_info_get_flags (GIFieldInfo *info); -gint g_field_info_get_size (GIFieldInfo *info); -gint g_field_info_get_offset (GIFieldInfo *info); -GITypeInfo * g_field_info_get_type (GIFieldInfo *info); - -gboolean g_field_info_get_field (GIFieldInfo *field_info, - gpointer mem, - GArgument *value); -gboolean g_field_info_set_field (GIFieldInfo *field_info, - gpointer mem, - const GArgument *value); - /* GIUnionInfo */ #define GI_IS_UNION_INFO(info) \ From e6733fd92e244685ac677ba4c52d90a44121b273 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 13:15:14 -0300 Subject: [PATCH 312/692] [gfield] Move over field set/get impl. Move over the GIFieldInfo set/get value implementation over to gifieldinfo.c --- Makefile.am | 1 - gfield.c | 416 -------------------------------------------------- gifieldinfo.c | 411 +++++++++++++++++++++++++++++++++++++++++++++++++ gifieldinfo.h | 13 +- 4 files changed, 417 insertions(+), 424 deletions(-) delete mode 100644 gfield.c diff --git a/Makefile.am b/Makefile.am index 24457c9d3..8fccc93ba 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,7 +18,6 @@ noinst_LTLIBRARIES = libgirepository-parser.la libgirepository_1_0_la_SOURCES = \ gdump.c \ - gfield.c \ giarginfo.c \ gibaseinfo.c \ gicallableinfo.c \ diff --git a/gfield.c b/gfield.c deleted file mode 100644 index 486211fa9..000000000 --- a/gfield.c +++ /dev/null @@ -1,416 +0,0 @@ -#include - -#include "girepository.h" -#include "girffi.h" -#include "config.h" - -/** - * g_field_info_get_field: - * @field_info: a #GIFieldInfo - * @mem: pointer to a block of memory representing a C structure or union - * @value: a #GArgument into which to store the value retrieved - * - * Reads a field identified by a #GFieldInfo from a C structure or - * union. This only handles fields of simple C types. It will fail - * for a field of a composite type like a nested structure or union - * even if that is actually readable. - * - * Returns: %TRUE if reading the field succeeded, otherwise %FALSE - */ -gboolean -g_field_info_get_field (GIFieldInfo *field_info, - gpointer mem, - GArgument *value) -{ - int offset; - GITypeInfo *type_info; - gboolean result = FALSE; - - if ((g_field_info_get_flags (field_info) & GI_FIELD_IS_READABLE) == 0) - return FALSE; - - offset = g_field_info_get_offset (field_info); - type_info = g_field_info_get_type (field_info); - - if (g_type_info_is_pointer (type_info)) - { - value->v_pointer = G_STRUCT_MEMBER(gpointer, mem, offset); - result = TRUE; - } - else - { - switch (g_type_info_get_tag (type_info)) - { - case GI_TYPE_TAG_VOID: - g_warning("Field %s: should not be have void type", - g_base_info_get_name ((GIBaseInfo *)field_info)); - break; - case GI_TYPE_TAG_BOOLEAN: - value->v_boolean = G_STRUCT_MEMBER(gboolean, mem, offset) != FALSE; - result = TRUE; - break; - case GI_TYPE_TAG_INT8: - case GI_TYPE_TAG_UINT8: - value->v_uint8 = G_STRUCT_MEMBER(guint8, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_INT16: - case GI_TYPE_TAG_UINT16: - case GI_TYPE_TAG_SHORT: - case GI_TYPE_TAG_USHORT: - value->v_uint16 = G_STRUCT_MEMBER(guint16, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_INT32: - case GI_TYPE_TAG_UINT32: - case GI_TYPE_TAG_INT: - case GI_TYPE_TAG_UINT: - value->v_uint32 = G_STRUCT_MEMBER(guint32, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_INT64: - case GI_TYPE_TAG_UINT64: - value->v_uint64 = G_STRUCT_MEMBER(guint64, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_LONG: - case GI_TYPE_TAG_ULONG: - value->v_ulong = G_STRUCT_MEMBER(gulong, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_SSIZE: - case GI_TYPE_TAG_SIZE: - case GI_TYPE_TAG_GTYPE: - value->v_size = G_STRUCT_MEMBER(gsize, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_FLOAT: - value->v_float = G_STRUCT_MEMBER(gfloat, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_DOUBLE: - value->v_double = G_STRUCT_MEMBER(gdouble, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_TIME_T: -#if SIZEOF_TIME_T == 4 - value->v_int32 = G_STRUCT_MEMBER(time_t, mem, offset); -#elif SIZEOF_TIME_T == 8 - value->v_int64 = G_STRUCT_MEMBER(time_t, mem, offset); -#else -# error "Unexpected size for time_t: not 4 or 8" -#endif - result = TRUE; - break; - case GI_TYPE_TAG_UTF8: - case GI_TYPE_TAG_FILENAME: - case GI_TYPE_TAG_ARRAY: - case GI_TYPE_TAG_GLIST: - case GI_TYPE_TAG_GSLIST: - case GI_TYPE_TAG_GHASH: - g_warning("Field %s: type %s should have is_pointer set", - g_base_info_get_name ((GIBaseInfo *)field_info), - g_type_tag_to_string (g_type_info_get_tag (type_info))); - break; - case GI_TYPE_TAG_ERROR: - /* Needs to be handled by the language binding directly */ - break; - case GI_TYPE_TAG_INTERFACE: - { - GIBaseInfo *interface = g_type_info_get_interface (type_info); - switch (g_base_info_get_type (interface)) - { - case GI_INFO_TYPE_STRUCT: - case GI_INFO_TYPE_UNION: - case GI_INFO_TYPE_BOXED: - /* Needs to be handled by the language binding directly */ - break; - case GI_INFO_TYPE_OBJECT: - break; - case GI_INFO_TYPE_ENUM: - case GI_INFO_TYPE_FLAGS: - { - /* FIXME: there's a mismatch here between the value->v_int we use - * here and the glong result returned from g_value_info_get_value(). - * But to switch this to glong, we'd have to make g_function_info_invoke() - * translate value->v_long to the proper ABI for an enum function - * call parameter, which will usually be int, and then fix up language - * bindings. - */ - GITypeTag storage_type = g_enum_info_get_storage_type ((GIEnumInfo *)interface); - switch (storage_type) - { - case GI_TYPE_TAG_INT8: - case GI_TYPE_TAG_UINT8: - value->v_int = (gint)G_STRUCT_MEMBER(guint8, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_INT16: - case GI_TYPE_TAG_UINT16: - case GI_TYPE_TAG_SHORT: - case GI_TYPE_TAG_USHORT: - value->v_int = (gint)G_STRUCT_MEMBER(guint16, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_INT32: - case GI_TYPE_TAG_UINT32: - case GI_TYPE_TAG_INT: - case GI_TYPE_TAG_UINT: - value->v_int = (gint)G_STRUCT_MEMBER(guint32, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_INT64: - case GI_TYPE_TAG_UINT64: - value->v_int = (gint)G_STRUCT_MEMBER(guint64, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_LONG: - case GI_TYPE_TAG_ULONG: - value->v_int = (gint)G_STRUCT_MEMBER(gulong, mem, offset); - result = TRUE; - break; - default: - g_warning("Field %s: Unexpected enum storage type %s", - g_base_info_get_name ((GIBaseInfo *)field_info), - g_type_tag_to_string (storage_type)); - break; - } - break; - } - case GI_INFO_TYPE_VFUNC: - case GI_INFO_TYPE_CALLBACK: - g_warning("Field %s: Interface type %d should have is_pointer set", - g_base_info_get_name ((GIBaseInfo *)field_info), - g_base_info_get_type (interface)); - break; - case GI_INFO_TYPE_INVALID: - case GI_INFO_TYPE_INTERFACE: - case GI_INFO_TYPE_FUNCTION: - case GI_INFO_TYPE_CONSTANT: - case GI_INFO_TYPE_ERROR_DOMAIN: - case GI_INFO_TYPE_VALUE: - case GI_INFO_TYPE_SIGNAL: - case GI_INFO_TYPE_PROPERTY: - case GI_INFO_TYPE_FIELD: - case GI_INFO_TYPE_ARG: - case GI_INFO_TYPE_TYPE: - case GI_INFO_TYPE_UNRESOLVED: - g_warning("Field %s: Interface type %d not expected", - g_base_info_get_name ((GIBaseInfo *)field_info), - g_base_info_get_type (interface)); - break; - } - - g_base_info_unref ((GIBaseInfo *)interface); - break; - } - break; - } - } - - g_base_info_unref ((GIBaseInfo *)type_info); - - return result; -} - -/** - * g_field_info_set_field: - * @field_info: a #GIFieldInfo - * @mem: pointer to a block of memory representing a C structure or union - * @value: a #GArgument holding the value to store - * - * Writes a field identified by a #GFieldInfo to a C structure or - * union. This only handles fields of simple C types. It will fail - * for a field of a composite type like a nested structure or union - * even if that is actually writable. Note also that that it will refuse - * to write fields where memory management would by required. A field - * with a type such as 'char *' must be set with a setter function. - * - * Returns: %TRUE if writing the field succeeded, otherwise %FALSE - */ -gboolean -g_field_info_set_field (GIFieldInfo *field_info, - gpointer mem, - const GArgument *value) -{ - int offset; - GITypeInfo *type_info; - gboolean result = FALSE; - - if ((g_field_info_get_flags (field_info) & GI_FIELD_IS_WRITABLE) == 0) - return FALSE; - - offset = g_field_info_get_offset (field_info); - type_info = g_field_info_get_type (field_info); - - if (!g_type_info_is_pointer (type_info)) - { - switch (g_type_info_get_tag (type_info)) - { - case GI_TYPE_TAG_VOID: - g_warning("Field %s: should not be have void type", - g_base_info_get_name ((GIBaseInfo *)field_info)); - break; - case GI_TYPE_TAG_BOOLEAN: - G_STRUCT_MEMBER(gboolean, mem, offset) = value->v_boolean != FALSE; - result = TRUE; - break; - case GI_TYPE_TAG_INT8: - case GI_TYPE_TAG_UINT8: - G_STRUCT_MEMBER(guint8, mem, offset) = value->v_uint8; - result = TRUE; - break; - case GI_TYPE_TAG_INT16: - case GI_TYPE_TAG_UINT16: - case GI_TYPE_TAG_SHORT: - case GI_TYPE_TAG_USHORT: - G_STRUCT_MEMBER(guint16, mem, offset) = value->v_uint16; - result = TRUE; - break; - case GI_TYPE_TAG_INT32: - case GI_TYPE_TAG_UINT32: - case GI_TYPE_TAG_INT: - case GI_TYPE_TAG_UINT: - G_STRUCT_MEMBER(guint32, mem, offset) = value->v_uint32; - result = TRUE; - break; - case GI_TYPE_TAG_INT64: - case GI_TYPE_TAG_UINT64: - G_STRUCT_MEMBER(guint64, mem, offset) = value->v_uint64; - result = TRUE; - break; - case GI_TYPE_TAG_LONG: - case GI_TYPE_TAG_ULONG: - G_STRUCT_MEMBER(gulong, mem, offset)= value->v_ulong; - result = TRUE; - break; - case GI_TYPE_TAG_SSIZE: - case GI_TYPE_TAG_SIZE: - case GI_TYPE_TAG_GTYPE: - G_STRUCT_MEMBER(gsize, mem, offset) = value->v_size; - result = TRUE; - break; - case GI_TYPE_TAG_FLOAT: - G_STRUCT_MEMBER(gfloat, mem, offset) = value->v_float; - result = TRUE; - break; - case GI_TYPE_TAG_DOUBLE: - G_STRUCT_MEMBER(gdouble, mem, offset)= value->v_double; - result = TRUE; - break; - case GI_TYPE_TAG_TIME_T: -#if SIZEOF_TIME_T == 4 - G_STRUCT_MEMBER(time_t, mem, offset) = value->v_int32; -#elif SIZEOF_TIME_T == 8 - G_STRUCT_MEMBER(time_t, mem, offset) = value->v_int64; -#else -# error "Unexpected size for time_t: not 4 or 8" -#endif - result = TRUE; - break; - case GI_TYPE_TAG_UTF8: - case GI_TYPE_TAG_FILENAME: - case GI_TYPE_TAG_ARRAY: - case GI_TYPE_TAG_GLIST: - case GI_TYPE_TAG_GSLIST: - case GI_TYPE_TAG_GHASH: - g_warning("Field %s: type %s should have is_pointer set", - g_base_info_get_name ((GIBaseInfo *)field_info), - g_type_tag_to_string (g_type_info_get_tag (type_info))); - break; - case GI_TYPE_TAG_ERROR: - /* Needs to be handled by the language binding directly */ - break; - case GI_TYPE_TAG_INTERFACE: - { - GIBaseInfo *interface = g_type_info_get_interface (type_info); - switch (g_base_info_get_type (interface)) - { - case GI_INFO_TYPE_STRUCT: - case GI_INFO_TYPE_UNION: - case GI_INFO_TYPE_BOXED: - /* Needs to be handled by the language binding directly */ - break; - case GI_INFO_TYPE_OBJECT: - break; - case GI_INFO_TYPE_ENUM: - case GI_INFO_TYPE_FLAGS: - { - /* See FIXME above - */ - GITypeTag storage_type = g_enum_info_get_storage_type ((GIEnumInfo *)interface); - switch (storage_type) - { - case GI_TYPE_TAG_INT8: - case GI_TYPE_TAG_UINT8: - G_STRUCT_MEMBER(guint8, mem, offset) = (guint8)value->v_int; - result = TRUE; - break; - case GI_TYPE_TAG_INT16: - case GI_TYPE_TAG_UINT16: - case GI_TYPE_TAG_SHORT: - case GI_TYPE_TAG_USHORT: - G_STRUCT_MEMBER(guint16, mem, offset) = (guint16)value->v_int; - result = TRUE; - break; - case GI_TYPE_TAG_INT32: - case GI_TYPE_TAG_UINT32: - case GI_TYPE_TAG_INT: - case GI_TYPE_TAG_UINT: - G_STRUCT_MEMBER(guint32, mem, offset) = (guint32)value->v_int; - result = TRUE; - break; - case GI_TYPE_TAG_INT64: - case GI_TYPE_TAG_UINT64: - G_STRUCT_MEMBER(guint64, mem, offset) = (guint64)value->v_int; - result = TRUE; - break; - case GI_TYPE_TAG_LONG: - case GI_TYPE_TAG_ULONG: - G_STRUCT_MEMBER(gulong, mem, offset) = (gulong)value->v_int; - result = TRUE; - break; - default: - g_warning("Field %s: Unexpected enum storage type %s", - g_base_info_get_name ((GIBaseInfo *)field_info), - g_type_tag_to_string (storage_type)); - break; - } - break; - } - break; - case GI_INFO_TYPE_VFUNC: - case GI_INFO_TYPE_CALLBACK: - g_warning("Field%s: Interface type %d should have is_pointer set", - g_base_info_get_name ((GIBaseInfo *)field_info), - g_base_info_get_type (interface)); - break; - case GI_INFO_TYPE_INVALID: - case GI_INFO_TYPE_INTERFACE: - case GI_INFO_TYPE_FUNCTION: - case GI_INFO_TYPE_CONSTANT: - case GI_INFO_TYPE_ERROR_DOMAIN: - case GI_INFO_TYPE_VALUE: - case GI_INFO_TYPE_SIGNAL: - case GI_INFO_TYPE_PROPERTY: - case GI_INFO_TYPE_FIELD: - case GI_INFO_TYPE_ARG: - case GI_INFO_TYPE_TYPE: - case GI_INFO_TYPE_UNRESOLVED: - g_warning("Field %s: Interface type %d not expected", - g_base_info_get_name ((GIBaseInfo *)field_info), - g_base_info_get_type (interface)); - break; - } - - g_base_info_unref ((GIBaseInfo *)interface); - break; - } - break; - } - } - - g_base_info_unref ((GIBaseInfo *)type_info); - - return result; -} diff --git a/gifieldinfo.c b/gifieldinfo.c index a04124a06..d6f2da98e 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -24,6 +24,7 @@ #include #include "girepository-private.h" #include "gitypelib-internal.h" +#include "config.h" /** * SECTION:gifieldinfo @@ -96,3 +97,413 @@ g_field_info_get_type (GIFieldInfo *info) return (GIBaseInfo*)type_info; } +/** + * g_field_info_get_field: + * @field_info: a #GIFieldInfo + * @mem: pointer to a block of memory representing a C structure or union + * @value: a #GArgument into which to store the value retrieved + * + * Reads a field identified by a #GFieldInfo from a C structure or + * union. This only handles fields of simple C types. It will fail + * for a field of a composite type like a nested structure or union + * even if that is actually readable. + * + * Returns: %TRUE if reading the field succeeded, otherwise %FALSE + */ +gboolean +g_field_info_get_field (GIFieldInfo *field_info, + gpointer mem, + GArgument *value) +{ + int offset; + GITypeInfo *type_info; + gboolean result = FALSE; + + if ((g_field_info_get_flags (field_info) & GI_FIELD_IS_READABLE) == 0) + return FALSE; + + offset = g_field_info_get_offset (field_info); + type_info = g_field_info_get_type (field_info); + + if (g_type_info_is_pointer (type_info)) + { + value->v_pointer = G_STRUCT_MEMBER(gpointer, mem, offset); + result = TRUE; + } + else + { + switch (g_type_info_get_tag (type_info)) + { + case GI_TYPE_TAG_VOID: + g_warning("Field %s: should not be have void type", + g_base_info_get_name ((GIBaseInfo *)field_info)); + break; + case GI_TYPE_TAG_BOOLEAN: + value->v_boolean = G_STRUCT_MEMBER(gboolean, mem, offset) != FALSE; + result = TRUE; + break; + case GI_TYPE_TAG_INT8: + case GI_TYPE_TAG_UINT8: + value->v_uint8 = G_STRUCT_MEMBER(guint8, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT16: + case GI_TYPE_TAG_UINT16: + case GI_TYPE_TAG_SHORT: + case GI_TYPE_TAG_USHORT: + value->v_uint16 = G_STRUCT_MEMBER(guint16, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT32: + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_INT: + case GI_TYPE_TAG_UINT: + value->v_uint32 = G_STRUCT_MEMBER(guint32, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + value->v_uint64 = G_STRUCT_MEMBER(guint64, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_LONG: + case GI_TYPE_TAG_ULONG: + value->v_ulong = G_STRUCT_MEMBER(gulong, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_SSIZE: + case GI_TYPE_TAG_SIZE: + case GI_TYPE_TAG_GTYPE: + value->v_size = G_STRUCT_MEMBER(gsize, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_FLOAT: + value->v_float = G_STRUCT_MEMBER(gfloat, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_DOUBLE: + value->v_double = G_STRUCT_MEMBER(gdouble, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_TIME_T: +#if SIZEOF_TIME_T == 4 + value->v_int32 = G_STRUCT_MEMBER(time_t, mem, offset); +#elif SIZEOF_TIME_T == 8 + value->v_int64 = G_STRUCT_MEMBER(time_t, mem, offset); +#else +# error "Unexpected size for time_t: not 4 or 8" +#endif + result = TRUE; + break; + case GI_TYPE_TAG_UTF8: + case GI_TYPE_TAG_FILENAME: + case GI_TYPE_TAG_ARRAY: + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: + case GI_TYPE_TAG_GHASH: + g_warning("Field %s: type %s should have is_pointer set", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_type_tag_to_string (g_type_info_get_tag (type_info))); + break; + case GI_TYPE_TAG_ERROR: + /* Needs to be handled by the language binding directly */ + break; + case GI_TYPE_TAG_INTERFACE: + { + GIBaseInfo *interface = g_type_info_get_interface (type_info); + switch (g_base_info_get_type (interface)) + { + case GI_INFO_TYPE_STRUCT: + case GI_INFO_TYPE_UNION: + case GI_INFO_TYPE_BOXED: + /* Needs to be handled by the language binding directly */ + break; + case GI_INFO_TYPE_OBJECT: + break; + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + { + /* FIXME: there's a mismatch here between the value->v_int we use + * here and the glong result returned from g_value_info_get_value(). + * But to switch this to glong, we'd have to make g_function_info_invoke() + * translate value->v_long to the proper ABI for an enum function + * call parameter, which will usually be int, and then fix up language + * bindings. + */ + GITypeTag storage_type = g_enum_info_get_storage_type ((GIEnumInfo *)interface); + switch (storage_type) + { + case GI_TYPE_TAG_INT8: + case GI_TYPE_TAG_UINT8: + value->v_int = (gint)G_STRUCT_MEMBER(guint8, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT16: + case GI_TYPE_TAG_UINT16: + case GI_TYPE_TAG_SHORT: + case GI_TYPE_TAG_USHORT: + value->v_int = (gint)G_STRUCT_MEMBER(guint16, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT32: + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_INT: + case GI_TYPE_TAG_UINT: + value->v_int = (gint)G_STRUCT_MEMBER(guint32, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + value->v_int = (gint)G_STRUCT_MEMBER(guint64, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_LONG: + case GI_TYPE_TAG_ULONG: + value->v_int = (gint)G_STRUCT_MEMBER(gulong, mem, offset); + result = TRUE; + break; + default: + g_warning("Field %s: Unexpected enum storage type %s", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_type_tag_to_string (storage_type)); + break; + } + break; + } + case GI_INFO_TYPE_VFUNC: + case GI_INFO_TYPE_CALLBACK: + g_warning("Field %s: Interface type %d should have is_pointer set", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_base_info_get_type (interface)); + break; + case GI_INFO_TYPE_INVALID: + case GI_INFO_TYPE_INTERFACE: + case GI_INFO_TYPE_FUNCTION: + case GI_INFO_TYPE_CONSTANT: + case GI_INFO_TYPE_ERROR_DOMAIN: + case GI_INFO_TYPE_VALUE: + case GI_INFO_TYPE_SIGNAL: + case GI_INFO_TYPE_PROPERTY: + case GI_INFO_TYPE_FIELD: + case GI_INFO_TYPE_ARG: + case GI_INFO_TYPE_TYPE: + case GI_INFO_TYPE_UNRESOLVED: + g_warning("Field %s: Interface type %d not expected", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_base_info_get_type (interface)); + break; + } + + g_base_info_unref ((GIBaseInfo *)interface); + break; + } + break; + } + } + + g_base_info_unref ((GIBaseInfo *)type_info); + + return result; +} + +/** + * g_field_info_set_field: + * @field_info: a #GIFieldInfo + * @mem: pointer to a block of memory representing a C structure or union + * @value: a #GArgument holding the value to store + * + * Writes a field identified by a #GFieldInfo to a C structure or + * union. This only handles fields of simple C types. It will fail + * for a field of a composite type like a nested structure or union + * even if that is actually writable. Note also that that it will refuse + * to write fields where memory management would by required. A field + * with a type such as 'char *' must be set with a setter function. + * + * Returns: %TRUE if writing the field succeeded, otherwise %FALSE + */ +gboolean +g_field_info_set_field (GIFieldInfo *field_info, + gpointer mem, + const GArgument *value) +{ + int offset; + GITypeInfo *type_info; + gboolean result = FALSE; + + if ((g_field_info_get_flags (field_info) & GI_FIELD_IS_WRITABLE) == 0) + return FALSE; + + offset = g_field_info_get_offset (field_info); + type_info = g_field_info_get_type (field_info); + + if (!g_type_info_is_pointer (type_info)) + { + switch (g_type_info_get_tag (type_info)) + { + case GI_TYPE_TAG_VOID: + g_warning("Field %s: should not be have void type", + g_base_info_get_name ((GIBaseInfo *)field_info)); + break; + case GI_TYPE_TAG_BOOLEAN: + G_STRUCT_MEMBER(gboolean, mem, offset) = value->v_boolean != FALSE; + result = TRUE; + break; + case GI_TYPE_TAG_INT8: + case GI_TYPE_TAG_UINT8: + G_STRUCT_MEMBER(guint8, mem, offset) = value->v_uint8; + result = TRUE; + break; + case GI_TYPE_TAG_INT16: + case GI_TYPE_TAG_UINT16: + case GI_TYPE_TAG_SHORT: + case GI_TYPE_TAG_USHORT: + G_STRUCT_MEMBER(guint16, mem, offset) = value->v_uint16; + result = TRUE; + break; + case GI_TYPE_TAG_INT32: + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_INT: + case GI_TYPE_TAG_UINT: + G_STRUCT_MEMBER(guint32, mem, offset) = value->v_uint32; + result = TRUE; + break; + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + G_STRUCT_MEMBER(guint64, mem, offset) = value->v_uint64; + result = TRUE; + break; + case GI_TYPE_TAG_LONG: + case GI_TYPE_TAG_ULONG: + G_STRUCT_MEMBER(gulong, mem, offset)= value->v_ulong; + result = TRUE; + break; + case GI_TYPE_TAG_SSIZE: + case GI_TYPE_TAG_SIZE: + case GI_TYPE_TAG_GTYPE: + G_STRUCT_MEMBER(gsize, mem, offset) = value->v_size; + result = TRUE; + break; + case GI_TYPE_TAG_FLOAT: + G_STRUCT_MEMBER(gfloat, mem, offset) = value->v_float; + result = TRUE; + break; + case GI_TYPE_TAG_DOUBLE: + G_STRUCT_MEMBER(gdouble, mem, offset)= value->v_double; + result = TRUE; + break; + case GI_TYPE_TAG_TIME_T: +#if SIZEOF_TIME_T == 4 + G_STRUCT_MEMBER(time_t, mem, offset) = value->v_int32; +#elif SIZEOF_TIME_T == 8 + G_STRUCT_MEMBER(time_t, mem, offset) = value->v_int64; +#else +# error "Unexpected size for time_t: not 4 or 8" +#endif + result = TRUE; + break; + case GI_TYPE_TAG_UTF8: + case GI_TYPE_TAG_FILENAME: + case GI_TYPE_TAG_ARRAY: + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: + case GI_TYPE_TAG_GHASH: + g_warning("Field %s: type %s should have is_pointer set", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_type_tag_to_string (g_type_info_get_tag (type_info))); + break; + case GI_TYPE_TAG_ERROR: + /* Needs to be handled by the language binding directly */ + break; + case GI_TYPE_TAG_INTERFACE: + { + GIBaseInfo *interface = g_type_info_get_interface (type_info); + switch (g_base_info_get_type (interface)) + { + case GI_INFO_TYPE_STRUCT: + case GI_INFO_TYPE_UNION: + case GI_INFO_TYPE_BOXED: + /* Needs to be handled by the language binding directly */ + break; + case GI_INFO_TYPE_OBJECT: + break; + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + { + /* See FIXME above + */ + GITypeTag storage_type = g_enum_info_get_storage_type ((GIEnumInfo *)interface); + switch (storage_type) + { + case GI_TYPE_TAG_INT8: + case GI_TYPE_TAG_UINT8: + G_STRUCT_MEMBER(guint8, mem, offset) = (guint8)value->v_int; + result = TRUE; + break; + case GI_TYPE_TAG_INT16: + case GI_TYPE_TAG_UINT16: + case GI_TYPE_TAG_SHORT: + case GI_TYPE_TAG_USHORT: + G_STRUCT_MEMBER(guint16, mem, offset) = (guint16)value->v_int; + result = TRUE; + break; + case GI_TYPE_TAG_INT32: + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_INT: + case GI_TYPE_TAG_UINT: + G_STRUCT_MEMBER(guint32, mem, offset) = (guint32)value->v_int; + result = TRUE; + break; + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + G_STRUCT_MEMBER(guint64, mem, offset) = (guint64)value->v_int; + result = TRUE; + break; + case GI_TYPE_TAG_LONG: + case GI_TYPE_TAG_ULONG: + G_STRUCT_MEMBER(gulong, mem, offset) = (gulong)value->v_int; + result = TRUE; + break; + default: + g_warning("Field %s: Unexpected enum storage type %s", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_type_tag_to_string (storage_type)); + break; + } + break; + } + break; + case GI_INFO_TYPE_VFUNC: + case GI_INFO_TYPE_CALLBACK: + g_warning("Field%s: Interface type %d should have is_pointer set", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_base_info_get_type (interface)); + break; + case GI_INFO_TYPE_INVALID: + case GI_INFO_TYPE_INTERFACE: + case GI_INFO_TYPE_FUNCTION: + case GI_INFO_TYPE_CONSTANT: + case GI_INFO_TYPE_ERROR_DOMAIN: + case GI_INFO_TYPE_VALUE: + case GI_INFO_TYPE_SIGNAL: + case GI_INFO_TYPE_PROPERTY: + case GI_INFO_TYPE_FIELD: + case GI_INFO_TYPE_ARG: + case GI_INFO_TYPE_TYPE: + case GI_INFO_TYPE_UNRESOLVED: + g_warning("Field %s: Interface type %d not expected", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_base_info_get_type (interface)); + break; + } + + g_base_info_unref ((GIBaseInfo *)interface); + break; + } + break; + } + } + + g_base_info_unref ((GIBaseInfo *)type_info); + + return result; +} diff --git a/gifieldinfo.h b/gifieldinfo.h index 5d5970be4..53ff9be34 100644 --- a/gifieldinfo.h +++ b/gifieldinfo.h @@ -37,13 +37,12 @@ GIFieldInfoFlags g_field_info_get_flags (GIFieldInfo *info); gint g_field_info_get_size (GIFieldInfo *info); gint g_field_info_get_offset (GIFieldInfo *info); GITypeInfo * g_field_info_get_type (GIFieldInfo *info); - -gboolean g_field_info_get_field (GIFieldInfo *field_info, - gpointer mem, - GArgument *value); -gboolean g_field_info_set_field (GIFieldInfo *field_info, - gpointer mem, - const GArgument *value); +gboolean g_field_info_get_field (GIFieldInfo *field_info, + gpointer mem, + GArgument *value); +gboolean g_field_info_set_field (GIFieldInfo *field_info, + gpointer mem, + const GArgument *value); G_END_DECLS From f05d309f572ec5c0d7150bff1a548b833456296c Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 13:22:29 -0300 Subject: [PATCH 313/692] [gifunctioninfo] Move over invoke function Move over g_function_info_invoke to gifunctioninfo.c --- gifunctioninfo.c | 226 +++++++++++++++++++++++++++++++++++++++++++++- ginvoke.c | 227 +---------------------------------------------- 2 files changed, 225 insertions(+), 228 deletions(-) diff --git a/gifunctioninfo.c b/gifunctioninfo.c index 07e0ec677..1bda54df8 100644 --- a/gifunctioninfo.c +++ b/gifunctioninfo.c @@ -24,8 +24,7 @@ #include #include "girepository-private.h" #include "gitypelib-internal.h" - -/* GIFunctionInfo functions */ +#include "girffi.h" /** * SECTION:gifunctioninfo @@ -167,3 +166,226 @@ g_function_info_get_vfunc (GIFunctionInfo *info) return g_interface_info_get_vfunc (container, blob->index); } +GQuark +g_invoke_error_quark (void) +{ + static GQuark quark = 0; + if (quark == 0) + quark = g_quark_from_static_string ("g-invoke-error-quark"); + return quark; +} + +/** + * g_function_info_invoke: + * @info: a #GIFunctionInfo describing the function to invoke + * @in_args: an array of #GArguments, one for each in + * parameter of @info. If there are no in parameter, @in_args + * can be %NULL + * @n_in_args: the length of the @in_args array + * @out_args: an array of #GArguments, one for each out + * parameter of @info. If there are no out parameters, @out_args + * may be %NULL + * @n_out_args: the length of the @out_args array + * @return_value: return location for the return value of the + * function. If the function returns void, @return_value may be + * %NULL + * @error: return location for detailed error information, or %NULL + * + * Invokes the function described in @info with the given + * arguments. Note that inout parameters must appear in both + * argument lists. This function uses dlsym() to obtain a pointer + * to the function, so the library or shared object containing the + * described function must either be linked to the caller, or must + * have been g_module_symbol()ed before calling this function. + * + * Returns: %TRUE if the function has been invoked, %FALSE if an + * error occurred. + */ +gboolean +g_function_info_invoke (GIFunctionInfo *info, + const GArgument *in_args, + int n_in_args, + const GArgument *out_args, + int n_out_args, + GArgument *return_value, + GError **error) +{ + ffi_cif cif; + ffi_type *rtype; + ffi_type **atypes; + const gchar *symbol; + gpointer func; + GITypeInfo *tinfo; + GIArgInfo *ainfo; + gboolean is_method; + gboolean throws; + gint n_args, n_invoke_args, in_pos, out_pos, i; + gpointer *args; + gboolean success = FALSE; + GError *local_error = NULL; + gpointer error_address = &local_error; + + symbol = g_function_info_get_symbol (info); + + if (!g_typelib_symbol (g_base_info_get_typelib((GIBaseInfo *) info), + symbol, &func)) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_SYMBOL_NOT_FOUND, + "Could not locate %s: %s", symbol, g_module_error ()); + + return FALSE; + } + + is_method = (g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0 + && (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR) == 0; + throws = g_function_info_get_flags (info) & GI_FUNCTION_THROWS; + + tinfo = g_callable_info_get_return_type ((GICallableInfo *)info); + rtype = g_type_info_get_ffi_type (tinfo); + g_base_info_unref ((GIBaseInfo *)tinfo); + + in_pos = 0; + out_pos = 0; + + n_args = g_callable_info_get_n_args ((GICallableInfo *)info); + if (is_method) + { + if (n_in_args == 0) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too few \"in\" arguments (handling this)"); + goto out; + } + n_invoke_args = n_args+1; + in_pos++; + } + else + n_invoke_args = n_args; + + if (throws) + /* Add an argument for the GError */ + n_invoke_args ++; + + atypes = g_alloca (sizeof (ffi_type*) * n_invoke_args); + args = g_alloca (sizeof (gpointer) * n_invoke_args); + + if (is_method) + { + atypes[0] = &ffi_type_pointer; + args[0] = (gpointer) &in_args[0]; + } + for (i = 0; i < n_args; i++) + { + int offset = (is_method ? 1 : 0); + ainfo = g_callable_info_get_arg ((GICallableInfo *)info, i); + switch (g_arg_info_get_direction (ainfo)) + { + case GI_DIRECTION_IN: + tinfo = g_arg_info_get_type (ainfo); + atypes[i+offset] = g_type_info_get_ffi_type (tinfo); + g_base_info_unref ((GIBaseInfo *)tinfo); + + if (in_pos >= n_in_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too few \"in\" arguments (handling in)"); + goto out; + } + + args[i+offset] = (gpointer)&in_args[in_pos]; + in_pos++; + + break; + case GI_DIRECTION_OUT: + atypes[i+offset] = &ffi_type_pointer; + + if (out_pos >= n_out_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too few \"out\" arguments (handling out)"); + goto out; + } + + args[i+offset] = (gpointer)&out_args[out_pos]; + out_pos++; + break; + case GI_DIRECTION_INOUT: + atypes[i+offset] = &ffi_type_pointer; + + if (in_pos >= n_in_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too few \"in\" arguments (handling inout)"); + goto out; + } + + if (out_pos >= n_out_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too few \"out\" arguments (handling inout)"); + goto out; + } + + args[i+offset] = (gpointer)&in_args[in_pos]; + in_pos++; + out_pos++; + break; + default: + g_assert_not_reached (); + } + g_base_info_unref ((GIBaseInfo *)ainfo); + } + + if (throws) + { + args[n_invoke_args - 1] = &error_address; + atypes[n_invoke_args - 1] = &ffi_type_pointer; + } + + if (in_pos < n_in_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too many \"in\" arguments (at end)"); + goto out; + } + if (out_pos < n_out_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too many \"out\" arguments (at end)"); + goto out; + } + + if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_invoke_args, rtype, atypes) != FFI_OK) + goto out; + + g_return_val_if_fail (return_value, FALSE); + ffi_call (&cif, func, return_value, args); + + if (local_error) + { + g_propagate_error (error, local_error); + success = FALSE; + } + else + { + success = TRUE; + } + out: + return success; +} diff --git a/ginvoke.c b/ginvoke.c index 3de6af415..0f9d22c94 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -23,235 +23,10 @@ #include #include -#include "girepository.h" +#include #include "girffi.h" -#include "gitypelib-internal.h" #include "config.h" -GQuark -g_invoke_error_quark (void) -{ - static GQuark quark = 0; - if (quark == 0) - quark = g_quark_from_static_string ("g-invoke-error-quark"); - return quark; -} - -/** - * g_function_info_invoke: - * @info: a #GIFunctionInfo describing the function to invoke - * @in_args: an array of #GArguments, one for each in - * parameter of @info. If there are no in parameter, @in_args - * can be %NULL - * @n_in_args: the length of the @in_args array - * @out_args: an array of #GArguments, one for each out - * parameter of @info. If there are no out parameters, @out_args - * may be %NULL - * @n_out_args: the length of the @out_args array - * @return_value: return location for the return value of the - * function. If the function returns void, @return_value may be - * %NULL - * @error: return location for detailed error information, or %NULL - * - * Invokes the function described in @info with the given - * arguments. Note that inout parameters must appear in both - * argument lists. This function uses dlsym() to obtain a pointer - * to the function, so the library or shared object containing the - * described function must either be linked to the caller, or must - * have been g_module_symbol()ed before calling this function. - * - * Returns: %TRUE if the function has been invoked, %FALSE if an - * error occurred. - */ -gboolean -g_function_info_invoke (GIFunctionInfo *info, - const GArgument *in_args, - int n_in_args, - const GArgument *out_args, - int n_out_args, - GArgument *return_value, - GError **error) -{ - ffi_cif cif; - ffi_type *rtype; - ffi_type **atypes; - const gchar *symbol; - gpointer func; - GITypeInfo *tinfo; - GIArgInfo *ainfo; - gboolean is_method; - gboolean throws; - gint n_args, n_invoke_args, in_pos, out_pos, i; - gpointer *args; - gboolean success = FALSE; - GError *local_error = NULL; - gpointer error_address = &local_error; - - symbol = g_function_info_get_symbol (info); - - if (!g_typelib_symbol (g_base_info_get_typelib((GIBaseInfo *) info), - symbol, &func)) - { - g_set_error (error, - G_INVOKE_ERROR, - G_INVOKE_ERROR_SYMBOL_NOT_FOUND, - "Could not locate %s: %s", symbol, g_module_error ()); - - return FALSE; - } - - is_method = (g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0 - && (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR) == 0; - throws = g_function_info_get_flags (info) & GI_FUNCTION_THROWS; - - tinfo = g_callable_info_get_return_type ((GICallableInfo *)info); - rtype = g_type_info_get_ffi_type (tinfo); - g_base_info_unref ((GIBaseInfo *)tinfo); - - in_pos = 0; - out_pos = 0; - - n_args = g_callable_info_get_n_args ((GICallableInfo *)info); - if (is_method) - { - if (n_in_args == 0) - { - g_set_error (error, - G_INVOKE_ERROR, - G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too few \"in\" arguments (handling this)"); - goto out; - } - n_invoke_args = n_args+1; - in_pos++; - } - else - n_invoke_args = n_args; - - if (throws) - /* Add an argument for the GError */ - n_invoke_args ++; - - atypes = g_alloca (sizeof (ffi_type*) * n_invoke_args); - args = g_alloca (sizeof (gpointer) * n_invoke_args); - - if (is_method) - { - atypes[0] = &ffi_type_pointer; - args[0] = (gpointer) &in_args[0]; - } - for (i = 0; i < n_args; i++) - { - int offset = (is_method ? 1 : 0); - ainfo = g_callable_info_get_arg ((GICallableInfo *)info, i); - switch (g_arg_info_get_direction (ainfo)) - { - case GI_DIRECTION_IN: - tinfo = g_arg_info_get_type (ainfo); - atypes[i+offset] = g_type_info_get_ffi_type (tinfo); - g_base_info_unref ((GIBaseInfo *)tinfo); - - if (in_pos >= n_in_args) - { - g_set_error (error, - G_INVOKE_ERROR, - G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too few \"in\" arguments (handling in)"); - goto out; - } - - args[i+offset] = (gpointer)&in_args[in_pos]; - in_pos++; - - break; - case GI_DIRECTION_OUT: - atypes[i+offset] = &ffi_type_pointer; - - if (out_pos >= n_out_args) - { - g_set_error (error, - G_INVOKE_ERROR, - G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too few \"out\" arguments (handling out)"); - goto out; - } - - args[i+offset] = (gpointer)&out_args[out_pos]; - out_pos++; - break; - case GI_DIRECTION_INOUT: - atypes[i+offset] = &ffi_type_pointer; - - if (in_pos >= n_in_args) - { - g_set_error (error, - G_INVOKE_ERROR, - G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too few \"in\" arguments (handling inout)"); - goto out; - } - - if (out_pos >= n_out_args) - { - g_set_error (error, - G_INVOKE_ERROR, - G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too few \"out\" arguments (handling inout)"); - goto out; - } - - args[i+offset] = (gpointer)&in_args[in_pos]; - in_pos++; - out_pos++; - break; - default: - g_assert_not_reached (); - } - g_base_info_unref ((GIBaseInfo *)ainfo); - } - - if (throws) - { - args[n_invoke_args - 1] = &error_address; - atypes[n_invoke_args - 1] = &ffi_type_pointer; - } - - if (in_pos < n_in_args) - { - g_set_error (error, - G_INVOKE_ERROR, - G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too many \"in\" arguments (at end)"); - goto out; - } - if (out_pos < n_out_args) - { - g_set_error (error, - G_INVOKE_ERROR, - G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too many \"out\" arguments (at end)"); - goto out; - } - - if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_invoke_args, rtype, atypes) != FFI_OK) - goto out; - - g_return_val_if_fail (return_value, FALSE); - ffi_call (&cif, func, return_value, args); - - if (local_error) - { - g_propagate_error (error, local_error); - success = FALSE; - } - else - { - success = TRUE; - } - out: - return success; -} - static ffi_type * value_to_ffi_type (const GValue *gvalue, gpointer *value) { From 94d52d910c25c8231aa99bb95c6efd00e8237fbb Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 13:35:14 -0300 Subject: [PATCH 314/692] [gifieldinfo] Document, indent and check params Document the remaining functions, indent to match coding style and check so that all info params are set and of the right type. --- gifieldinfo.c | 735 +++++++++++++++++++++++++++----------------------- 1 file changed, 393 insertions(+), 342 deletions(-) diff --git a/gifieldinfo.c b/gifieldinfo.c index d6f2da98e..878f411cc 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -43,9 +43,13 @@ GIFieldInfoFlags g_field_info_get_flags (GIFieldInfo *info) { GIFieldInfoFlags flags; - GIRealInfo *rinfo = (GIRealInfo *)info; - FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; + FieldBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_FIELD_INFO (info), 0); + + blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; flags = 0; @@ -58,32 +62,73 @@ g_field_info_get_flags (GIFieldInfo *info) return flags; } +/** + * g_field_info_get_size: + * @info: a #GIFieldInfo + * + * Obtain the size in bits of the field member, this is how + * much space you need to allocate to store the field. + * + * Returns: the field size + */ gint g_field_info_get_size (GIFieldInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; + FieldBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_FIELD_INFO (info), 0); + + blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->bits; } +/** + * g_field_info_get_offset: + * @info: a #GIFieldInfo + * + * Obtain the offset in bits of the field member, this is relative + * to the beginning of the struct or union. + * + * Returns: the field offset + */ gint g_field_info_get_offset (GIFieldInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; + FieldBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_FIELD_INFO (info), 0); + + blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->struct_offset; } +/** + * g_field_info_get_type: + * + * Obtain the type of a field as a #GITypeInfo. + * + * Returns: (transfer full): the #GITypeInfo. Free the struct by calling + * g_base_info_unref() when done. + */ GITypeInfo * g_field_info_get_type (GIFieldInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; Header *header = (Header *)rinfo->typelib->data; - FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; + FieldBlob *blob; GIRealInfo *type_info; + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_FIELD_INFO (info), NULL); + + blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; + if (blob->has_embedded_type) { type_info = (GIRealInfo *) g_info_new (GI_INFO_TYPE_TYPE, @@ -115,195 +160,198 @@ g_field_info_get_field (GIFieldInfo *field_info, gpointer mem, GArgument *value) { - int offset; - GITypeInfo *type_info; - gboolean result = FALSE; + int offset; + GITypeInfo *type_info; + gboolean result = FALSE; - if ((g_field_info_get_flags (field_info) & GI_FIELD_IS_READABLE) == 0) - return FALSE; + g_return_val_if_fail (field_info != NULL, FALSE); + g_return_val_if_fail (GI_IS_FIELD_INFO (field_info), FALSE); - offset = g_field_info_get_offset (field_info); - type_info = g_field_info_get_type (field_info); + if ((g_field_info_get_flags (field_info) & GI_FIELD_IS_READABLE) == 0) + return FALSE; - if (g_type_info_is_pointer (type_info)) - { - value->v_pointer = G_STRUCT_MEMBER(gpointer, mem, offset); - result = TRUE; - } - else - { - switch (g_type_info_get_tag (type_info)) - { - case GI_TYPE_TAG_VOID: - g_warning("Field %s: should not be have void type", - g_base_info_get_name ((GIBaseInfo *)field_info)); - break; - case GI_TYPE_TAG_BOOLEAN: - value->v_boolean = G_STRUCT_MEMBER(gboolean, mem, offset) != FALSE; - result = TRUE; - break; - case GI_TYPE_TAG_INT8: - case GI_TYPE_TAG_UINT8: - value->v_uint8 = G_STRUCT_MEMBER(guint8, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_INT16: - case GI_TYPE_TAG_UINT16: - case GI_TYPE_TAG_SHORT: - case GI_TYPE_TAG_USHORT: - value->v_uint16 = G_STRUCT_MEMBER(guint16, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_INT32: - case GI_TYPE_TAG_UINT32: - case GI_TYPE_TAG_INT: - case GI_TYPE_TAG_UINT: - value->v_uint32 = G_STRUCT_MEMBER(guint32, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_INT64: - case GI_TYPE_TAG_UINT64: - value->v_uint64 = G_STRUCT_MEMBER(guint64, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_LONG: - case GI_TYPE_TAG_ULONG: - value->v_ulong = G_STRUCT_MEMBER(gulong, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_SSIZE: - case GI_TYPE_TAG_SIZE: - case GI_TYPE_TAG_GTYPE: - value->v_size = G_STRUCT_MEMBER(gsize, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_FLOAT: - value->v_float = G_STRUCT_MEMBER(gfloat, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_DOUBLE: - value->v_double = G_STRUCT_MEMBER(gdouble, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_TIME_T: + offset = g_field_info_get_offset (field_info); + type_info = g_field_info_get_type (field_info); + + if (g_type_info_is_pointer (type_info)) + { + value->v_pointer = G_STRUCT_MEMBER (gpointer, mem, offset); + result = TRUE; + } + else + { + switch (g_type_info_get_tag (type_info)) + { + case GI_TYPE_TAG_VOID: + g_warning("Field %s: should not be have void type", + g_base_info_get_name ((GIBaseInfo *)field_info)); + break; + case GI_TYPE_TAG_BOOLEAN: + value->v_boolean = G_STRUCT_MEMBER (gboolean, mem, offset) != FALSE; + result = TRUE; + break; + case GI_TYPE_TAG_INT8: + case GI_TYPE_TAG_UINT8: + value->v_uint8 = G_STRUCT_MEMBER (guint8, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT16: + case GI_TYPE_TAG_UINT16: + case GI_TYPE_TAG_SHORT: + case GI_TYPE_TAG_USHORT: + value->v_uint16 = G_STRUCT_MEMBER (guint16, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT32: + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_INT: + case GI_TYPE_TAG_UINT: + value->v_uint32 = G_STRUCT_MEMBER (guint32, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + value->v_uint64 = G_STRUCT_MEMBER (guint64, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_LONG: + case GI_TYPE_TAG_ULONG: + value->v_ulong = G_STRUCT_MEMBER (gulong, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_SSIZE: + case GI_TYPE_TAG_SIZE: + case GI_TYPE_TAG_GTYPE: + value->v_size = G_STRUCT_MEMBER (gsize, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_FLOAT: + value->v_float = G_STRUCT_MEMBER (gfloat, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_DOUBLE: + value->v_double = G_STRUCT_MEMBER (gdouble, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_TIME_T: #if SIZEOF_TIME_T == 4 - value->v_int32 = G_STRUCT_MEMBER(time_t, mem, offset); + value->v_int32 = G_STRUCT_MEMBER (time_t, mem, offset); #elif SIZEOF_TIME_T == 8 - value->v_int64 = G_STRUCT_MEMBER(time_t, mem, offset); + value->v_int64 = G_STRUCT_MEMBER (time_t, mem, offset); #else # error "Unexpected size for time_t: not 4 or 8" #endif - result = TRUE; - break; - case GI_TYPE_TAG_UTF8: - case GI_TYPE_TAG_FILENAME: - case GI_TYPE_TAG_ARRAY: - case GI_TYPE_TAG_GLIST: - case GI_TYPE_TAG_GSLIST: - case GI_TYPE_TAG_GHASH: - g_warning("Field %s: type %s should have is_pointer set", - g_base_info_get_name ((GIBaseInfo *)field_info), - g_type_tag_to_string (g_type_info_get_tag (type_info))); - break; - case GI_TYPE_TAG_ERROR: - /* Needs to be handled by the language binding directly */ - break; - case GI_TYPE_TAG_INTERFACE: - { - GIBaseInfo *interface = g_type_info_get_interface (type_info); - switch (g_base_info_get_type (interface)) + result = TRUE; + break; + case GI_TYPE_TAG_UTF8: + case GI_TYPE_TAG_FILENAME: + case GI_TYPE_TAG_ARRAY: + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: + case GI_TYPE_TAG_GHASH: + g_warning("Field %s: type %s should have is_pointer set", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_type_tag_to_string (g_type_info_get_tag (type_info))); + break; + case GI_TYPE_TAG_ERROR: + /* Needs to be handled by the language binding directly */ + break; + case GI_TYPE_TAG_INTERFACE: + { + GIBaseInfo *interface = g_type_info_get_interface (type_info); + switch (g_base_info_get_type (interface)) + { + case GI_INFO_TYPE_STRUCT: + case GI_INFO_TYPE_UNION: + case GI_INFO_TYPE_BOXED: + /* Needs to be handled by the language binding directly */ + break; + case GI_INFO_TYPE_OBJECT: + break; + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: { - case GI_INFO_TYPE_STRUCT: - case GI_INFO_TYPE_UNION: - case GI_INFO_TYPE_BOXED: - /* Needs to be handled by the language binding directly */ - break; - case GI_INFO_TYPE_OBJECT: - break; - case GI_INFO_TYPE_ENUM: - case GI_INFO_TYPE_FLAGS: - { - /* FIXME: there's a mismatch here between the value->v_int we use - * here and the glong result returned from g_value_info_get_value(). - * But to switch this to glong, we'd have to make g_function_info_invoke() - * translate value->v_long to the proper ABI for an enum function - * call parameter, which will usually be int, and then fix up language - * bindings. - */ - GITypeTag storage_type = g_enum_info_get_storage_type ((GIEnumInfo *)interface); - switch (storage_type) - { - case GI_TYPE_TAG_INT8: - case GI_TYPE_TAG_UINT8: - value->v_int = (gint)G_STRUCT_MEMBER(guint8, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_INT16: - case GI_TYPE_TAG_UINT16: - case GI_TYPE_TAG_SHORT: - case GI_TYPE_TAG_USHORT: - value->v_int = (gint)G_STRUCT_MEMBER(guint16, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_INT32: - case GI_TYPE_TAG_UINT32: - case GI_TYPE_TAG_INT: - case GI_TYPE_TAG_UINT: - value->v_int = (gint)G_STRUCT_MEMBER(guint32, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_INT64: - case GI_TYPE_TAG_UINT64: - value->v_int = (gint)G_STRUCT_MEMBER(guint64, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_LONG: - case GI_TYPE_TAG_ULONG: - value->v_int = (gint)G_STRUCT_MEMBER(gulong, mem, offset); - result = TRUE; - break; - default: - g_warning("Field %s: Unexpected enum storage type %s", - g_base_info_get_name ((GIBaseInfo *)field_info), - g_type_tag_to_string (storage_type)); - break; - } - break; - } - case GI_INFO_TYPE_VFUNC: - case GI_INFO_TYPE_CALLBACK: - g_warning("Field %s: Interface type %d should have is_pointer set", - g_base_info_get_name ((GIBaseInfo *)field_info), - g_base_info_get_type (interface)); - break; - case GI_INFO_TYPE_INVALID: - case GI_INFO_TYPE_INTERFACE: - case GI_INFO_TYPE_FUNCTION: - case GI_INFO_TYPE_CONSTANT: - case GI_INFO_TYPE_ERROR_DOMAIN: - case GI_INFO_TYPE_VALUE: - case GI_INFO_TYPE_SIGNAL: - case GI_INFO_TYPE_PROPERTY: - case GI_INFO_TYPE_FIELD: - case GI_INFO_TYPE_ARG: - case GI_INFO_TYPE_TYPE: - case GI_INFO_TYPE_UNRESOLVED: - g_warning("Field %s: Interface type %d not expected", - g_base_info_get_name ((GIBaseInfo *)field_info), - g_base_info_get_type (interface)); + /* FIXME: there's a mismatch here between the value->v_int we use + * here and the glong result returned from g_value_info_get_value(). + * But to switch this to glong, we'd have to make g_function_info_invoke() + * translate value->v_long to the proper ABI for an enum function + * call parameter, which will usually be int, and then fix up language + * bindings. + */ + GITypeTag storage_type = g_enum_info_get_storage_type ((GIEnumInfo *)interface); + switch (storage_type) + { + case GI_TYPE_TAG_INT8: + case GI_TYPE_TAG_UINT8: + value->v_int = (gint)G_STRUCT_MEMBER (guint8, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT16: + case GI_TYPE_TAG_UINT16: + case GI_TYPE_TAG_SHORT: + case GI_TYPE_TAG_USHORT: + value->v_int = (gint)G_STRUCT_MEMBER (guint16, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT32: + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_INT: + case GI_TYPE_TAG_UINT: + value->v_int = (gint)G_STRUCT_MEMBER (guint32, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + value->v_int = (gint)G_STRUCT_MEMBER (guint64, mem, offset); + result = TRUE; + break; + case GI_TYPE_TAG_LONG: + case GI_TYPE_TAG_ULONG: + value->v_int = (gint)G_STRUCT_MEMBER (gulong, mem, offset); + result = TRUE; + break; + default: + g_warning("Field %s: Unexpected enum storage type %s", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_type_tag_to_string (storage_type)); + break; + } break; } + case GI_INFO_TYPE_VFUNC: + case GI_INFO_TYPE_CALLBACK: + g_warning("Field %s: Interface type %d should have is_pointer set", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_base_info_get_type (interface)); + break; + case GI_INFO_TYPE_INVALID: + case GI_INFO_TYPE_INTERFACE: + case GI_INFO_TYPE_FUNCTION: + case GI_INFO_TYPE_CONSTANT: + case GI_INFO_TYPE_ERROR_DOMAIN: + case GI_INFO_TYPE_VALUE: + case GI_INFO_TYPE_SIGNAL: + case GI_INFO_TYPE_PROPERTY: + case GI_INFO_TYPE_FIELD: + case GI_INFO_TYPE_ARG: + case GI_INFO_TYPE_TYPE: + case GI_INFO_TYPE_UNRESOLVED: + g_warning("Field %s: Interface type %d not expected", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_base_info_get_type (interface)); + break; + } - g_base_info_unref ((GIBaseInfo *)interface); - break; - } + g_base_info_unref ((GIBaseInfo *)interface); break; } - } + break; + } + } - g_base_info_unref ((GIBaseInfo *)type_info); + g_base_info_unref ((GIBaseInfo *)type_info); - return result; + return result; } /** @@ -326,184 +374,187 @@ g_field_info_set_field (GIFieldInfo *field_info, gpointer mem, const GArgument *value) { - int offset; - GITypeInfo *type_info; - gboolean result = FALSE; + int offset; + GITypeInfo *type_info; + gboolean result = FALSE; - if ((g_field_info_get_flags (field_info) & GI_FIELD_IS_WRITABLE) == 0) - return FALSE; + g_return_val_if_fail (field_info != NULL, FALSE); + g_return_val_if_fail (GI_IS_FIELD_INFO (field_info), FALSE); - offset = g_field_info_get_offset (field_info); - type_info = g_field_info_get_type (field_info); + if ((g_field_info_get_flags (field_info) & GI_FIELD_IS_WRITABLE) == 0) + return FALSE; - if (!g_type_info_is_pointer (type_info)) - { - switch (g_type_info_get_tag (type_info)) - { - case GI_TYPE_TAG_VOID: - g_warning("Field %s: should not be have void type", - g_base_info_get_name ((GIBaseInfo *)field_info)); - break; - case GI_TYPE_TAG_BOOLEAN: - G_STRUCT_MEMBER(gboolean, mem, offset) = value->v_boolean != FALSE; - result = TRUE; - break; - case GI_TYPE_TAG_INT8: - case GI_TYPE_TAG_UINT8: - G_STRUCT_MEMBER(guint8, mem, offset) = value->v_uint8; - result = TRUE; - break; - case GI_TYPE_TAG_INT16: - case GI_TYPE_TAG_UINT16: - case GI_TYPE_TAG_SHORT: - case GI_TYPE_TAG_USHORT: - G_STRUCT_MEMBER(guint16, mem, offset) = value->v_uint16; - result = TRUE; - break; - case GI_TYPE_TAG_INT32: - case GI_TYPE_TAG_UINT32: - case GI_TYPE_TAG_INT: - case GI_TYPE_TAG_UINT: - G_STRUCT_MEMBER(guint32, mem, offset) = value->v_uint32; - result = TRUE; - break; - case GI_TYPE_TAG_INT64: - case GI_TYPE_TAG_UINT64: - G_STRUCT_MEMBER(guint64, mem, offset) = value->v_uint64; - result = TRUE; - break; - case GI_TYPE_TAG_LONG: - case GI_TYPE_TAG_ULONG: - G_STRUCT_MEMBER(gulong, mem, offset)= value->v_ulong; - result = TRUE; - break; - case GI_TYPE_TAG_SSIZE: - case GI_TYPE_TAG_SIZE: - case GI_TYPE_TAG_GTYPE: - G_STRUCT_MEMBER(gsize, mem, offset) = value->v_size; - result = TRUE; - break; - case GI_TYPE_TAG_FLOAT: - G_STRUCT_MEMBER(gfloat, mem, offset) = value->v_float; - result = TRUE; - break; - case GI_TYPE_TAG_DOUBLE: - G_STRUCT_MEMBER(gdouble, mem, offset)= value->v_double; - result = TRUE; - break; - case GI_TYPE_TAG_TIME_T: + offset = g_field_info_get_offset (field_info); + type_info = g_field_info_get_type (field_info); + + if (!g_type_info_is_pointer (type_info)) + { + switch (g_type_info_get_tag (type_info)) + { + case GI_TYPE_TAG_VOID: + g_warning("Field %s: should not be have void type", + g_base_info_get_name ((GIBaseInfo *)field_info)); + break; + case GI_TYPE_TAG_BOOLEAN: + G_STRUCT_MEMBER (gboolean, mem, offset) = value->v_boolean != FALSE; + result = TRUE; + break; + case GI_TYPE_TAG_INT8: + case GI_TYPE_TAG_UINT8: + G_STRUCT_MEMBER (guint8, mem, offset) = value->v_uint8; + result = TRUE; + break; + case GI_TYPE_TAG_INT16: + case GI_TYPE_TAG_UINT16: + case GI_TYPE_TAG_SHORT: + case GI_TYPE_TAG_USHORT: + G_STRUCT_MEMBER (guint16, mem, offset) = value->v_uint16; + result = TRUE; + break; + case GI_TYPE_TAG_INT32: + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_INT: + case GI_TYPE_TAG_UINT: + G_STRUCT_MEMBER (guint32, mem, offset) = value->v_uint32; + result = TRUE; + break; + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + G_STRUCT_MEMBER (guint64, mem, offset) = value->v_uint64; + result = TRUE; + break; + case GI_TYPE_TAG_LONG: + case GI_TYPE_TAG_ULONG: + G_STRUCT_MEMBER (gulong, mem, offset)= value->v_ulong; + result = TRUE; + break; + case GI_TYPE_TAG_SSIZE: + case GI_TYPE_TAG_SIZE: + case GI_TYPE_TAG_GTYPE: + G_STRUCT_MEMBER (gsize, mem, offset) = value->v_size; + result = TRUE; + break; + case GI_TYPE_TAG_FLOAT: + G_STRUCT_MEMBER (gfloat, mem, offset) = value->v_float; + result = TRUE; + break; + case GI_TYPE_TAG_DOUBLE: + G_STRUCT_MEMBER (gdouble, mem, offset)= value->v_double; + result = TRUE; + break; + case GI_TYPE_TAG_TIME_T: #if SIZEOF_TIME_T == 4 - G_STRUCT_MEMBER(time_t, mem, offset) = value->v_int32; + G_STRUCT_MEMBER (time_t, mem, offset) = value->v_int32; #elif SIZEOF_TIME_T == 8 - G_STRUCT_MEMBER(time_t, mem, offset) = value->v_int64; + G_STRUCT_MEMBER (time_t, mem, offset) = value->v_int64; #else # error "Unexpected size for time_t: not 4 or 8" #endif - result = TRUE; - break; - case GI_TYPE_TAG_UTF8: - case GI_TYPE_TAG_FILENAME: - case GI_TYPE_TAG_ARRAY: - case GI_TYPE_TAG_GLIST: - case GI_TYPE_TAG_GSLIST: - case GI_TYPE_TAG_GHASH: - g_warning("Field %s: type %s should have is_pointer set", - g_base_info_get_name ((GIBaseInfo *)field_info), - g_type_tag_to_string (g_type_info_get_tag (type_info))); - break; - case GI_TYPE_TAG_ERROR: - /* Needs to be handled by the language binding directly */ - break; - case GI_TYPE_TAG_INTERFACE: - { - GIBaseInfo *interface = g_type_info_get_interface (type_info); - switch (g_base_info_get_type (interface)) + result = TRUE; + break; + case GI_TYPE_TAG_UTF8: + case GI_TYPE_TAG_FILENAME: + case GI_TYPE_TAG_ARRAY: + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: + case GI_TYPE_TAG_GHASH: + g_warning("Field %s: type %s should have is_pointer set", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_type_tag_to_string (g_type_info_get_tag (type_info))); + break; + case GI_TYPE_TAG_ERROR: + /* Needs to be handled by the language binding directly */ + break; + case GI_TYPE_TAG_INTERFACE: + { + GIBaseInfo *interface = g_type_info_get_interface (type_info); + switch (g_base_info_get_type (interface)) + { + case GI_INFO_TYPE_STRUCT: + case GI_INFO_TYPE_UNION: + case GI_INFO_TYPE_BOXED: + /* Needs to be handled by the language binding directly */ + break; + case GI_INFO_TYPE_OBJECT: + break; + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: { - case GI_INFO_TYPE_STRUCT: - case GI_INFO_TYPE_UNION: - case GI_INFO_TYPE_BOXED: - /* Needs to be handled by the language binding directly */ - break; - case GI_INFO_TYPE_OBJECT: - break; - case GI_INFO_TYPE_ENUM: - case GI_INFO_TYPE_FLAGS: - { - /* See FIXME above - */ - GITypeTag storage_type = g_enum_info_get_storage_type ((GIEnumInfo *)interface); - switch (storage_type) - { - case GI_TYPE_TAG_INT8: - case GI_TYPE_TAG_UINT8: - G_STRUCT_MEMBER(guint8, mem, offset) = (guint8)value->v_int; - result = TRUE; - break; - case GI_TYPE_TAG_INT16: - case GI_TYPE_TAG_UINT16: - case GI_TYPE_TAG_SHORT: - case GI_TYPE_TAG_USHORT: - G_STRUCT_MEMBER(guint16, mem, offset) = (guint16)value->v_int; - result = TRUE; - break; - case GI_TYPE_TAG_INT32: - case GI_TYPE_TAG_UINT32: - case GI_TYPE_TAG_INT: - case GI_TYPE_TAG_UINT: - G_STRUCT_MEMBER(guint32, mem, offset) = (guint32)value->v_int; - result = TRUE; - break; - case GI_TYPE_TAG_INT64: - case GI_TYPE_TAG_UINT64: - G_STRUCT_MEMBER(guint64, mem, offset) = (guint64)value->v_int; - result = TRUE; - break; - case GI_TYPE_TAG_LONG: - case GI_TYPE_TAG_ULONG: - G_STRUCT_MEMBER(gulong, mem, offset) = (gulong)value->v_int; - result = TRUE; - break; - default: - g_warning("Field %s: Unexpected enum storage type %s", - g_base_info_get_name ((GIBaseInfo *)field_info), - g_type_tag_to_string (storage_type)); - break; - } - break; - } - break; - case GI_INFO_TYPE_VFUNC: - case GI_INFO_TYPE_CALLBACK: - g_warning("Field%s: Interface type %d should have is_pointer set", - g_base_info_get_name ((GIBaseInfo *)field_info), - g_base_info_get_type (interface)); - break; - case GI_INFO_TYPE_INVALID: - case GI_INFO_TYPE_INTERFACE: - case GI_INFO_TYPE_FUNCTION: - case GI_INFO_TYPE_CONSTANT: - case GI_INFO_TYPE_ERROR_DOMAIN: - case GI_INFO_TYPE_VALUE: - case GI_INFO_TYPE_SIGNAL: - case GI_INFO_TYPE_PROPERTY: - case GI_INFO_TYPE_FIELD: - case GI_INFO_TYPE_ARG: - case GI_INFO_TYPE_TYPE: - case GI_INFO_TYPE_UNRESOLVED: - g_warning("Field %s: Interface type %d not expected", - g_base_info_get_name ((GIBaseInfo *)field_info), - g_base_info_get_type (interface)); + /* See FIXME above + */ + GITypeTag storage_type = g_enum_info_get_storage_type ((GIEnumInfo *)interface); + switch (storage_type) + { + case GI_TYPE_TAG_INT8: + case GI_TYPE_TAG_UINT8: + G_STRUCT_MEMBER (guint8, mem, offset) = (guint8)value->v_int; + result = TRUE; + break; + case GI_TYPE_TAG_INT16: + case GI_TYPE_TAG_UINT16: + case GI_TYPE_TAG_SHORT: + case GI_TYPE_TAG_USHORT: + G_STRUCT_MEMBER (guint16, mem, offset) = (guint16)value->v_int; + result = TRUE; + break; + case GI_TYPE_TAG_INT32: + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_INT: + case GI_TYPE_TAG_UINT: + G_STRUCT_MEMBER (guint32, mem, offset) = (guint32)value->v_int; + result = TRUE; + break; + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + G_STRUCT_MEMBER (guint64, mem, offset) = (guint64)value->v_int; + result = TRUE; + break; + case GI_TYPE_TAG_LONG: + case GI_TYPE_TAG_ULONG: + G_STRUCT_MEMBER (gulong, mem, offset) = (gulong)value->v_int; + result = TRUE; + break; + default: + g_warning("Field %s: Unexpected enum storage type %s", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_type_tag_to_string (storage_type)); + break; + } break; } + break; + case GI_INFO_TYPE_VFUNC: + case GI_INFO_TYPE_CALLBACK: + g_warning("Field%s: Interface type %d should have is_pointer set", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_base_info_get_type (interface)); + break; + case GI_INFO_TYPE_INVALID: + case GI_INFO_TYPE_INTERFACE: + case GI_INFO_TYPE_FUNCTION: + case GI_INFO_TYPE_CONSTANT: + case GI_INFO_TYPE_ERROR_DOMAIN: + case GI_INFO_TYPE_VALUE: + case GI_INFO_TYPE_SIGNAL: + case GI_INFO_TYPE_PROPERTY: + case GI_INFO_TYPE_FIELD: + case GI_INFO_TYPE_ARG: + case GI_INFO_TYPE_TYPE: + case GI_INFO_TYPE_UNRESOLVED: + g_warning("Field %s: Interface type %d not expected", + g_base_info_get_name ((GIBaseInfo *)field_info), + g_base_info_get_type (interface)); + break; + } - g_base_info_unref ((GIBaseInfo *)interface); - break; - } + g_base_info_unref ((GIBaseInfo *)interface); break; } - } + break; + } + } - g_base_info_unref ((GIBaseInfo *)type_info); + g_base_info_unref ((GIBaseInfo *)type_info); - return result; + return result; } From baf36f793e3b94c95c9b69595369ac92ddbc4d65 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 19:28:35 -0300 Subject: [PATCH 315/692] [girepository] Move GIRegisteredTypeInfo out of ginfo.ch --- Makefile.am | 6 ++-- ginfo.c | 48 --------------------------- giregisteredtypeinfo.c | 75 ++++++++++++++++++++++++++++++++++++++++++ giregisteredtypeinfo.h | 51 ++++++++++++++++++++++++++++ girepository.h | 14 +------- 5 files changed, 131 insertions(+), 63 deletions(-) create mode 100644 giregisteredtypeinfo.c create mode 100644 giregisteredtypeinfo.h diff --git a/Makefile.am b/Makefile.am index 8fccc93ba..34cdfabfe 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,6 +7,7 @@ girepo_HEADERS = \ gierrordomaininfo.h \ gifieldinfo.h \ gifunctioninfo.h \ + giregisteredtypeinfo.h \ girepository.h \ girffi.h \ gitypeinfo.h \ @@ -27,15 +28,16 @@ libgirepository_1_0_la_SOURCES = \ gifunctioninfo.c \ ginfo.c \ ginvoke.c \ + giregisteredtypeinfo.c \ girepository.c \ girepository-private.h \ girffi.c \ girffi.h \ girffi-private.h \ - glib-compat.h \ gitypeinfo.c \ gitypelib.c \ - gitypelib-internal.h + gitypelib-internal.h \ + glib-compat.h libgirepository_1_0_la_CPPFLAGS = $(GIREPO_CFLAGS) libgirepository_1_0_la_LIBADD = $(GIREPO_LIBS) diff --git a/ginfo.c b/ginfo.c index 825ad5d65..5048431a0 100644 --- a/ginfo.c +++ b/ginfo.c @@ -28,54 +28,6 @@ #include "gitypelib-internal.h" #include "girepository-private.h" -/* GIRegisteredTypeInfo functions */ -const gchar * -g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->gtype_name) - return g_typelib_get_string (rinfo->typelib, blob->gtype_name); - - return NULL; -} - -const gchar * -g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->gtype_init) - return g_typelib_get_string (rinfo->typelib, blob->gtype_init); - - return NULL; -} - -GType -g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info) -{ - const char *type_init; - GType (* get_type_func) (void); - GIRealInfo *rinfo = (GIRealInfo*)info; - - type_init = g_registered_type_info_get_type_init (info); - - if (type_init == NULL) - return G_TYPE_NONE; - else if (!strcmp (type_init, "intern")) - return G_TYPE_OBJECT; - - get_type_func = NULL; - if (!g_typelib_symbol (rinfo->typelib, - type_init, - (void**) &get_type_func)) - return G_TYPE_NONE; - - return (* get_type_func) (); -} - /* GIStructInfo functions */ gint g_struct_info_get_n_fields (GIStructInfo *info) diff --git a/giregisteredtypeinfo.c b/giregisteredtypeinfo.c new file mode 100644 index 000000000..944444f01 --- /dev/null +++ b/giregisteredtypeinfo.c @@ -0,0 +1,75 @@ +/* GObject introspection: Registered Type implementation + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 "girepository-private.h" +#include "gitypelib-internal.h" +#include "girffi.h" + +const gchar * +g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->gtype_name) + return g_typelib_get_string (rinfo->typelib, blob->gtype_name); + + return NULL; +} + +const gchar * +g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->gtype_init) + return g_typelib_get_string (rinfo->typelib, blob->gtype_init); + + return NULL; +} + +GType +g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info) +{ + const char *type_init; + GType (* get_type_func) (void); + GIRealInfo *rinfo = (GIRealInfo*)info; + + type_init = g_registered_type_info_get_type_init (info); + + if (type_init == NULL) + return G_TYPE_NONE; + else if (!strcmp (type_init, "intern")) + return G_TYPE_OBJECT; + + get_type_func = NULL; + if (!g_typelib_symbol (rinfo->typelib, + type_init, + (void**) &get_type_func)) + return G_TYPE_NONE; + + return (* get_type_func) (); +} + diff --git a/giregisteredtypeinfo.h b/giregisteredtypeinfo.h new file mode 100644 index 000000000..8a6332147 --- /dev/null +++ b/giregisteredtypeinfo.h @@ -0,0 +1,51 @@ +/* GObject introspection: Registered Type + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GIREGISTEREDTYPEINFO_H__ +#define __GIREGISTEREDTYPEINFO_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +/* GIRegisteredTypeInfo */ + +#define GI_IS_REGISTERED_TYPE_INFO(info) \ + ((g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ENUM) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_INTERFACE) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_OBJECT) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_STRUCT) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_UNION)) + +const gchar * g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info); +const gchar * g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info); +GType g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info); + +G_END_DECLS + + +#endif /* __GIREGISTEREDTYPEINFO_H__ */ + diff --git a/girepository.h b/girepository.h index d03845937..47d02b59c 100644 --- a/girepository.h +++ b/girepository.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -191,19 +192,6 @@ gsize g_struct_info_get_alignment (GIStructInfo *info); gboolean g_struct_info_is_gtype_struct (GIStructInfo *info); gboolean g_struct_info_is_foreign (GIStructInfo *info); -/* GIRegisteredTypeInfo */ - -#define GI_IS_REGISTERED_TYPE_INFO(info) \ - ((g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ENUM) || \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_INTERFACE) || \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_OBJECT) || \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_STRUCT) || \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_UNION)) - -const gchar * g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info); -const gchar * g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info); -GType g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info); - /* GIObjectInfo */ #define GI_IS_OBJECT_INFO(info) \ From c223abfa36f40dd6ff32243cef1b7bd257dff465 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 19:52:12 -0300 Subject: [PATCH 316/692] [girepository] Move the rest out of ginfo.ch --- Makefile.am | 20 +- gibaseinfo.c | 1 - giconstantinfo.c | 113 ++++ giconstantinfo.h | 43 ++ gifunctioninfo.c | 28 + giinterfaceinfo.c | 256 +++++++++ giinterfaceinfo.h | 65 +++ ginfo.c | 1122 ---------------------------------------- giobjectinfo.c | 333 ++++++++++++ giobjectinfo.h | 74 +++ gipropertyinfo.c | 60 +++ gipropertyinfo.h | 42 ++ giregisteredtypeinfo.c | 2 + girepository-private.h | 8 + girepository.h | 156 +----- gisignalinfo.c | 83 +++ gisignalinfo.h | 44 ++ gistructinfo.c | 151 ++++++ gistructinfo.h | 52 ++ giunioninfo.c | 156 ++++++ giunioninfo.h | 56 ++ givfuncinfo.c | 131 +++++ givfuncinfo.h | 44 ++ 23 files changed, 1766 insertions(+), 1274 deletions(-) create mode 100644 giconstantinfo.c create mode 100644 giconstantinfo.h create mode 100644 giinterfaceinfo.c create mode 100644 giinterfaceinfo.h delete mode 100644 ginfo.c create mode 100644 giobjectinfo.c create mode 100644 giobjectinfo.h create mode 100644 gipropertyinfo.c create mode 100644 gipropertyinfo.h create mode 100644 gisignalinfo.c create mode 100644 gisignalinfo.h create mode 100644 gistructinfo.c create mode 100644 gistructinfo.h create mode 100644 giunioninfo.c create mode 100644 giunioninfo.h create mode 100644 givfuncinfo.c create mode 100644 givfuncinfo.h diff --git a/Makefile.am b/Makefile.am index 34cdfabfe..bec0cfce0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,16 +3,23 @@ girepo_HEADERS = \ giarginfo.h \ gibaseinfo.h \ gicallableinfo.h \ + giconstantinfo.h \ gienuminfo.h \ gierrordomaininfo.h \ gifieldinfo.h \ gifunctioninfo.h \ + giinterfaceinfo.h \ + giobjectinfo.h \ + gipropertyinfo.h \ giregisteredtypeinfo.h \ girepository.h \ girffi.h \ + gisignalinfo.h \ gitypeinfo.h \ gitypelib.h \ - gitypes.h + gitypes.h \ + giunioninfo.h \ + givfuncinfo.h lib_LTLIBRARIES = libgirepository-1.0.la noinst_LTLIBRARIES = libgirepository-parser.la @@ -22,22 +29,29 @@ libgirepository_1_0_la_SOURCES = \ giarginfo.c \ gibaseinfo.c \ gicallableinfo.c \ + giconstantinfo.c \ gienuminfo.c \ gierrordomaininfo.c \ gifieldinfo.c \ gifunctioninfo.c \ - ginfo.c \ ginvoke.c \ + giinterfaceinfo.c \ + giobjectinfo.c \ + gipropertyinfo.c \ giregisteredtypeinfo.c \ girepository.c \ girepository-private.h \ girffi.c \ girffi.h \ girffi-private.h \ + gisignalinfo.c \ + gistructinfo.c \ gitypeinfo.c \ gitypelib.c \ gitypelib-internal.h \ - glib-compat.h + glib-compat.h \ + giunioninfo.c \ + givfuncinfo.c libgirepository_1_0_la_CPPFLAGS = $(GIREPO_CFLAGS) libgirepository_1_0_la_LIBADD = $(GIREPO_LIBS) diff --git a/gibaseinfo.c b/gibaseinfo.c index 10e5d7c38..5cb153234 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -149,7 +149,6 @@ _g_type_info_init (GIBaseInfo *info, (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset); } - /* GIBaseInfo functions */ /** diff --git a/giconstantinfo.c b/giconstantinfo.c new file mode 100644 index 000000000..72cc04368 --- /dev/null +++ b/giconstantinfo.c @@ -0,0 +1,113 @@ +/* GObject introspection: Constant implementation + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 "girepository-private.h" +#include "gitypelib-internal.h" +#include "girffi.h" + +GITypeInfo * +g_constant_info_get_type (GIConstantInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + + return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 8); +} + +gint +g_constant_info_get_value (GIConstantInfo *info, + GArgument *value) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ConstantBlob *blob = (ConstantBlob *)&rinfo->typelib->data[rinfo->offset]; + + /* FIXME non-basic types ? */ + if (blob->type.flags.reserved == 0 && blob->type.flags.reserved2 == 0) + { + if (blob->type.flags.pointer) + value->v_pointer = g_memdup (&rinfo->typelib->data[blob->offset], blob->size); + else + { + switch (blob->type.flags.tag) + { + case GI_TYPE_TAG_BOOLEAN: + value->v_boolean = *(gboolean*)&rinfo->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_INT8: + value->v_int8 = *(gint8*)&rinfo->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_UINT8: + value->v_uint8 = *(guint8*)&rinfo->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_INT16: + value->v_int16 = *(gint16*)&rinfo->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_UINT16: + value->v_uint16 = *(guint16*)&rinfo->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_INT32: + value->v_int32 = *(gint32*)&rinfo->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_UINT32: + value->v_uint32 = *(guint32*)&rinfo->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_INT64: + value->v_int64 = *(gint64*)&rinfo->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_UINT64: + value->v_uint64 = *(guint64*)&rinfo->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_FLOAT: + value->v_float = *(gfloat*)&rinfo->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_DOUBLE: + value->v_double = *(gdouble*)&rinfo->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_TIME_T: + value->v_long = *(long*)&rinfo->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_SHORT: + value->v_short = *(gshort*)&rinfo->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_USHORT: + value->v_ushort = *(gushort*)&rinfo->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_INT: + value->v_int = *(gint*)&rinfo->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_UINT: + value->v_uint = *(guint*)&rinfo->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_LONG: + value->v_long = *(glong*)&rinfo->typelib->data[blob->offset]; + break; + case GI_TYPE_TAG_ULONG: + value->v_ulong = *(gulong*)&rinfo->typelib->data[blob->offset]; + break; + } + } + } + + return blob->size; +} + diff --git a/giconstantinfo.h b/giconstantinfo.h new file mode 100644 index 000000000..eea0f66d0 --- /dev/null +++ b/giconstantinfo.h @@ -0,0 +1,43 @@ +/* GObject introspection: Constant + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GICONSTANTINFO_H__ +#define __GICONSTANTINFO_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define GI_IS_CONSTANT_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_CONSTANT) + +GITypeInfo * g_constant_info_get_type (GIConstantInfo *info); +gint g_constant_info_get_value(GIConstantInfo *info, + GArgument *value); +G_END_DECLS + + +#endif /* __GICONSTANTINFO_H__ */ + diff --git a/gifunctioninfo.c b/gifunctioninfo.c index 1bda54df8..33852801f 100644 --- a/gifunctioninfo.c +++ b/gifunctioninfo.c @@ -19,6 +19,8 @@ * Boston, MA 02111-1307, USA. */ +#include + #include #include @@ -39,6 +41,32 @@ * other metadata. */ +GIFunctionInfo * +_g_base_info_find_method (GIBaseInfo *base, + guint32 offset, + gint n_methods, + const gchar *name) +{ + /* FIXME hash */ + GIRealInfo *rinfo = (GIRealInfo*)base; + Header *header = (Header *)rinfo->typelib->data; + gint i; + + for (i = 0; i < n_methods; i++) + { + FunctionBlob *fblob = (FunctionBlob *)&rinfo->typelib->data[offset]; + const gchar *fname = (const gchar *)&rinfo->typelib->data[fblob->name]; + + if (strcmp (name, fname) == 0) + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, + rinfo->typelib, offset); + + offset += header->function_blob_size; + } + + return NULL; +} + /** * g_function_info_get_symbol: * @info: a #GIFunctionInfo diff --git a/giinterfaceinfo.c b/giinterfaceinfo.c new file mode 100644 index 000000000..070343ddf --- /dev/null +++ b/giinterfaceinfo.c @@ -0,0 +1,256 @@ +/* GObject introspection: Interface implementation + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 "girepository-private.h" +#include "gitypelib-internal.h" +#include "girffi.h" + +gint +g_interface_info_get_n_prerequisites (GIInterfaceInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_prerequisites; +} + +GIBaseInfo * +g_interface_info_get_prerequisite (GIInterfaceInfo *info, + gint n) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + + return _g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->prerequisites[n]); +} + + +gint +g_interface_info_get_n_properties (GIInterfaceInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_properties; +} + +GIPropertyInfo * +g_interface_info_get_property (GIInterfaceInfo *info, + gint n) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->interface_blob_size + + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + + n * header->property_blob_size; + + return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info, + rinfo->typelib, offset); +} + +gint +g_interface_info_get_n_methods (GIInterfaceInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_methods; +} + +GIFunctionInfo * +g_interface_info_get_method (GIInterfaceInfo *info, + gint n) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->interface_blob_size + + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + + blob->n_properties * header->property_blob_size + + n * header->function_blob_size; + + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, + rinfo->typelib, offset); +} + +GIFunctionInfo * +g_interface_info_find_method (GIInterfaceInfo *info, + const gchar *name) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->interface_blob_size + + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + + blob->n_properties * header->property_blob_size; + + return _g_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_methods, name); +} + +gint +g_interface_info_get_n_signals (GIInterfaceInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_signals; +} + +GISignalInfo * +g_interface_info_get_signal (GIInterfaceInfo *info, + gint n) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->interface_blob_size + + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + + n * header->signal_blob_size; + + return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info, + rinfo->typelib, offset); +} + +gint +g_interface_info_get_n_vfuncs (GIInterfaceInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_vfuncs; +} + +GIVFuncInfo * +g_interface_info_get_vfunc (GIInterfaceInfo *info, + gint n) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->interface_blob_size + + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + + blob->n_signals * header->signal_blob_size + + n * header->vfunc_blob_size; + + return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info, + rinfo->typelib, offset); +} + +/** + * g_interface_info_find_vfunc: + * @info: a #GIObjectInfo + * @name: The name of a virtual function to find. + * + * Locate a virtual function slot with name @name. See the documentation + * for g_object_info_find_vfunc() for more information on virtuals. + * + * Returns: (transfer full): the #GIVFuncInfo, or %NULL. Free it with + * g_base_info_unref() when done. + */ +GIVFuncInfo * +g_interface_info_find_vfunc (GIInterfaceInfo *info, + const gchar *name) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->interface_blob_size + + (blob->n_prerequisites + blob->n_prerequisites % 2) * 2 + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + + blob->n_signals * header->signal_blob_size; + + return _g_base_info_find_vfunc (rinfo, offset, blob->n_vfuncs, name); +} + +gint +g_interface_info_get_n_constants (GIInterfaceInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_constants; +} + +GIConstantInfo * +g_interface_info_get_constant (GIInterfaceInfo *info, + gint n) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->interface_blob_size + + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + + blob->n_signals * header->signal_blob_size + + blob->n_vfuncs * header->vfunc_blob_size + + n * header->constant_blob_size; + + return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, + rinfo->typelib, offset); +} + +/** + * g_interface_info_get_iface_struct: + * @info: a #GIInterfaceInfo + * + * Returns the layout C structure associated with this #GInterface. + * + * Returns: (transfer full): the #GIStructInfo or %NULL. Free it with + * g_base_info_unref() when done. + */ +GIStructInfo * +g_interface_info_get_iface_struct (GIInterfaceInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->gtype_struct) + return (GIStructInfo *) _g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->gtype_struct); + else + return NULL; +} + diff --git a/giinterfaceinfo.h b/giinterfaceinfo.h new file mode 100644 index 000000000..4f4c05c9f --- /dev/null +++ b/giinterfaceinfo.h @@ -0,0 +1,65 @@ +/* GObject introspection: Interface + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GIINTERFACEINFO_H__ +#define __GIINTERFACEINFO_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define GI_IS_INTERFACE_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_INTERFACE) + +gint g_interface_info_get_n_prerequisites (GIInterfaceInfo *info); +GIBaseInfo * g_interface_info_get_prerequisite (GIInterfaceInfo *info, + gint n); +gint g_interface_info_get_n_properties (GIInterfaceInfo *info); +GIPropertyInfo * g_interface_info_get_property (GIInterfaceInfo *info, + gint n); +gint g_interface_info_get_n_methods (GIInterfaceInfo *info); +GIFunctionInfo * g_interface_info_get_method (GIInterfaceInfo *info, + gint n); +GIFunctionInfo * g_interface_info_find_method (GIInterfaceInfo *info, + const gchar *name); +gint g_interface_info_get_n_signals (GIInterfaceInfo *info); +GISignalInfo * g_interface_info_get_signal (GIInterfaceInfo *info, + gint n); +gint g_interface_info_get_n_vfuncs (GIInterfaceInfo *info); +GIVFuncInfo * g_interface_info_get_vfunc (GIInterfaceInfo *info, + gint n); +GIVFuncInfo * g_interface_info_find_vfunc (GIInterfaceInfo *info, + const gchar *name); +gint g_interface_info_get_n_constants (GIInterfaceInfo *info); +GIConstantInfo * g_interface_info_get_constant (GIInterfaceInfo *info, + gint n); + +GIStructInfo * g_interface_info_get_iface_struct (GIInterfaceInfo *info); + +G_END_DECLS + + +#endif /* __GIINTERFACEINFO_H__ */ + diff --git a/ginfo.c b/ginfo.c deleted file mode 100644 index 5048431a0..000000000 --- a/ginfo.c +++ /dev/null @@ -1,1122 +0,0 @@ -/* GObject introspection: Repository implementation - * - * Copyright (C) 2005 Matthias Clasen - * Copyright (C) 2008,2009 Red Hat, Inc. - * - * 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 - -#include "gitypelib-internal.h" -#include "girepository-private.h" - -/* GIStructInfo functions */ -gint -g_struct_info_get_n_fields (GIStructInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_fields; -} - -static gint32 -g_struct_get_field_offset (GIStructInfo *info, - gint n) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - guint32 offset = rinfo->offset + header->struct_blob_size; - gint i; - FieldBlob *field_blob; - - for (i = 0; i < n; i++) - { - field_blob = (FieldBlob *)&rinfo->typelib->data[offset]; - offset += header->field_blob_size; - if (field_blob->has_embedded_type) - offset += header->callback_blob_size; - } - - return offset; -} - -GIFieldInfo * -g_struct_info_get_field (GIStructInfo *info, - gint n) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - - return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, - g_struct_get_field_offset (info, n)); -} - -gint -g_struct_info_get_n_methods (GIStructInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_methods; -} - -GIFunctionInfo * -g_struct_info_get_method (GIStructInfo *info, - gint n) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; - Header *header = (Header *)rinfo->typelib->data; - gint offset; - - offset = g_struct_get_field_offset (info, blob->n_fields) + n * header->function_blob_size; - return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, - rinfo->typelib, offset); -} - -static GIFunctionInfo * -find_method (GIBaseInfo *base, - guint32 offset, - gint n_methods, - const gchar *name) -{ - /* FIXME hash */ - GIRealInfo *rinfo = (GIRealInfo*)base; - Header *header = (Header *)rinfo->typelib->data; - gint i; - - for (i = 0; i < n_methods; i++) - { - FunctionBlob *fblob = (FunctionBlob *)&rinfo->typelib->data[offset]; - const gchar *fname = (const gchar *)&rinfo->typelib->data[fblob->name]; - - if (strcmp (name, fname) == 0) - return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, - rinfo->typelib, offset); - - offset += header->function_blob_size; - } - - return NULL; -} - -GIFunctionInfo * -g_struct_info_find_method (GIStructInfo *info, - const gchar *name) -{ - gint offset; - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->struct_blob_size - + blob->n_fields * header->field_blob_size; - - return find_method ((GIBaseInfo*)info, offset, blob->n_methods, name); -} - -gsize -g_struct_info_get_size (GIStructInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->size; -} - -gsize -g_struct_info_get_alignment (GIStructInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->alignment; -} - -gboolean -g_struct_info_is_foreign (GIStructInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->foreign; -} - -/** - * g_struct_info_is_gtype_struct: - * @info: a #GIStructInfo - * - * Return true if this structure represents the "class structure" for some - * #GObject or #GInterface. This function is mainly useful to hide this kind of structure - * from generated public APIs. - * - * Returns: %TRUE if this is a class struct, %FALSE otherwise - */ -gboolean -g_struct_info_is_gtype_struct (GIStructInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->is_gtype_struct; -} - -/* GIObjectInfo functions */ -GIObjectInfo * -g_object_info_get_parent (GIObjectInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->parent) - return (GIObjectInfo *) _g_info_from_entry (rinfo->repository, - rinfo->typelib, blob->parent); - else - return NULL; -} - -gboolean -g_object_info_get_abstract (GIObjectInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - return blob->abstract != 0; -} - -const gchar * -g_object_info_get_type_name (GIObjectInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - return g_typelib_get_string (rinfo->typelib, blob->gtype_name); -} - -const gchar * -g_object_info_get_type_init (GIObjectInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - return g_typelib_get_string (rinfo->typelib, blob->gtype_init); -} - -gint -g_object_info_get_n_interfaces (GIObjectInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_interfaces; -} - -GIInterfaceInfo * -g_object_info_get_interface (GIObjectInfo *info, - gint n) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - return (GIInterfaceInfo *) _g_info_from_entry (rinfo->repository, - rinfo->typelib, blob->interfaces[n]); -} - -gint -g_object_info_get_n_fields (GIObjectInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_fields; -} - -GIFieldInfo * -g_object_info_get_field (GIObjectInfo *info, - gint n) -{ - gint offset; - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->object_blob_size - + (blob->n_interfaces + blob->n_interfaces % 2) * 2 - + n * header->field_blob_size; - - return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, offset); -} - -gint -g_object_info_get_n_properties (GIObjectInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_properties; -} - -GIPropertyInfo * -g_object_info_get_property (GIObjectInfo *info, - gint n) -{ - gint offset; - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->object_blob_size - + (blob->n_interfaces + blob->n_interfaces % 2) * 2 - + blob->n_fields * header->field_blob_size - + n * header->property_blob_size; - - return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info, - rinfo->typelib, offset); -} - -gint -g_object_info_get_n_methods (GIObjectInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_methods; -} - -GIFunctionInfo * -g_object_info_get_method (GIObjectInfo *info, - gint n) -{ - gint offset; - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->object_blob_size - + (blob->n_interfaces + blob->n_interfaces % 2) * 2 - + blob->n_fields * header->field_blob_size - + blob->n_properties * header->property_blob_size - + n * header->function_blob_size; - - return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, - rinfo->typelib, offset); -} - -GIFunctionInfo * -g_object_info_find_method (GIObjectInfo *info, - const gchar *name) -{ - gint offset; - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->object_blob_size - + (blob->n_interfaces + blob->n_interfaces % 2) * 2 - + blob->n_fields * header->field_blob_size + - + blob->n_properties * header->property_blob_size; - - return find_method ((GIBaseInfo*)info, offset, blob->n_methods, name); -} - -gint -g_object_info_get_n_signals (GIObjectInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_signals; -} - -GISignalInfo * -g_object_info_get_signal (GIObjectInfo *info, - gint n) -{ - gint offset; - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->object_blob_size - + (blob->n_interfaces + blob->n_interfaces % 2) * 2 - + blob->n_fields * header->field_blob_size - + blob->n_properties * header->property_blob_size - + blob->n_methods * header->function_blob_size - + n * header->signal_blob_size; - - return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info, - rinfo->typelib, offset); -} - -gint -g_object_info_get_n_vfuncs (GIObjectInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_vfuncs; -} - -GIVFuncInfo * -g_object_info_get_vfunc (GIObjectInfo *info, - gint n) -{ - gint offset; - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->object_blob_size - + (blob->n_interfaces + blob->n_interfaces % 2) * 2 - + blob->n_fields * header->field_blob_size - + blob->n_properties * header->property_blob_size - + blob->n_methods * header->function_blob_size - + blob->n_signals * header->signal_blob_size - + n * header->vfunc_blob_size; - - return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info, - rinfo->typelib, offset); -} - -static GIVFuncInfo * -find_vfunc (GIRealInfo *rinfo, - guint32 offset, - gint n_vfuncs, - const gchar *name) -{ - /* FIXME hash */ - Header *header = (Header *)rinfo->typelib->data; - gint i; - - for (i = 0; i < n_vfuncs; i++) - { - VFuncBlob *fblob = (VFuncBlob *)&rinfo->typelib->data[offset]; - const gchar *fname = (const gchar *)&rinfo->typelib->data[fblob->name]; - - if (strcmp (name, fname) == 0) - return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*) rinfo, - rinfo->typelib, offset); - - offset += header->vfunc_blob_size; - } - - return NULL; -} - -/** - * g_object_info_find_vfunc: - * @info: a #GIObjectInfo - * @name: The name of a virtual function to find. - * - * Locate a virtual function slot with name @name. Note that the namespace - * for virtuals is distinct from that of methods; there may or may not be - * a concrete method associated for a virtual. If there is one, it may - * be retrieved using g_vfunc_info_get_invoker(), otherwise %NULL will be - * returned. - * See the documentation for g_vfunc_info_get_invoker() for more - * information on invoking virtuals. - * - * Returns: (transfer full): the #GIVFuncInfo, or %NULL. Free it with - * g_base_info_unref() when done. - */ -GIVFuncInfo * -g_object_info_find_vfunc (GIObjectInfo *info, - const gchar *name) -{ - gint offset; - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->object_blob_size - + (blob->n_interfaces + blob->n_interfaces % 2) * 2 - + blob->n_fields * header->field_blob_size - + blob->n_properties * header->property_blob_size - + blob->n_methods * header->function_blob_size - + blob->n_signals * header->signal_blob_size; - - return find_vfunc (rinfo, offset, blob->n_vfuncs, name); -} - -gint -g_object_info_get_n_constants (GIObjectInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_constants; -} - -GIConstantInfo * -g_object_info_get_constant (GIObjectInfo *info, - gint n) -{ - gint offset; - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->object_blob_size - + (blob->n_interfaces + blob->n_interfaces % 2) * 2 - + blob->n_fields * header->field_blob_size - + blob->n_properties * header->property_blob_size - + blob->n_methods * header->function_blob_size - + blob->n_signals * header->signal_blob_size - + blob->n_vfuncs * header->vfunc_blob_size - + n * header->constant_blob_size; - - return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, - rinfo->typelib, offset); -} - -/** - * g_object_info_get_class_struct: - * @info: a #GIObjectInfo - * - * Every #GObject has two structures; an instance structure and a class - * structure. This function returns the metadata for the class structure. - * - * Returns: (transfer full): the #GIStructInfo or %NULL. Free with - * g_base_info_unref() when done. - */ -GIStructInfo * -g_object_info_get_class_struct (GIObjectInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->gtype_struct) - return (GIStructInfo *) _g_info_from_entry (rinfo->repository, - rinfo->typelib, blob->gtype_struct); - else - return NULL; -} - -/* GIInterfaceInfo functions */ -gint -g_interface_info_get_n_prerequisites (GIInterfaceInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_prerequisites; -} - -GIBaseInfo * -g_interface_info_get_prerequisite (GIInterfaceInfo *info, - gint n) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - - return _g_info_from_entry (rinfo->repository, - rinfo->typelib, blob->prerequisites[n]); -} - - -gint -g_interface_info_get_n_properties (GIInterfaceInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_properties; -} - -GIPropertyInfo * -g_interface_info_get_property (GIInterfaceInfo *info, - gint n) -{ - gint offset; - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->interface_blob_size - + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 - + n * header->property_blob_size; - - return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info, - rinfo->typelib, offset); -} - -gint -g_interface_info_get_n_methods (GIInterfaceInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_methods; -} - -GIFunctionInfo * -g_interface_info_get_method (GIInterfaceInfo *info, - gint n) -{ - gint offset; - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->interface_blob_size - + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 - + blob->n_properties * header->property_blob_size - + n * header->function_blob_size; - - return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, - rinfo->typelib, offset); -} - -GIFunctionInfo * -g_interface_info_find_method (GIInterfaceInfo *info, - const gchar *name) -{ - gint offset; - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->interface_blob_size - + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 - + blob->n_properties * header->property_blob_size; - - return find_method ((GIBaseInfo*)info, offset, blob->n_methods, name); -} - -gint -g_interface_info_get_n_signals (GIInterfaceInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_signals; -} - -GISignalInfo * -g_interface_info_get_signal (GIInterfaceInfo *info, - gint n) -{ - gint offset; - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->interface_blob_size - + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 - + blob->n_properties * header->property_blob_size - + blob->n_methods * header->function_blob_size - + n * header->signal_blob_size; - - return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info, - rinfo->typelib, offset); -} - -gint -g_interface_info_get_n_vfuncs (GIInterfaceInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_vfuncs; -} - -GIVFuncInfo * -g_interface_info_get_vfunc (GIInterfaceInfo *info, - gint n) -{ - gint offset; - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->interface_blob_size - + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 - + blob->n_properties * header->property_blob_size - + blob->n_methods * header->function_blob_size - + blob->n_signals * header->signal_blob_size - + n * header->vfunc_blob_size; - - return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info, - rinfo->typelib, offset); -} - -/** - * g_interface_info_find_vfunc: - * @info: a #GIObjectInfo - * @name: The name of a virtual function to find. - * - * Locate a virtual function slot with name @name. See the documentation - * for g_object_info_find_vfunc() for more information on virtuals. - * - * Returns: (transfer full): the #GIVFuncInfo, or %NULL. Free it with - * g_base_info_unref() when done. - */ -GIVFuncInfo * -g_interface_info_find_vfunc (GIInterfaceInfo *info, - const gchar *name) -{ - gint offset; - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->interface_blob_size - + (blob->n_prerequisites + blob->n_prerequisites % 2) * 2 - + blob->n_properties * header->property_blob_size - + blob->n_methods * header->function_blob_size - + blob->n_signals * header->signal_blob_size; - - return find_vfunc (rinfo, offset, blob->n_vfuncs, name); -} - -gint -g_interface_info_get_n_constants (GIInterfaceInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_constants; -} - -GIConstantInfo * -g_interface_info_get_constant (GIInterfaceInfo *info, - gint n) -{ - gint offset; - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->interface_blob_size - + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 - + blob->n_properties * header->property_blob_size - + blob->n_methods * header->function_blob_size - + blob->n_signals * header->signal_blob_size - + blob->n_vfuncs * header->vfunc_blob_size - + n * header->constant_blob_size; - - return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, - rinfo->typelib, offset); -} - -/** - * g_interface_info_get_iface_struct: - * @info: a #GIInterfaceInfo - * - * Returns the layout C structure associated with this #GInterface. - * - * Returns: (transfer full): the #GIStructInfo or %NULL. Free it with - * g_base_info_unref() when done. - */ -GIStructInfo * -g_interface_info_get_iface_struct (GIInterfaceInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->gtype_struct) - return (GIStructInfo *) _g_info_from_entry (rinfo->repository, - rinfo->typelib, blob->gtype_struct); - else - return NULL; -} - -/* GIPropertyInfo functions */ -GParamFlags -g_property_info_get_flags (GIPropertyInfo *info) -{ - GParamFlags flags; - GIRealInfo *rinfo = (GIRealInfo *)info; - PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset]; - - flags = 0; - - if (blob->readable) - flags = flags | G_PARAM_READABLE; - - if (blob->writable) - flags = flags | G_PARAM_WRITABLE; - - if (blob->construct) - flags = flags | G_PARAM_CONSTRUCT; - - if (blob->construct_only) - flags = flags | G_PARAM_CONSTRUCT_ONLY; - - return flags; -} - -GITypeInfo * -g_property_info_get_type (GIPropertyInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - - return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (PropertyBlob, type)); -} - - -/* GISignalInfo functions */ -GSignalFlags -g_signal_info_get_flags (GISignalInfo *info) -{ - GSignalFlags flags; - - GIRealInfo *rinfo = (GIRealInfo *)info; - SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; - - flags = 0; - - if (blob->run_first) - flags = flags | G_SIGNAL_RUN_FIRST; - - if (blob->run_last) - flags = flags | G_SIGNAL_RUN_LAST; - - if (blob->run_cleanup) - flags = flags | G_SIGNAL_RUN_CLEANUP; - - if (blob->no_recurse) - flags = flags | G_SIGNAL_NO_RECURSE; - - if (blob->detailed) - flags = flags | G_SIGNAL_DETAILED; - - if (blob->action) - flags = flags | G_SIGNAL_ACTION; - - if (blob->no_hooks) - flags = flags | G_SIGNAL_NO_HOOKS; - - return flags; -} - -GIVFuncInfo * -g_signal_info_get_class_closure (GISignalInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->has_class_closure) - return g_interface_info_get_vfunc ((GIInterfaceInfo *)rinfo->container, blob->class_closure); - - return NULL; -} - -gboolean -g_signal_info_true_stops_emit (GISignalInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->true_stops_emit; -} - -/* GIVFuncInfo functions */ -GIVFuncInfoFlags -g_vfunc_info_get_flags (GIVFuncInfo *info) -{ - GIVFuncInfoFlags flags; - - GIRealInfo *rinfo = (GIRealInfo *)info; - VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; - - flags = 0; - - if (blob->must_chain_up) - flags = flags | GI_VFUNC_MUST_CHAIN_UP; - - if (blob->must_be_implemented) - flags = flags | GI_VFUNC_MUST_OVERRIDE; - - if (blob->must_not_be_implemented) - flags = flags | GI_VFUNC_MUST_NOT_OVERRIDE; - - return flags; -} - -gint -g_vfunc_info_get_offset (GIVFuncInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->struct_offset; -} - -GISignalInfo * -g_vfunc_info_get_signal (GIVFuncInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->class_closure) - return g_interface_info_get_signal ((GIInterfaceInfo *)rinfo->container, blob->signal); - - return NULL; -} - -/** - * g_vfunc_info_get_invoker: - * @info: a #GIVFuncInfo - * - * If this virtual function has an associated invoker method, this - * method will return it. An invoker method is a C entry point. - * - * Not all virtuals will have invokers. - * - * Returns: (transfer full): the #GIVFuncInfo or %NULL. Free it with - * g_base_info_unref() when done. - */ -GIFunctionInfo * -g_vfunc_info_get_invoker (GIVFuncInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; - GIBaseInfo *container = rinfo->container; - GIInfoType parent_type; - - /* 1023 = 0x3ff is the maximum of the 10 bits for invoker index */ - if (blob->invoker == 1023) - return NULL; - - parent_type = g_base_info_get_type (container); - if (parent_type == GI_INFO_TYPE_OBJECT) - return g_object_info_get_method ((GIObjectInfo*)container, blob->invoker); - else if (parent_type == GI_INFO_TYPE_INTERFACE) - return g_interface_info_get_method ((GIInterfaceInfo*)container, blob->invoker); - else - g_assert_not_reached (); -} - -/* GIConstantInfo functions */ -GITypeInfo * -g_constant_info_get_type (GIConstantInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - - return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 8); -} - -gint -g_constant_info_get_value (GIConstantInfo *info, - GArgument *value) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ConstantBlob *blob = (ConstantBlob *)&rinfo->typelib->data[rinfo->offset]; - - /* FIXME non-basic types ? */ - if (blob->type.flags.reserved == 0 && blob->type.flags.reserved2 == 0) - { - if (blob->type.flags.pointer) - value->v_pointer = g_memdup (&rinfo->typelib->data[blob->offset], blob->size); - else - { - switch (blob->type.flags.tag) - { - case GI_TYPE_TAG_BOOLEAN: - value->v_boolean = *(gboolean*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_INT8: - value->v_int8 = *(gint8*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_UINT8: - value->v_uint8 = *(guint8*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_INT16: - value->v_int16 = *(gint16*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_UINT16: - value->v_uint16 = *(guint16*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_INT32: - value->v_int32 = *(gint32*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_UINT32: - value->v_uint32 = *(guint32*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_INT64: - value->v_int64 = *(gint64*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_UINT64: - value->v_uint64 = *(guint64*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_FLOAT: - value->v_float = *(gfloat*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_DOUBLE: - value->v_double = *(gdouble*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_TIME_T: - value->v_long = *(long*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_SHORT: - value->v_short = *(gshort*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_USHORT: - value->v_ushort = *(gushort*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_INT: - value->v_int = *(gint*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_UINT: - value->v_uint = *(guint*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_LONG: - value->v_long = *(glong*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_ULONG: - value->v_ulong = *(gulong*)&rinfo->typelib->data[blob->offset]; - break; - } - } - } - - return blob->size; -} - -/* GIUnionInfo functions */ -gint -g_union_info_get_n_fields (GIUnionInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_fields; -} - -GIFieldInfo * -g_union_info_get_field (GIUnionInfo *info, - gint n) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - - return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, - rinfo->offset + header->union_blob_size + - n * header->field_blob_size); -} - -gint -g_union_info_get_n_methods (GIUnionInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->n_functions; -} - -GIFunctionInfo * -g_union_info_get_method (GIUnionInfo *info, - gint n) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; - Header *header = (Header *)rinfo->typelib->data; - gint offset; - - offset = rinfo->offset + header->union_blob_size - + blob->n_fields * header->field_blob_size - + n * header->function_blob_size; - return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, - rinfo->typelib, offset); -} - -gboolean -g_union_info_is_discriminated (GIUnionInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->discriminated; -} - -gint -g_union_info_get_discriminator_offset (GIUnionInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->discriminator_offset; -} - -GITypeInfo * -g_union_info_get_discriminator_type (GIUnionInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - - return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 24); -} - -GIConstantInfo * -g_union_info_get_discriminator (GIUnionInfo *info, - gint n) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->discriminated) - { - Header *header = (Header *)rinfo->typelib->data; - gint offset; - - offset = rinfo->offset + header->union_blob_size - + blob->n_fields * header->field_blob_size - + blob->n_functions * header->function_blob_size - + n * header->constant_blob_size; - - return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, - rinfo->typelib, offset); - } - - return NULL; -} - -GIFunctionInfo * -g_union_info_find_method (GIUnionInfo *info, - const gchar *name) -{ - gint offset; - GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->union_blob_size - + blob->n_fields * header->field_blob_size; - - return find_method ((GIBaseInfo*)info, offset, blob->n_functions, name); -} - -gsize -g_union_info_get_size (GIUnionInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->size; -} - -gsize -g_union_info_get_alignment (GIUnionInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; - - return blob->alignment; -} diff --git a/giobjectinfo.c b/giobjectinfo.c new file mode 100644 index 000000000..ac7de59e7 --- /dev/null +++ b/giobjectinfo.c @@ -0,0 +1,333 @@ +/* GObject introspection: Object implementation + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 "girepository-private.h" +#include "gitypelib-internal.h" +#include "girffi.h" + +/* GIObjectInfo functions */ +GIObjectInfo * +g_object_info_get_parent (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->parent) + return (GIObjectInfo *) _g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->parent); + else + return NULL; +} + +gboolean +g_object_info_get_abstract (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + return blob->abstract != 0; +} + +const gchar * +g_object_info_get_type_name (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + return g_typelib_get_string (rinfo->typelib, blob->gtype_name); +} + +const gchar * +g_object_info_get_type_init (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + return g_typelib_get_string (rinfo->typelib, blob->gtype_init); +} + +gint +g_object_info_get_n_interfaces (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_interfaces; +} + +GIInterfaceInfo * +g_object_info_get_interface (GIObjectInfo *info, + gint n) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + return (GIInterfaceInfo *) _g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->interfaces[n]); +} + +gint +g_object_info_get_n_fields (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_fields; +} + +GIFieldInfo * +g_object_info_get_field (GIObjectInfo *info, + gint n) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + n * header->field_blob_size; + + return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, offset); +} + +gint +g_object_info_get_n_properties (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_properties; +} + +GIPropertyInfo * +g_object_info_get_property (GIObjectInfo *info, + gint n) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + n * header->property_blob_size; + + return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info, + rinfo->typelib, offset); +} + +gint +g_object_info_get_n_methods (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_methods; +} + +GIFunctionInfo * +g_object_info_get_method (GIObjectInfo *info, + gint n) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + blob->n_properties * header->property_blob_size + + n * header->function_blob_size; + + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, + rinfo->typelib, offset); +} + +GIFunctionInfo * +g_object_info_find_method (GIObjectInfo *info, + const gchar *name) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + + blob->n_properties * header->property_blob_size; + + return _g_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_methods, name); +} + +gint +g_object_info_get_n_signals (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_signals; +} + +GISignalInfo * +g_object_info_get_signal (GIObjectInfo *info, + gint n) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + + n * header->signal_blob_size; + + return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info, + rinfo->typelib, offset); +} + +gint +g_object_info_get_n_vfuncs (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_vfuncs; +} + +GIVFuncInfo * +g_object_info_get_vfunc (GIObjectInfo *info, + gint n) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + + blob->n_signals * header->signal_blob_size + + n * header->vfunc_blob_size; + + return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info, + rinfo->typelib, offset); +} + +/** + * g_object_info_find_vfunc: + * @info: a #GIObjectInfo + * @name: The name of a virtual function to find. + * + * Locate a virtual function slot with name @name. Note that the namespace + * for virtuals is distinct from that of methods; there may or may not be + * a concrete method associated for a virtual. If there is one, it may + * be retrieved using g_vfunc_info_get_invoker(), otherwise %NULL will be + * returned. + * See the documentation for g_vfunc_info_get_invoker() for more + * information on invoking virtuals. + * + * Returns: (transfer full): the #GIVFuncInfo, or %NULL. Free it with + * g_base_info_unref() when done. + */ +GIVFuncInfo * +g_object_info_find_vfunc (GIObjectInfo *info, + const gchar *name) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + + blob->n_signals * header->signal_blob_size; + + return _g_base_info_find_vfunc (rinfo, offset, blob->n_vfuncs, name); +} + +gint +g_object_info_get_n_constants (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_constants; +} + +GIConstantInfo * +g_object_info_get_constant (GIObjectInfo *info, + gint n) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + blob->n_properties * header->property_blob_size + + blob->n_methods * header->function_blob_size + + blob->n_signals * header->signal_blob_size + + blob->n_vfuncs * header->vfunc_blob_size + + n * header->constant_blob_size; + + return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, + rinfo->typelib, offset); +} + +/** + * g_object_info_get_class_struct: + * @info: a #GIObjectInfo + * + * Every #GObject has two structures; an instance structure and a class + * structure. This function returns the metadata for the class structure. + * + * Returns: (transfer full): the #GIStructInfo or %NULL. Free with + * g_base_info_unref() when done. + */ +GIStructInfo * +g_object_info_get_class_struct (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->gtype_struct) + return (GIStructInfo *) _g_info_from_entry (rinfo->repository, + rinfo->typelib, blob->gtype_struct); + else + return NULL; +} + diff --git a/giobjectinfo.h b/giobjectinfo.h new file mode 100644 index 000000000..50a85b7a2 --- /dev/null +++ b/giobjectinfo.h @@ -0,0 +1,74 @@ +/* GObject introspection: Object + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GIOBJECTINFO_H__ +#define __GIOBJECTINFO_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/* GIObjectInfo */ + +#define GI_IS_OBJECT_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_OBJECT) + +const gchar * g_object_info_get_type_name (GIObjectInfo *info); +const gchar * g_object_info_get_type_init (GIObjectInfo *info); +gboolean g_object_info_get_abstract (GIObjectInfo *info); +GIObjectInfo * g_object_info_get_parent (GIObjectInfo *info); +gint g_object_info_get_n_interfaces (GIObjectInfo *info); +GIInterfaceInfo * g_object_info_get_interface (GIObjectInfo *info, + gint n); +gint g_object_info_get_n_fields (GIObjectInfo *info); +GIFieldInfo * g_object_info_get_field (GIObjectInfo *info, + gint n); +gint g_object_info_get_n_properties (GIObjectInfo *info); +GIPropertyInfo * g_object_info_get_property (GIObjectInfo *info, + gint n); +gint g_object_info_get_n_methods (GIObjectInfo *info); +GIFunctionInfo * g_object_info_get_method (GIObjectInfo *info, + gint n); +GIFunctionInfo * g_object_info_find_method (GIObjectInfo *info, + const gchar *name); +gint g_object_info_get_n_signals (GIObjectInfo *info); +GISignalInfo * g_object_info_get_signal (GIObjectInfo *info, + gint n); +gint g_object_info_get_n_vfuncs (GIObjectInfo *info); +GIVFuncInfo * g_object_info_get_vfunc (GIObjectInfo *info, + gint n); +GIVFuncInfo * g_object_info_find_vfunc (GIObjectInfo *info, + const gchar *name); +gint g_object_info_get_n_constants (GIObjectInfo *info); +GIConstantInfo * g_object_info_get_constant (GIObjectInfo *info, + gint n); +GIStructInfo * g_object_info_get_class_struct (GIObjectInfo *info); + + +G_END_DECLS + + +#endif /* __GIOBJECTINFO_H__ */ + diff --git a/gipropertyinfo.c b/gipropertyinfo.c new file mode 100644 index 000000000..56b763c4c --- /dev/null +++ b/gipropertyinfo.c @@ -0,0 +1,60 @@ +/* GObject introspection: Property implementation + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 "girepository-private.h" +#include "gitypelib-internal.h" +#include "girffi.h" + +GParamFlags +g_property_info_get_flags (GIPropertyInfo *info) +{ + GParamFlags flags; + GIRealInfo *rinfo = (GIRealInfo *)info; + PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset]; + + flags = 0; + + if (blob->readable) + flags = flags | G_PARAM_READABLE; + + if (blob->writable) + flags = flags | G_PARAM_WRITABLE; + + if (blob->construct) + flags = flags | G_PARAM_CONSTRUCT; + + if (blob->construct_only) + flags = flags | G_PARAM_CONSTRUCT_ONLY; + + return flags; +} + +GITypeInfo * +g_property_info_get_type (GIPropertyInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + + return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (PropertyBlob, type)); +} + diff --git a/gipropertyinfo.h b/gipropertyinfo.h new file mode 100644 index 000000000..168b88ccd --- /dev/null +++ b/gipropertyinfo.h @@ -0,0 +1,42 @@ +/* GObject introspection: Property + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GIPROPERTYINFO_H__ +#define __GIPROPERTYINFO_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define GI_IS_PROPERTY_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_PROPERTY) + +GParamFlags g_property_info_get_flags (GIPropertyInfo *info); +GITypeInfo * g_property_info_get_type (GIPropertyInfo *info); + +G_END_DECLS + +#endif /* __GIPROPERTYINFO_H__ */ + diff --git a/giregisteredtypeinfo.c b/giregisteredtypeinfo.c index 944444f01..0f3493f3a 100644 --- a/giregisteredtypeinfo.c +++ b/giregisteredtypeinfo.c @@ -19,6 +19,8 @@ * Boston, MA 02111-1307, USA. */ +#include + #include #include diff --git a/girepository-private.h b/girepository-private.h index 52fc749a2..a4c0393e2 100644 --- a/girepository-private.h +++ b/girepository-private.h @@ -95,6 +95,14 @@ void _g_type_info_init (GIBaseInfo *info, GTypelib *typelib, guint32 offset); +GIFunctionInfo * _g_base_info_find_method (GIBaseInfo *base, + guint32 offset, + gint n_methods, + const gchar *name); +GIVFuncInfo * _g_base_info_find_vfunc (GIRealInfo *rinfo, + guint32 offset, + gint n_vfuncs, + const gchar *name); #endif /* __GIREPOSITORY_PRIVATE_H__ */ diff --git a/girepository.h b/girepository.h index 47d02b59c..5138e4aea 100644 --- a/girepository.h +++ b/girepository.h @@ -29,14 +29,22 @@ #include #include #include +#include #include #include #include #include +#include +#include +#include #include +#include +#include #include #include #include +#include +#include G_BEGIN_DECLS @@ -152,154 +160,6 @@ void gi_cclosure_marshal_generic (GClosure *closure, gpointer invocation_hint, gpointer marshal_data); -/* GIUnionInfo */ - -#define GI_IS_UNION_INFO(info) \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_UNION) - -gint g_union_info_get_n_fields (GIUnionInfo *info); -GIFieldInfo * g_union_info_get_field (GIUnionInfo *info, - gint n); -gint g_union_info_get_n_methods (GIUnionInfo *info); -GIFunctionInfo * g_union_info_get_method (GIUnionInfo *info, - gint n); -gboolean g_union_info_is_discriminated (GIUnionInfo *info); -gint g_union_info_get_discriminator_offset (GIUnionInfo *info); -GITypeInfo * g_union_info_get_discriminator_type (GIUnionInfo *info); -GIConstantInfo * g_union_info_get_discriminator (GIUnionInfo *info, - gint n); -GIFunctionInfo * g_union_info_find_method (GIUnionInfo *info, - const gchar *name); -gsize g_union_info_get_size (GIUnionInfo *info); -gsize g_union_info_get_alignment (GIUnionInfo *info); - - -/* GIStructInfo */ - -#define GI_IS_STRUCT_INFO(info) \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_STRUCT) - -gint g_struct_info_get_n_fields (GIStructInfo *info); -GIFieldInfo * g_struct_info_get_field (GIStructInfo *info, - gint n); -gint g_struct_info_get_n_methods (GIStructInfo *info); -GIFunctionInfo * g_struct_info_get_method (GIStructInfo *info, - gint n); -GIFunctionInfo * g_struct_info_find_method (GIStructInfo *info, - const gchar *name); -gsize g_struct_info_get_size (GIStructInfo *info); -gsize g_struct_info_get_alignment (GIStructInfo *info); -gboolean g_struct_info_is_gtype_struct (GIStructInfo *info); -gboolean g_struct_info_is_foreign (GIStructInfo *info); - -/* GIObjectInfo */ - -#define GI_IS_OBJECT_INFO(info) \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_OBJECT) - -const gchar * g_object_info_get_type_name (GIObjectInfo *info); -const gchar * g_object_info_get_type_init (GIObjectInfo *info); -gboolean g_object_info_get_abstract (GIObjectInfo *info); -GIObjectInfo * g_object_info_get_parent (GIObjectInfo *info); -gint g_object_info_get_n_interfaces (GIObjectInfo *info); -GIInterfaceInfo * g_object_info_get_interface (GIObjectInfo *info, - gint n); -gint g_object_info_get_n_fields (GIObjectInfo *info); -GIFieldInfo * g_object_info_get_field (GIObjectInfo *info, - gint n); -gint g_object_info_get_n_properties (GIObjectInfo *info); -GIPropertyInfo * g_object_info_get_property (GIObjectInfo *info, - gint n); -gint g_object_info_get_n_methods (GIObjectInfo *info); -GIFunctionInfo * g_object_info_get_method (GIObjectInfo *info, - gint n); -GIFunctionInfo * g_object_info_find_method (GIObjectInfo *info, - const gchar *name); -gint g_object_info_get_n_signals (GIObjectInfo *info); -GISignalInfo * g_object_info_get_signal (GIObjectInfo *info, - gint n); -gint g_object_info_get_n_vfuncs (GIObjectInfo *info); -GIVFuncInfo * g_object_info_get_vfunc (GIObjectInfo *info, - gint n); -GIVFuncInfo * g_object_info_find_vfunc (GIObjectInfo *info, - const gchar *name); -gint g_object_info_get_n_constants (GIObjectInfo *info); -GIConstantInfo * g_object_info_get_constant (GIObjectInfo *info, - gint n); -GIStructInfo * g_object_info_get_class_struct (GIObjectInfo *info); - - -/* GIInterfaceInfo */ - -#define GI_IS_INTERFACE_INFO(info) \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_INTERFACE) - -gint g_interface_info_get_n_prerequisites (GIInterfaceInfo *info); -GIBaseInfo * g_interface_info_get_prerequisite (GIInterfaceInfo *info, - gint n); -gint g_interface_info_get_n_properties (GIInterfaceInfo *info); -GIPropertyInfo * g_interface_info_get_property (GIInterfaceInfo *info, - gint n); -gint g_interface_info_get_n_methods (GIInterfaceInfo *info); -GIFunctionInfo * g_interface_info_get_method (GIInterfaceInfo *info, - gint n); -GIFunctionInfo * g_interface_info_find_method (GIInterfaceInfo *info, - const gchar *name); -gint g_interface_info_get_n_signals (GIInterfaceInfo *info); -GISignalInfo * g_interface_info_get_signal (GIInterfaceInfo *info, - gint n); -gint g_interface_info_get_n_vfuncs (GIInterfaceInfo *info); -GIVFuncInfo * g_interface_info_get_vfunc (GIInterfaceInfo *info, - gint n); -GIVFuncInfo * g_interface_info_find_vfunc (GIInterfaceInfo *info, - const gchar *name); -gint g_interface_info_get_n_constants (GIInterfaceInfo *info); -GIConstantInfo * g_interface_info_get_constant (GIInterfaceInfo *info, - gint n); - -GIStructInfo * g_interface_info_get_iface_struct (GIInterfaceInfo *info); - - -/* GIPropertyInfo */ - -#define GI_IS_PROPERTY_INFO(info) \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_PROPERTY) - -GParamFlags g_property_info_get_flags (GIPropertyInfo *info); -GITypeInfo * g_property_info_get_type (GIPropertyInfo *info); - - -/* GISignalInfo */ - -#define GI_IS_SIGNAL_INFO(info) \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_SIGNAL) - -GSignalFlags g_signal_info_get_flags (GISignalInfo *info); -GIVFuncInfo * g_signal_info_get_class_closure (GISignalInfo *info); -gboolean g_signal_info_true_stops_emit (GISignalInfo *info); - - -/* GIVFuncInfo */ - -#define GI_IS_VFUNC_INFO(info) \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_VFUNC) - -GIVFuncInfoFlags g_vfunc_info_get_flags (GIVFuncInfo *info); -gint g_vfunc_info_get_offset (GIVFuncInfo *info); -GISignalInfo * g_vfunc_info_get_signal (GIVFuncInfo *info); -GIFunctionInfo * g_vfunc_info_get_invoker (GIVFuncInfo *info); - - -/* GIConstantInfo */ - -#define GI_IS_CONSTANT_INFO(info) \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_CONSTANT) - -GITypeInfo * g_constant_info_get_type (GIConstantInfo *info); -gint g_constant_info_get_value (GIConstantInfo *info, - GArgument *value); - - G_END_DECLS diff --git a/gisignalinfo.c b/gisignalinfo.c new file mode 100644 index 000000000..2516a8b67 --- /dev/null +++ b/gisignalinfo.c @@ -0,0 +1,83 @@ +/* GObject introspection: Signal implementation + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 "girepository-private.h" +#include "gitypelib-internal.h" +#include "girffi.h" + +GSignalFlags +g_signal_info_get_flags (GISignalInfo *info) +{ + GSignalFlags flags; + + GIRealInfo *rinfo = (GIRealInfo *)info; + SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; + + flags = 0; + + if (blob->run_first) + flags = flags | G_SIGNAL_RUN_FIRST; + + if (blob->run_last) + flags = flags | G_SIGNAL_RUN_LAST; + + if (blob->run_cleanup) + flags = flags | G_SIGNAL_RUN_CLEANUP; + + if (blob->no_recurse) + flags = flags | G_SIGNAL_NO_RECURSE; + + if (blob->detailed) + flags = flags | G_SIGNAL_DETAILED; + + if (blob->action) + flags = flags | G_SIGNAL_ACTION; + + if (blob->no_hooks) + flags = flags | G_SIGNAL_NO_HOOKS; + + return flags; +} + +GIVFuncInfo * +g_signal_info_get_class_closure (GISignalInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->has_class_closure) + return g_interface_info_get_vfunc ((GIInterfaceInfo *)rinfo->container, blob->class_closure); + + return NULL; +} + +gboolean +g_signal_info_true_stops_emit (GISignalInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->true_stops_emit; +} + diff --git a/gisignalinfo.h b/gisignalinfo.h new file mode 100644 index 000000000..12054b003 --- /dev/null +++ b/gisignalinfo.h @@ -0,0 +1,44 @@ +/* GObject introspection: Signal + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GISIGNALINFO_H__ +#define __GISIGNALINFO_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define GI_IS_SIGNAL_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_SIGNAL) + +GSignalFlags g_signal_info_get_flags (GISignalInfo *info); +GIVFuncInfo * g_signal_info_get_class_closure (GISignalInfo *info); +gboolean g_signal_info_true_stops_emit (GISignalInfo *info); + +G_END_DECLS + + +#endif /* __GISIGNALINFO_H__ */ diff --git a/gistructinfo.c b/gistructinfo.c new file mode 100644 index 000000000..eee5609c6 --- /dev/null +++ b/gistructinfo.c @@ -0,0 +1,151 @@ +/* GObject introspection: Struct implementation + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 "girepository-private.h" +#include "gitypelib-internal.h" +#include "girffi.h" + +gint +g_struct_info_get_n_fields (GIStructInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_fields; +} + +static gint32 +g_struct_get_field_offset (GIStructInfo *info, + gint n) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + guint32 offset = rinfo->offset + header->struct_blob_size; + gint i; + FieldBlob *field_blob; + + for (i = 0; i < n; i++) + { + field_blob = (FieldBlob *)&rinfo->typelib->data[offset]; + offset += header->field_blob_size; + if (field_blob->has_embedded_type) + offset += header->callback_blob_size; + } + + return offset; +} + +GIFieldInfo * +g_struct_info_get_field (GIStructInfo *info, + gint n) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + + return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, + g_struct_get_field_offset (info, n)); +} + +gint +g_struct_info_get_n_methods (GIStructInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_methods; +} + +GIFunctionInfo * +g_struct_info_get_method (GIStructInfo *info, + gint n) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header = (Header *)rinfo->typelib->data; + gint offset; + + offset = g_struct_get_field_offset (info, blob->n_fields) + n * header->function_blob_size; + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, + rinfo->typelib, offset); +} + +GIFunctionInfo * +g_struct_info_find_method (GIStructInfo *info, + const gchar *name) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->struct_blob_size + + blob->n_fields * header->field_blob_size; + + return _g_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_methods, name); +} + +gsize +g_struct_info_get_size (GIStructInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->size; +} + +gsize +g_struct_info_get_alignment (GIStructInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->alignment; +} + +gboolean +g_struct_info_is_foreign (GIStructInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->foreign; +} + +/** + * g_struct_info_is_gtype_struct: + * @info: a #GIStructInfo + * + * Return true if this structure represents the "class structure" for some + * #GObject or #GInterface. This function is mainly useful to hide this kind of structure + * from generated public APIs. + * + * Returns: %TRUE if this is a class struct, %FALSE otherwise + */ +gboolean +g_struct_info_is_gtype_struct (GIStructInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->is_gtype_struct; +} diff --git a/gistructinfo.h b/gistructinfo.h new file mode 100644 index 000000000..91296c1c7 --- /dev/null +++ b/gistructinfo.h @@ -0,0 +1,52 @@ +/* GObject introspection: Struct + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GISTRUCTINFO_H__ +#define __GISTRUCTINFO_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define GI_IS_STRUCT_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_STRUCT) + +gint g_struct_info_get_n_fields (GIStructInfo *info); +GIFieldInfo * g_struct_info_get_field (GIStructInfo *info, + gint n); +gint g_struct_info_get_n_methods (GIStructInfo *info); +GIFunctionInfo * g_struct_info_get_method (GIStructInfo *info, + gint n); +GIFunctionInfo * g_struct_info_find_method (GIStructInfo *info, + const gchar *name); +gsize g_struct_info_get_size (GIStructInfo *info); +gsize g_struct_info_get_alignment (GIStructInfo *info); +gboolean g_struct_info_is_gtype_struct (GIStructInfo *info); +gboolean g_struct_info_is_foreign (GIStructInfo *info); + +G_END_DECLS + + +#endif /* __GISTRUCTINFO_H__ */ diff --git a/giunioninfo.c b/giunioninfo.c new file mode 100644 index 000000000..007eabd23 --- /dev/null +++ b/giunioninfo.c @@ -0,0 +1,156 @@ +/* GObject introspection: Union implementation + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 "girepository-private.h" +#include "gitypelib-internal.h" +#include "girffi.h" + +gint +g_union_info_get_n_fields (GIUnionInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_fields; +} + +GIFieldInfo * +g_union_info_get_field (GIUnionInfo *info, + gint n) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + + return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, + rinfo->offset + header->union_blob_size + + n * header->field_blob_size); +} + +gint +g_union_info_get_n_methods (GIUnionInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_functions; +} + +GIFunctionInfo * +g_union_info_get_method (GIUnionInfo *info, + gint n) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header = (Header *)rinfo->typelib->data; + gint offset; + + offset = rinfo->offset + header->union_blob_size + + blob->n_fields * header->field_blob_size + + n * header->function_blob_size; + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, + rinfo->typelib, offset); +} + +gboolean +g_union_info_is_discriminated (GIUnionInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->discriminated; +} + +gint +g_union_info_get_discriminator_offset (GIUnionInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->discriminator_offset; +} + +GITypeInfo * +g_union_info_get_discriminator_type (GIUnionInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + + return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 24); +} + +GIConstantInfo * +g_union_info_get_discriminator (GIUnionInfo *info, + gint n) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->discriminated) + { + Header *header = (Header *)rinfo->typelib->data; + gint offset; + + offset = rinfo->offset + header->union_blob_size + + blob->n_fields * header->field_blob_size + + blob->n_functions * header->function_blob_size + + n * header->constant_blob_size; + + return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, + rinfo->typelib, offset); + } + + return NULL; +} + +GIFunctionInfo * +g_union_info_find_method (GIUnionInfo *info, + const gchar *name) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->union_blob_size + + blob->n_fields * header->field_blob_size; + + return _g_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_functions, name); +} + +gsize +g_union_info_get_size (GIUnionInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->size; +} + +gsize +g_union_info_get_alignment (GIUnionInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->alignment; +} diff --git a/giunioninfo.h b/giunioninfo.h new file mode 100644 index 000000000..e42fe6f87 --- /dev/null +++ b/giunioninfo.h @@ -0,0 +1,56 @@ +/* GObject introspection: Union + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GIUNIONINFO_H__ +#define __GIUNIONINFO_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define GI_IS_UNION_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_UNION) + +gint g_union_info_get_n_fields (GIUnionInfo *info); +GIFieldInfo * g_union_info_get_field (GIUnionInfo *info, + gint n); +gint g_union_info_get_n_methods (GIUnionInfo *info); +GIFunctionInfo * g_union_info_get_method (GIUnionInfo *info, + gint n); +gboolean g_union_info_is_discriminated (GIUnionInfo *info); +gint g_union_info_get_discriminator_offset (GIUnionInfo *info); +GITypeInfo * g_union_info_get_discriminator_type (GIUnionInfo *info); +GIConstantInfo * g_union_info_get_discriminator (GIUnionInfo *info, + gint n); +GIFunctionInfo * g_union_info_find_method (GIUnionInfo *info, + const gchar *name); +gsize g_union_info_get_size (GIUnionInfo *info); +gsize g_union_info_get_alignment (GIUnionInfo *info); + +G_END_DECLS + + +#endif /* __GIUNIONINFO_H__ */ + diff --git a/givfuncinfo.c b/givfuncinfo.c new file mode 100644 index 000000000..e0bb68746 --- /dev/null +++ b/givfuncinfo.c @@ -0,0 +1,131 @@ +/* GObject introspection: Virtual Function implementation + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 "girepository-private.h" +#include "gitypelib-internal.h" +#include "girffi.h" + +GIVFuncInfo * +_g_base_info_find_vfunc (GIRealInfo *rinfo, + guint32 offset, + gint n_vfuncs, + const gchar *name) +{ + /* FIXME hash */ + Header *header = (Header *)rinfo->typelib->data; + gint i; + + for (i = 0; i < n_vfuncs; i++) + { + VFuncBlob *fblob = (VFuncBlob *)&rinfo->typelib->data[offset]; + const gchar *fname = (const gchar *)&rinfo->typelib->data[fblob->name]; + + if (strcmp (name, fname) == 0) + return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*) rinfo, + rinfo->typelib, offset); + + offset += header->vfunc_blob_size; + } + + return NULL; +} + +GIVFuncInfoFlags +g_vfunc_info_get_flags (GIVFuncInfo *info) +{ + GIVFuncInfoFlags flags; + + GIRealInfo *rinfo = (GIRealInfo *)info; + VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; + + flags = 0; + + if (blob->must_chain_up) + flags = flags | GI_VFUNC_MUST_CHAIN_UP; + + if (blob->must_be_implemented) + flags = flags | GI_VFUNC_MUST_OVERRIDE; + + if (blob->must_not_be_implemented) + flags = flags | GI_VFUNC_MUST_NOT_OVERRIDE; + + return flags; +} + +gint +g_vfunc_info_get_offset (GIVFuncInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->struct_offset; +} + +GISignalInfo * +g_vfunc_info_get_signal (GIVFuncInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->class_closure) + return g_interface_info_get_signal ((GIInterfaceInfo *)rinfo->container, blob->signal); + + return NULL; +} + +/** + * g_vfunc_info_get_invoker: + * @info: a #GIVFuncInfo + * + * If this virtual function has an associated invoker method, this + * method will return it. An invoker method is a C entry point. + * + * Not all virtuals will have invokers. + * + * Returns: (transfer full): the #GIVFuncInfo or %NULL. Free it with + * g_base_info_unref() when done. + */ +GIFunctionInfo * +g_vfunc_info_get_invoker (GIVFuncInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; + GIBaseInfo *container = rinfo->container; + GIInfoType parent_type; + + /* 1023 = 0x3ff is the maximum of the 10 bits for invoker index */ + if (blob->invoker == 1023) + return NULL; + + parent_type = g_base_info_get_type (container); + if (parent_type == GI_INFO_TYPE_OBJECT) + return g_object_info_get_method ((GIObjectInfo*)container, blob->invoker); + else if (parent_type == GI_INFO_TYPE_INTERFACE) + return g_interface_info_get_method ((GIInterfaceInfo*)container, blob->invoker); + else + g_assert_not_reached (); +} + diff --git a/givfuncinfo.h b/givfuncinfo.h new file mode 100644 index 000000000..6629cad81 --- /dev/null +++ b/givfuncinfo.h @@ -0,0 +1,44 @@ +/* GObject introspection: Virtual Functions + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 __GIVFUNCINFO_H__ +#define __GIVFUNCINFO_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define GI_IS_VFUNC_INFO(info) \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_VFUNC) + +GIVFuncInfoFlags g_vfunc_info_get_flags (GIVFuncInfo *info); +gint g_vfunc_info_get_offset (GIVFuncInfo *info); +GISignalInfo * g_vfunc_info_get_signal (GIVFuncInfo *info); +GIFunctionInfo * g_vfunc_info_get_invoker (GIVFuncInfo *info); + +G_END_DECLS + + +#endif /* __GIVFUNCINFO_H__ */ From e57e4f2868c93ceb92953a90a38a92c12630e265 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 19:53:41 -0300 Subject: [PATCH 317/692] [gifunction.h] Move GIFunctionInfoFlags to gitypes.h --- gifunctioninfo.h | 21 --------------------- gitypes.h | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/gifunctioninfo.h b/gifunctioninfo.h index 9c47bd16a..a07b60f74 100644 --- a/gifunctioninfo.h +++ b/gifunctioninfo.h @@ -33,27 +33,6 @@ G_BEGIN_DECLS #define GI_IS_FUNCTION_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FUNCTION) -/** - * GIFunctionInfoFlags: - * @GI_FUNCTION_IS_METHOD: is a method. - * @GI_FUNCTION_IS_CONSTRUCTOR: is a constructor. - * @GI_FUNCTION_IS_GETTER: is a getter of a #GIPropertyInfo. - * @GI_FUNCTION_IS_SETTER: is a setter of a #GIPropertyInfo. - * @GI_FUNCTION_WRAPS_VFUNC: represents a virtual function. - * @GI_FUNCTION_THROWS: the function may throw an error. - * - * Flags for a #GIFunctionInfo struct. - */ -typedef enum -{ - GI_FUNCTION_IS_METHOD = 1 << 0, - GI_FUNCTION_IS_CONSTRUCTOR = 1 << 1, - GI_FUNCTION_IS_GETTER = 1 << 2, - GI_FUNCTION_IS_SETTER = 1 << 3, - GI_FUNCTION_WRAPS_VFUNC = 1 << 4, - GI_FUNCTION_THROWS = 1 << 5 -} GIFunctionInfoFlags; - const gchar * g_function_info_get_symbol (GIFunctionInfo *info); GIFunctionInfoFlags g_function_info_get_flags (GIFunctionInfo *info); GIPropertyInfo * g_function_info_get_property (GIFunctionInfo *info); diff --git a/gitypes.h b/gitypes.h index b6986b47b..10a412d75 100644 --- a/gitypes.h +++ b/gitypes.h @@ -413,5 +413,26 @@ typedef enum GI_VFUNC_MUST_NOT_OVERRIDE = 1 << 2 } GIVFuncInfoFlags; +/** + * GIFunctionInfoFlags: + * @GI_FUNCTION_IS_METHOD: is a method. + * @GI_FUNCTION_IS_CONSTRUCTOR: is a constructor. + * @GI_FUNCTION_IS_GETTER: is a getter of a #GIPropertyInfo. + * @GI_FUNCTION_IS_SETTER: is a setter of a #GIPropertyInfo. + * @GI_FUNCTION_WRAPS_VFUNC: represents a virtual function. + * @GI_FUNCTION_THROWS: the function may throw an error. + * + * Flags for a #GIFunctionInfo struct. + */ +typedef enum +{ + GI_FUNCTION_IS_METHOD = 1 << 0, + GI_FUNCTION_IS_CONSTRUCTOR = 1 << 1, + GI_FUNCTION_IS_GETTER = 1 << 2, + GI_FUNCTION_IS_SETTER = 1 << 3, + GI_FUNCTION_WRAPS_VFUNC = 1 << 4, + GI_FUNCTION_THROWS = 1 << 5 +} GIFunctionInfoFlags; + #endif /* __GITYPES_H__ */ From dc4a7e9e32fccd4587c739569df8064ba2aa1216 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 22:47:02 -0300 Subject: [PATCH 318/692] [giregisteredtype] Flags have a GType --- giregisteredtypeinfo.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/giregisteredtypeinfo.h b/giregisteredtypeinfo.h index 8a6332147..a7d19f5db 100644 --- a/giregisteredtypeinfo.h +++ b/giregisteredtypeinfo.h @@ -31,10 +31,9 @@ G_BEGIN_DECLS -/* GIRegisteredTypeInfo */ - #define GI_IS_REGISTERED_TYPE_INFO(info) \ ((g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ENUM) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FLAGS) || \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_INTERFACE) || \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_OBJECT) || \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_STRUCT) || \ From 501238c318f4490be9abc0af6b12dff0a5b57a91 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 22:47:21 -0300 Subject: [PATCH 319/692] Remove left-over comments --- gibaseinfo.h | 2 -- giobjectinfo.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/gibaseinfo.h b/gibaseinfo.h index 79f50ce9d..5d0cb8444 100644 --- a/gibaseinfo.h +++ b/gibaseinfo.h @@ -44,8 +44,6 @@ struct _GIBaseInfoStub { gpointer padding[4]; }; -/* GIBaseInfo */ - /** * GIAttributeIter: * diff --git a/giobjectinfo.h b/giobjectinfo.h index 50a85b7a2..27ec71411 100644 --- a/giobjectinfo.h +++ b/giobjectinfo.h @@ -30,8 +30,6 @@ G_BEGIN_DECLS -/* GIObjectInfo */ - #define GI_IS_OBJECT_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_OBJECT) From 6e11316e28b207f3228f496bca083d4ce3771d78 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 22:47:50 -0300 Subject: [PATCH 320/692] [gifieldinfo] Document g_field_info_get_flags --- gifieldinfo.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gifieldinfo.c b/gifieldinfo.c index 878f411cc..a902e6f67 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -39,6 +39,15 @@ * which is currently #GI_FIELD_IS_READABLE or #GI_FIELD_IS_WRITABLE. */ +/** + * g_field_info_get_flags: + * @info: a #GIFieldInfo + * + * Obtain the flags for this #GIFieldInfo. See #GIFieldInfoFlags for possible + * flag values. + * + * Returns: the flags + */ GIFieldInfoFlags g_field_info_get_flags (GIFieldInfo *info) { @@ -110,6 +119,7 @@ g_field_info_get_offset (GIFieldInfo *info) /** * g_field_info_get_type: + * @info: a #GIFieldInfo * * Obtain the type of a field as a #GITypeInfo. * From a2df86f9f675bc367f0a5b8267449b55c03dd9a0 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 22:48:08 -0300 Subject: [PATCH 321/692] [giconstantinfo] Document and check parameters --- giconstantinfo.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/giconstantinfo.c b/giconstantinfo.c index 72cc04368..16237793e 100644 --- a/giconstantinfo.c +++ b/giconstantinfo.c @@ -26,20 +26,59 @@ #include "gitypelib-internal.h" #include "girffi.h" +/** + * SECTION:giconstantinfo + * @Short_description: Struct representing a constant + * @Title: GIConstantInfo + * + * GIConstantInfo represents a constant. A constant has a type associated + * which can be obtained by calling g_constant_info_get_type() and a value, + * which can be obtained by calling g_constant_info_get_value(). + */ + + +/** + * g_constant_info_get_type: + * @info: a #GIConstantInfo + * + * Obtain the type of the constant as a #GITypeInfo. + * + * Returns: (transfer full): the #GITypeInfo. Free the struct by calling + * g_base_info_unref() when done. + */ GITypeInfo * g_constant_info_get_type (GIConstantInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_CONSTANT_INFO (info), NULL); + return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 8); } +/** + * g_constant_info_get_value: + * @info: a #GIConstantInfo + * @value: (out): an argument + * + * Obtain the value associated with the #GIConstantInfo and store it in the + * @value parameter. @argument needs to be allocated before passing it in. + * The size of the constant value stored in @argument will be returned. + * + * Returns: size of the constant + */ gint g_constant_info_get_value (GIConstantInfo *info, GArgument *value) { GIRealInfo *rinfo = (GIRealInfo *)info; - ConstantBlob *blob = (ConstantBlob *)&rinfo->typelib->data[rinfo->offset]; + ConstantBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_CONSTANT_INFO (info), 0); + + blob = (ConstantBlob *)&rinfo->typelib->data[rinfo->offset]; /* FIXME non-basic types ? */ if (blob->type.flags.reserved == 0 && blob->type.flags.reserved2 == 0) From c47ecdee4164c0d34c038d0ee945f8040a5dcd88 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 22:57:14 -0300 Subject: [PATCH 322/692] [build] Install gistructinfo.h --- Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.am b/Makefile.am index bec0cfce0..9faff911d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,6 +15,7 @@ girepo_HEADERS = \ girepository.h \ girffi.h \ gisignalinfo.h \ + gistructinfo.h \ gitypeinfo.h \ gitypelib.h \ gitypes.h \ From a23a6976640442e06e51a65a53a2e35557ba9018 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 22:57:28 -0300 Subject: [PATCH 323/692] [gitypes] Remove a comment and move G_END_DECLS --- gitypes.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gitypes.h b/gitypes.h index 10a412d75..78becaef2 100644 --- a/gitypes.h +++ b/gitypes.h @@ -189,8 +189,6 @@ typedef union gpointer v_pointer; } GArgument; -/* Types of objects registered in the repository */ - /** * GIInfoType: * @GI_INFO_TYPE_INVALID: invalid type @@ -293,8 +291,6 @@ typedef enum { GI_SCOPE_TYPE_NOTIFIED } GIScopeType; -G_END_DECLS - /** * GITypeTag: * @GI_TYPE_TAG_VOID: void @@ -434,5 +430,7 @@ typedef enum GI_FUNCTION_THROWS = 1 << 5 } GIFunctionInfoFlags; +G_END_DECLS + #endif /* __GITYPES_H__ */ From 91c621b9dbcbd4f6f3435ca28997120292f21e38 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 23:04:15 -0300 Subject: [PATCH 324/692] [giregisteredtypeinfo] Document and check parameters --- giregisteredtypeinfo.c | 61 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/giregisteredtypeinfo.c b/giregisteredtypeinfo.c index 0f3493f3a..3f308d22f 100644 --- a/giregisteredtypeinfo.c +++ b/giregisteredtypeinfo.c @@ -28,11 +28,40 @@ #include "gitypelib-internal.h" #include "girffi.h" +/** + * SECTION:giregisteredtypeinfo + * @Short_description: Struct representing a struct with a GType + * @Title: GIRegisteredTypeInfo + * + * GIRegisteredTypeInfo represents an entity with a GType associated. Could + * be either a #GIEnumInfo, #GIInterfaceInfo, #GIObjectInfo, #GIStructInfo or a + * #GIUnionInfo. + * + * A registered type info struct has a name and a type function. + * To get the name call g_registered_type_info_get_type_name(). + * Most users want to call g_registered_type_info_get_g_type() and don't worry + * about the rest of the details. + */ + +/** + * g_registered_type_info_get_type_name: + * @info: a #GIRegisteredTypeInfo + * + * Obtain the type name of the struct within the GObject type system. + * This type can be passed to g_type_name() to get a #GType. + * + * Returns: the type name + */ const gchar * g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + RegisteredTypeBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_REGISTERED_TYPE_INFO (info), NULL); + + blob = (RegisteredTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->gtype_name) return g_typelib_get_string (rinfo->typelib, blob->gtype_name); @@ -40,11 +69,28 @@ g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info) return NULL; } +/** + * g_registered_type_info_get_type_init: + * @info: a #GIRegisteredTypeInfo + * + * Obtain the type init function for @info. The type init function is the + * function which will register the GType within the GObject type system. + * Usually this is not called by langauge bindings or applications, use + * g_registered_type_info_get_g_type() directly instead. + * + * Returns: the symbol name of the type init function, suitable for + * passing into g_module_symbol(). + */ const gchar * g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&rinfo->typelib->data[rinfo->offset]; + RegisteredTypeBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_REGISTERED_TYPE_INFO (info), NULL); + + blob = (RegisteredTypeBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->gtype_init) return g_typelib_get_string (rinfo->typelib, blob->gtype_init); @@ -52,6 +98,14 @@ g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info) return NULL; } +/** + * g_registered_type_info_get_g_type: + * @info: a #GIRegisteredTypeInfo + * + * Obtain the #GType for this registered type. + * + * Returns: the #GType. + */ GType g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info) { @@ -59,6 +113,9 @@ g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info) GType (* get_type_func) (void); GIRealInfo *rinfo = (GIRealInfo*)info; + g_return_val_if_fail (info != NULL, G_TYPE_INVALID); + g_return_val_if_fail (GI_IS_REGISTERED_TYPE_INFO (info), G_TYPE_INVALID); + type_init = g_registered_type_info_get_type_init (info); if (type_init == NULL) From 1edafae79e3c5b1e6aecd34065cbb9ed8ffff84d Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 23:17:46 -0300 Subject: [PATCH 325/692] [girepository] Don't include girffi.h everywhere --- giconstantinfo.c | 1 - giinterfaceinfo.c | 1 - giobjectinfo.c | 1 - gipropertyinfo.c | 1 - giregisteredtypeinfo.c | 1 - gisignalinfo.c | 1 - gistructinfo.c | 1 - giunioninfo.c | 1 - givfuncinfo.c | 1 - 9 files changed, 9 deletions(-) diff --git a/giconstantinfo.c b/giconstantinfo.c index 16237793e..551e73cd5 100644 --- a/giconstantinfo.c +++ b/giconstantinfo.c @@ -24,7 +24,6 @@ #include #include "girepository-private.h" #include "gitypelib-internal.h" -#include "girffi.h" /** * SECTION:giconstantinfo diff --git a/giinterfaceinfo.c b/giinterfaceinfo.c index 070343ddf..ba8f43f85 100644 --- a/giinterfaceinfo.c +++ b/giinterfaceinfo.c @@ -24,7 +24,6 @@ #include #include "girepository-private.h" #include "gitypelib-internal.h" -#include "girffi.h" gint g_interface_info_get_n_prerequisites (GIInterfaceInfo *info) diff --git a/giobjectinfo.c b/giobjectinfo.c index ac7de59e7..6f9e04612 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -24,7 +24,6 @@ #include #include "girepository-private.h" #include "gitypelib-internal.h" -#include "girffi.h" /* GIObjectInfo functions */ GIObjectInfo * diff --git a/gipropertyinfo.c b/gipropertyinfo.c index 56b763c4c..705a80bfa 100644 --- a/gipropertyinfo.c +++ b/gipropertyinfo.c @@ -24,7 +24,6 @@ #include #include "girepository-private.h" #include "gitypelib-internal.h" -#include "girffi.h" GParamFlags g_property_info_get_flags (GIPropertyInfo *info) diff --git a/giregisteredtypeinfo.c b/giregisteredtypeinfo.c index 3f308d22f..fe159cf8d 100644 --- a/giregisteredtypeinfo.c +++ b/giregisteredtypeinfo.c @@ -26,7 +26,6 @@ #include #include "girepository-private.h" #include "gitypelib-internal.h" -#include "girffi.h" /** * SECTION:giregisteredtypeinfo diff --git a/gisignalinfo.c b/gisignalinfo.c index 2516a8b67..2333980a9 100644 --- a/gisignalinfo.c +++ b/gisignalinfo.c @@ -24,7 +24,6 @@ #include #include "girepository-private.h" #include "gitypelib-internal.h" -#include "girffi.h" GSignalFlags g_signal_info_get_flags (GISignalInfo *info) diff --git a/gistructinfo.c b/gistructinfo.c index eee5609c6..aaecebbf2 100644 --- a/gistructinfo.c +++ b/gistructinfo.c @@ -24,7 +24,6 @@ #include #include "girepository-private.h" #include "gitypelib-internal.h" -#include "girffi.h" gint g_struct_info_get_n_fields (GIStructInfo *info) diff --git a/giunioninfo.c b/giunioninfo.c index 007eabd23..5db7c0472 100644 --- a/giunioninfo.c +++ b/giunioninfo.c @@ -24,7 +24,6 @@ #include #include "girepository-private.h" #include "gitypelib-internal.h" -#include "girffi.h" gint g_union_info_get_n_fields (GIUnionInfo *info) diff --git a/givfuncinfo.c b/givfuncinfo.c index e0bb68746..fe5c00cff 100644 --- a/givfuncinfo.c +++ b/givfuncinfo.c @@ -26,7 +26,6 @@ #include #include "girepository-private.h" #include "gitypelib-internal.h" -#include "girffi.h" GIVFuncInfo * _g_base_info_find_vfunc (GIRealInfo *rinfo, From 6b4647c08887e9b84542afcead2031545315689b Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sun, 6 Jun 2010 23:22:57 -0300 Subject: [PATCH 326/692] [girepository] Kill girffi-private.h --- Makefile.am | 1 - girepository-private.h | 5 +++++ girepository.h | 5 +++-- girffi-private.h | 32 -------------------------------- girffi.c | 8 ++++---- giroffsets.c | 4 ++-- 6 files changed, 14 insertions(+), 41 deletions(-) delete mode 100644 girffi-private.h diff --git a/Makefile.am b/Makefile.am index 9faff911d..958941259 100644 --- a/Makefile.am +++ b/Makefile.am @@ -44,7 +44,6 @@ libgirepository_1_0_la_SOURCES = \ girepository-private.h \ girffi.c \ girffi.h \ - girffi-private.h \ gisignalinfo.c \ gistructinfo.c \ gitypeinfo.c \ diff --git a/girepository-private.h b/girepository-private.h index a4c0393e2..8382f408f 100644 --- a/girepository-private.h +++ b/girepository-private.h @@ -22,8 +22,11 @@ #ifndef __GIREPOSITORY_PRIVATE_H__ #define __GIREPOSITORY_PRIVATE_H__ +#include #include +#define __GIREPOSITORY_H_INSIDE__ + #include #include #include @@ -105,4 +108,6 @@ GIVFuncInfo * _g_base_info_find_vfunc (GIRealInfo *rinfo, gint n_vfuncs, const gchar *name); +ffi_type * _gi_type_tag_get_ffi_type (GITypeTag type_tag, gboolean is_pointer); + #endif /* __GIREPOSITORY_PRIVATE_H__ */ diff --git a/girepository.h b/girepository.h index 5138e4aea..4b605d237 100644 --- a/girepository.h +++ b/girepository.h @@ -22,10 +22,11 @@ #ifndef __G_IREPOSITORY_H__ #define __G_IREPOSITORY_H__ -#define __GIREPOSITORY_H_INSIDE__ - #include #include + +#define __GIREPOSITORY_H_INSIDE__ + #include #include #include diff --git a/girffi-private.h b/girffi-private.h deleted file mode 100644 index 645335006..000000000 --- a/girffi-private.h +++ /dev/null @@ -1,32 +0,0 @@ -/* GObject introspection: Private helper functions for ffi integration - * - * Copyright (C) 2008, 2009 Red Hat, Inc - * - * 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 __GIRFFI_PRIVATE_H__ -#define __GIRFFI_PRIVATE_H__ - -#include "girffi.h" - -G_BEGIN_DECLS - -ffi_type * g_ir_ffi_get_ffi_type (GITypeTag type_tag, gboolean is_pointer); - -G_END_DECLS - -#endif /* __GIRFFI_PRIVATE_H__ */ diff --git a/girffi.c b/girffi.c index 6716324ee..559af258c 100644 --- a/girffi.c +++ b/girffi.c @@ -27,12 +27,12 @@ #include #include #include "girffi.h" -#include "girffi-private.h" #include "girepository.h" +#include "girepository-private.h" ffi_type * -g_ir_ffi_get_ffi_type (GITypeTag tag, - gboolean is_pointer) +_gi_type_tag_get_ffi_type (GITypeTag tag, + gboolean is_pointer) { switch (tag) { @@ -125,7 +125,7 @@ g_ir_ffi_get_ffi_type (GITypeTag tag, ffi_type * g_type_info_get_ffi_type (GITypeInfo *info) { - return g_ir_ffi_get_ffi_type (g_type_info_get_tag (info), g_type_info_is_pointer (info)); + return _gi_type_tag_get_ffi_type (g_type_info_get_tag (info), g_type_info_is_pointer (info)); } /** diff --git a/giroffsets.c b/giroffsets.c index 263665ce3..5d481da15 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -18,7 +18,7 @@ * Boston, MA 02111-1307, USA. */ -#include "girffi-private.h" +#include "girepository-private.h" #include "girnode.h" /* The C standard specifies that an enumeration can be any char or any signed @@ -262,7 +262,7 @@ get_type_size_alignment (GIrNodeType *type, } else { - type_ffi = g_ir_ffi_get_ffi_type (type->tag, type->is_pointer); + type_ffi = _gi_type_tag_get_ffi_type (type->tag, type->is_pointer); if (type_ffi == &ffi_type_void) { From 06d778dc3c20246faee378343e3486f2f90bfbe8 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Mon, 7 Jun 2010 10:29:53 -0300 Subject: [PATCH 327/692] [Makefile.am] Reindent --- Makefile.am | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/Makefile.am b/Makefile.am index 958941259..f85b5be5e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,26 +1,26 @@ girepodir = $(includedir)/gobject-introspection-1.0/ girepo_HEADERS = \ - giarginfo.h \ - gibaseinfo.h \ - gicallableinfo.h \ - giconstantinfo.h \ - gienuminfo.h \ - gierrordomaininfo.h \ - gifieldinfo.h \ - gifunctioninfo.h \ - giinterfaceinfo.h \ - giobjectinfo.h \ - gipropertyinfo.h \ - giregisteredtypeinfo.h \ - girepository.h \ - girffi.h \ - gisignalinfo.h \ - gistructinfo.h \ - gitypeinfo.h \ - gitypelib.h \ - gitypes.h \ - giunioninfo.h \ - givfuncinfo.h + giarginfo.h \ + gibaseinfo.h \ + gicallableinfo.h \ + giconstantinfo.h \ + gienuminfo.h \ + gierrordomaininfo.h \ + gifieldinfo.h \ + gifunctioninfo.h \ + giinterfaceinfo.h \ + giobjectinfo.h \ + gipropertyinfo.h \ + giregisteredtypeinfo.h \ + girepository.h \ + girffi.h \ + gisignalinfo.h \ + gistructinfo.h \ + gitypeinfo.h \ + gitypelib.h \ + gitypes.h \ + giunioninfo.h \ + givfuncinfo.h lib_LTLIBRARIES = libgirepository-1.0.la noinst_LTLIBRARIES = libgirepository-parser.la From 27511f220b11801c5540ef441e0472bd3137e199 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Mon, 7 Jun 2010 10:52:43 -0300 Subject: [PATCH 328/692] [girwriter] Refactor out of generate.c Move out the girwriter out of generate.c. Still a private API, but that will probably change in the future. --- Makefile.am | 4 +- girwriter.c | 1402 +++++++++++++++++++++++++++++++++++++++++++++++++++ girwriter.h | 11 +- 3 files changed, 1412 insertions(+), 5 deletions(-) create mode 100644 girwriter.c diff --git a/Makefile.am b/Makefile.am index f85b5be5e..f76e6c3ef 100644 --- a/Makefile.am +++ b/Makefile.am @@ -64,6 +64,8 @@ libgirepository_parser_la_SOURCES = \ girnode.h \ giroffsets.c \ girparser.c \ - girparser.h + girparser.h \ + girwriter.c \ + girwriter.h libgirepository_parser_la_CFLAGS = $(GIREPO_CFLAGS) diff --git a/girwriter.c b/girwriter.c new file mode 100644 index 000000000..6fa892db2 --- /dev/null +++ b/girwriter.c @@ -0,0 +1,1402 @@ + +/* -*- Mode: C; c-file-style: "gnu"; -*- */ +/* GObject introspection: IDL generator + * + * Copyright (C) 2005 Matthias Clasen + * Copyright (C) 2008,2009 Red Hat, Inc. + * + * 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 +#include +#include + +#include "girwriter.h" +#include "girepository.h" +#include "gitypelib-internal.h" + +typedef struct { + FILE *file; + GSList *stack; + gboolean show_all; +} Xml; + +typedef struct { + char *name; + guint has_children : 1; +} XmlElement; + +static XmlElement * +xml_element_new (const char *name) +{ + XmlElement *elem; + + elem = g_new (XmlElement, 1); + elem->name = g_strdup (name); + elem->has_children = FALSE; + return elem; +} + +static void +xml_element_free (XmlElement *elem) +{ + g_free (elem->name); + g_free (elem); +} + +static void +xml_printf (Xml *xml, const char *fmt, ...) +{ + va_list ap; + char *s; + + va_start (ap, fmt); + s = g_markup_vprintf_escaped (fmt, ap); + fputs (s, xml->file); + g_free (s); + va_end (ap); +} + +static void +xml_start_element (Xml *xml, const char *element_name) +{ + XmlElement *parent = NULL; + + if (xml->stack) + { + parent = xml->stack->data; + + if (!parent->has_children) + xml_printf (xml, ">\n"); + + parent->has_children = TRUE; + } + + xml_printf (xml, "%*s<%s", g_slist_length(xml->stack)*2, "", element_name); + + xml->stack = g_slist_prepend (xml->stack, xml_element_new (element_name)); +} + +static void +xml_end_element (Xml *xml, const char *name) +{ + XmlElement *elem; + + g_assert (xml->stack != NULL); + + elem = xml->stack->data; + xml->stack = g_slist_delete_link (xml->stack, xml->stack); + + if (name != NULL) + g_assert_cmpstr (name, ==, elem->name); + + if (elem->has_children) + xml_printf (xml, "%*s\n", g_slist_length (xml->stack)*2, "", elem->name); + else + xml_printf (xml, "/>\n"); + + xml_element_free (elem); +} + +static void +xml_end_element_unchecked (Xml *xml) +{ + xml_end_element (xml, NULL); +} + +static Xml * +xml_open (FILE *file) +{ + Xml *xml; + + xml = g_new (Xml, 1); + xml->file = file; + xml->stack = NULL; + + return xml; +} + +static void +xml_close (Xml *xml) +{ + g_assert (xml->stack == NULL); + if (xml->file != NULL) + { + fflush (xml->file); + if (xml->file != stdout) + fclose (xml->file); + xml->file = NULL; + } +} + +static void +xml_free (Xml *xml) +{ + xml_close (xml); + g_free (xml); +} + + +static void +check_unresolved (GIBaseInfo *info) +{ + if (g_base_info_get_type (info) != GI_INFO_TYPE_UNRESOLVED) + return; + + g_critical ("Found unresolved type '%s' '%s'\n", + g_base_info_get_name (info), g_base_info_get_namespace (info)); +} + +static void +write_type_name (const gchar *namespace, + GIBaseInfo *info, + Xml *file) +{ + if (strcmp (namespace, g_base_info_get_namespace (info)) != 0) + xml_printf (file, "%s.", g_base_info_get_namespace (info)); + + xml_printf (file, "%s", g_base_info_get_name (info)); +} + +static void +write_type_name_attribute (const gchar *namespace, + GIBaseInfo *info, + const char *attr_name, + Xml *file) +{ + xml_printf (file, " %s=\"", attr_name); + write_type_name (namespace, info, file); + xml_printf (file, "\""); +} + +static void +write_type_info (const gchar *namespace, + GITypeInfo *info, + Xml *file) +{ + gint tag; + gint i; + GITypeInfo *type; + gboolean is_pointer; + + check_unresolved ((GIBaseInfo*)info); + + tag = g_type_info_get_tag (info); + is_pointer = g_type_info_is_pointer (info); + + if (tag == GI_TYPE_TAG_VOID) + { + xml_start_element (file, "type"); + + xml_printf (file, " name=\"%s\"", is_pointer ? "any" : "none"); + + xml_end_element (file, "type"); + } + else if (G_TYPE_TAG_IS_BASIC (tag)) + { + xml_start_element (file, "type"); + xml_printf (file, " name=\"%s\"", g_type_tag_to_string (tag)); + xml_end_element (file, "type"); + } + else if (tag == GI_TYPE_TAG_ARRAY) + { + gint length, size; + char *name = NULL; + + xml_start_element (file, "array"); + + switch (g_type_info_get_array_type (info)) { + case GI_ARRAY_TYPE_C: + break; + case GI_ARRAY_TYPE_ARRAY: + name = "GLib.Array"; + break; + case GI_ARRAY_TYPE_PTR_ARRAY: + name = "GLib.PtrArray"; + break; + case GI_ARRAY_TYPE_BYTE_ARRAY: + name = "GLib.ByteArray"; + break; + default: + break; + } + + if (name) + xml_printf (file, " name=\"%s\"", name); + + type = g_type_info_get_param_type (info, 0); + + length = g_type_info_get_array_length (info); + if (length >= 0) + xml_printf (file, " length=\"%d\"", length); + + size = g_type_info_get_array_fixed_size (info); + if (size >= 0) + xml_printf (file, " fixed-size=\"%d\"", size); + + if (g_type_info_is_zero_terminated (info)) + xml_printf (file, " zero-terminated=\"1\""); + + write_type_info (namespace, type, file); + + g_base_info_unref ((GIBaseInfo *)type); + + xml_end_element (file, "array"); + } + else if (tag == GI_TYPE_TAG_INTERFACE) + { + GIBaseInfo *iface = g_type_info_get_interface (info); + xml_start_element (file, "type"); + write_type_name_attribute (namespace, iface, "name", file); + xml_end_element (file, "type"); + g_base_info_unref (iface); + } + else if (tag == GI_TYPE_TAG_GLIST) + { + xml_start_element (file, "type"); + xml_printf (file, " name=\"GLib.List\""); + type = g_type_info_get_param_type (info, 0); + if (type) + { + write_type_info (namespace, type, file); + g_base_info_unref ((GIBaseInfo *)type); + } + xml_end_element (file, "type"); + } + else if (tag == GI_TYPE_TAG_GSLIST) + { + xml_start_element (file, "type"); + xml_printf (file, " name=\"GLib.SList\""); + type = g_type_info_get_param_type (info, 0); + if (type) + { + write_type_info (namespace, type, file); + g_base_info_unref ((GIBaseInfo *)type); + } + xml_end_element (file, "type"); + } + else if (tag == GI_TYPE_TAG_GHASH) + { + xml_start_element (file, "type"); + xml_printf (file, " name=\"GLib.HashTable\""); + type = g_type_info_get_param_type (info, 0); + if (type) + { + write_type_info (namespace, type, file); + g_base_info_unref ((GIBaseInfo *)type); + type = g_type_info_get_param_type (info, 1); + write_type_info (namespace, type, file); + g_base_info_unref ((GIBaseInfo *)type); + } + xml_end_element (file, "type"); + } + else if (tag == GI_TYPE_TAG_ERROR) + { + gint n; + + xml_start_element (file, "type"); + xml_printf (file, " name=\"GLib.Error\""); + + n = g_type_info_get_n_error_domains (info); + if (n > 0) + { + for (i = 0; i < n; i++) + { + GIErrorDomainInfo *ed = g_type_info_get_error_domain (info, i); + xml_start_element (file, "type"); + write_type_name_attribute (namespace, (GIBaseInfo *)ed, "name", file); + xml_end_element (file, "type"); + g_base_info_unref ((GIBaseInfo *)ed); + } + } + + xml_end_element (file, "type"); + } + else + { + g_printerr ("Unhandled type tag %d\n", tag); + g_assert_not_reached (); + } +} + +static void +write_attributes (Xml *file, + GIBaseInfo *info) +{ + GIAttributeIter iter = { 0, }; + char *name, *value; + + while (g_base_info_iterate_attributes (info, &iter, &name, &value)) + { + xml_start_element (file, "attribute"); + xml_printf (file, " name=\"%s\" value=\"%s\"", name, value); + xml_end_element (file, "attribute"); + } +} + +static void +write_constant_value (const gchar *namespace, + GITypeInfo *info, + GArgument *argument, + Xml *file); + +static void +write_callback_info (const gchar *namespace, + GICallbackInfo *info, + Xml *file); + +static void +write_field_info (const gchar *namespace, + GIFieldInfo *info, + GIConstantInfo *branch, + Xml *file) +{ + const gchar *name; + GIFieldInfoFlags flags; + gint size; + gint offset; + GITypeInfo *type; + GIBaseInfo *interface; + GArgument value; + + name = g_base_info_get_name ((GIBaseInfo *)info); + flags = g_field_info_get_flags (info); + size = g_field_info_get_size (info); + offset = g_field_info_get_offset (info); + + xml_start_element (file, "field"); + xml_printf (file, " name=\"%s\"", name); + + /* Fields are assumed to be read-only + * (see also girwriter.py and girparser.c) + */ + if (!(flags & GI_FIELD_IS_READABLE)) + xml_printf (file, " readable=\"0\""); + if (flags & GI_FIELD_IS_WRITABLE) + xml_printf (file, " writable=\"1\""); + + if (size) + xml_printf (file, " bits=\"%d\"", size); + + write_attributes (file, (GIBaseInfo*) info); + + type = g_field_info_get_type (info); + + if (branch) + { + xml_printf (file, " branch=\""); + type = g_constant_info_get_type (branch); + g_constant_info_get_value (branch, &value); + write_constant_value (namespace, type, &value, file); + xml_printf (file, "\""); + } + + if (file->show_all) + { + if (offset >= 0) + xml_printf (file, "offset=\"%d\"", offset); + } + + interface = g_type_info_get_interface (type); + if (interface && g_base_info_get_type(interface) == GI_INFO_TYPE_CALLBACK) + write_callback_info (namespace, (GICallbackInfo *)interface, file); + else + write_type_info (namespace, type, file); + + if (interface) + g_base_info_unref (interface); + + g_base_info_unref ((GIBaseInfo *)type); + + xml_end_element (file, "field"); +} + +static void +write_callable_info (const gchar *namespace, + GICallableInfo *info, + Xml *file) +{ + GITypeInfo *type; + gint i; + + write_attributes (file, (GIBaseInfo*) info); + + type = g_callable_info_get_return_type (info); + + xml_start_element (file, "return-value"); + + switch (g_callable_info_get_caller_owns (info)) + { + case GI_TRANSFER_NOTHING: + xml_printf (file, " transfer-ownership=\"none\""); + break; + case GI_TRANSFER_CONTAINER: + xml_printf (file, " transfer-ownership=\"container\""); + break; + case GI_TRANSFER_EVERYTHING: + xml_printf (file, " transfer-ownership=\"full\""); + break; + default: + g_assert_not_reached (); + } + + if (g_callable_info_may_return_null (info)) + xml_printf (file, " allow-none=\"1\""); + + write_type_info (namespace, type, file); + + xml_end_element (file, "return-value"); + + if (g_callable_info_get_n_args (info) <= 0) + return; + + xml_start_element (file, "parameters"); + for (i = 0; i < g_callable_info_get_n_args (info); i++) + { + GIArgInfo *arg = g_callable_info_get_arg (info, i); + + xml_start_element (file, "parameter"); + xml_printf (file, " name=\"%s\"", + g_base_info_get_name ((GIBaseInfo *) arg)); + + switch (g_arg_info_get_ownership_transfer (arg)) + { + case GI_TRANSFER_NOTHING: + xml_printf (file, " transfer-ownership=\"none\""); + break; + case GI_TRANSFER_CONTAINER: + xml_printf (file, " transfer-ownership=\"container\""); + break; + case GI_TRANSFER_EVERYTHING: + xml_printf (file, " transfer-ownership=\"full\""); + break; + default: + g_assert_not_reached (); + } + + switch (g_arg_info_get_direction (arg)) + { + case GI_DIRECTION_IN: + break; + case GI_DIRECTION_OUT: + xml_printf (file, " direction=\"out\" caller-allocates=\"%s\"", + g_arg_info_is_caller_allocates (arg) ? "1" : "0"); + break; + case GI_DIRECTION_INOUT: + xml_printf (file, " direction=\"inout\""); + break; + } + + if (g_arg_info_may_be_null (arg)) + xml_printf (file, " allow-none=\"1\""); + + if (g_arg_info_is_return_value (arg)) + xml_printf (file, " retval=\"1\""); + + if (g_arg_info_is_optional (arg)) + xml_printf (file, " optional=\"1\""); + + switch (g_arg_info_get_scope (arg)) + { + case GI_SCOPE_TYPE_INVALID: + break; + case GI_SCOPE_TYPE_CALL: + xml_printf (file, " scope=\"call\""); + break; + case GI_SCOPE_TYPE_ASYNC: + xml_printf (file, " scope=\"async\""); + break; + case GI_SCOPE_TYPE_NOTIFIED: + xml_printf (file, " scope=\"notified\""); + break; + } + + if (g_arg_info_get_closure (arg) >= 0) + xml_printf (file, " closure=\"%d\"", g_arg_info_get_closure (arg)); + + if (g_arg_info_get_destroy (arg) >= 0) + xml_printf (file, " destroy=\"%d\"", g_arg_info_get_destroy (arg)); + + type = g_arg_info_get_type (arg); + write_type_info (namespace, type, file); + + xml_end_element (file, "parameter"); + + g_base_info_unref ((GIBaseInfo *)arg); + } + + xml_end_element (file, "parameters"); + g_base_info_unref ((GIBaseInfo *)type); +} + +static void +write_function_info (const gchar *namespace, + GIFunctionInfo *info, + Xml *file) +{ + GIFunctionInfoFlags flags; + const gchar *tag; + const gchar *name; + const gchar *symbol; + gboolean deprecated; + gboolean throws; + + flags = g_function_info_get_flags (info); + name = g_base_info_get_name ((GIBaseInfo *)info); + symbol = g_function_info_get_symbol (info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + throws = flags & GI_FUNCTION_THROWS; + + if (flags & GI_FUNCTION_IS_CONSTRUCTOR) + tag = "constructor"; + else if (flags & GI_FUNCTION_IS_METHOD) + tag = "method"; + else + tag = "function"; + + xml_start_element (file, tag); + xml_printf (file, " name=\"%s\" c:identifier=\"%s\"", + name, symbol); + + if (flags & GI_FUNCTION_IS_SETTER) + xml_printf (file, " type=\"setter\""); + else if (flags & GI_FUNCTION_IS_GETTER) + xml_printf (file, " type=\"getter\""); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + if (throws) + xml_printf (file, " throws=\"1\""); + + write_callable_info (namespace, (GICallableInfo*)info, file); + xml_end_element (file, tag); +} + +static void +write_callback_info (const gchar *namespace, + GICallbackInfo *info, + Xml *file) +{ + const gchar *name; + gboolean deprecated; + + name = g_base_info_get_name ((GIBaseInfo *)info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + + xml_start_element (file, "callback"); + xml_printf (file, " name=\"%s\"", name); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + write_callable_info (namespace, (GICallableInfo*)info, file); + xml_end_element (file, "callback"); +} + +static void +write_struct_info (const gchar *namespace, + GIStructInfo *info, + Xml *file) +{ + const gchar *name; + const gchar *type_name; + const gchar *type_init; + gboolean deprecated; + gboolean is_gtype_struct; + gboolean foreign; + gint i; + gint size; + int n_elts; + + name = g_base_info_get_name ((GIBaseInfo *)info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)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_BOXED) + { + xml_start_element (file, "glib:boxed"); + xml_printf (file, " glib:name=\"%s\"", name); + } + else + { + xml_start_element (file, "record"); + xml_printf (file, " name=\"%s\"", name); + } + + if (type_name != NULL) + xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + is_gtype_struct = g_struct_info_is_gtype_struct (info); + if (is_gtype_struct) + xml_printf (file, " glib:is-gtype-struct=\"1\""); + + write_attributes (file, (GIBaseInfo*) info); + + size = g_struct_info_get_size (info); + if (file->show_all && size >= 0) + xml_printf (file, " size=\"%d\"", size); + + foreign = g_struct_info_is_foreign (info); + if (foreign) + xml_printf (file, " foreign=\"1\""); + + n_elts = g_struct_info_get_n_fields (info) + g_struct_info_get_n_methods (info); + if (n_elts > 0) + { + for (i = 0; i < g_struct_info_get_n_fields (info); i++) + { + GIFieldInfo *field = g_struct_info_get_field (info, i); + write_field_info (namespace, field, NULL, file); + g_base_info_unref ((GIBaseInfo *)field); + } + + for (i = 0; i < g_struct_info_get_n_methods (info); i++) + { + GIFunctionInfo *function = g_struct_info_get_method (info, i); + write_function_info (namespace, function, file); + g_base_info_unref ((GIBaseInfo *)function); + } + + } + + xml_end_element_unchecked (file); +} + +static void +write_value_info (const gchar *namespace, + GIValueInfo *info, + Xml *file) +{ + const gchar *name; + glong value; + gboolean deprecated; + + name = g_base_info_get_name ((GIBaseInfo *)info); + value = g_value_info_get_value (info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + + xml_start_element (file, "member"); + xml_printf (file, " name=\"%s\" value=\"%ld\"", name, value); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + write_attributes (file, (GIBaseInfo*) info); + + xml_end_element (file, "member"); +} + +static void +write_constant_value (const gchar *namespace, + GITypeInfo *type, + GArgument *value, + Xml *file) +{ + switch (g_type_info_get_tag (type)) + { + case GI_TYPE_TAG_BOOLEAN: + xml_printf (file, "%d", value->v_boolean); + break; + case GI_TYPE_TAG_INT8: + xml_printf (file, "%d", value->v_int8); + break; + case GI_TYPE_TAG_UINT8: + xml_printf (file, "%d", value->v_uint8); + break; + case GI_TYPE_TAG_INT16: + xml_printf (file, "%" G_GINT16_FORMAT, value->v_int16); + break; + case GI_TYPE_TAG_UINT16: + xml_printf (file, "%" G_GUINT16_FORMAT, value->v_uint16); + break; + case GI_TYPE_TAG_INT32: + xml_printf (file, "%" G_GINT32_FORMAT, value->v_int32); + break; + case GI_TYPE_TAG_UINT32: + xml_printf (file, "%" G_GUINT32_FORMAT, value->v_uint32); + break; + case GI_TYPE_TAG_INT64: + xml_printf (file, "%" G_GINT64_FORMAT, value->v_int64); + break; + case GI_TYPE_TAG_UINT64: + xml_printf (file, "%" G_GUINT64_FORMAT, value->v_uint64); + break; + case GI_TYPE_TAG_INT: + xml_printf (file, "%d", value->v_int); + break; + case GI_TYPE_TAG_UINT: + xml_printf (file, "%d", value->v_uint); + break; + case GI_TYPE_TAG_LONG: + xml_printf (file, "%ld", value->v_long); + break; + case GI_TYPE_TAG_ULONG: + xml_printf (file, "%ld", value->v_ulong); + break; + case GI_TYPE_TAG_SSIZE: + xml_printf (file, "%zd", value->v_ssize); + break; + case GI_TYPE_TAG_SIZE: + xml_printf (file, "%zd", value->v_size); + break; + case GI_TYPE_TAG_FLOAT: + xml_printf (file, "%f", value->v_float); + break; + case GI_TYPE_TAG_DOUBLE: + xml_printf (file, "%f", value->v_double); + break; + case GI_TYPE_TAG_UTF8: + case GI_TYPE_TAG_FILENAME: + xml_printf (file, "%s", value->v_string); + break; + default: + g_assert_not_reached (); + } +} + +static void +write_constant_info (const gchar *namespace, + GIConstantInfo *info, + Xml *file) +{ + GITypeInfo *type; + const gchar *name; + gboolean deprecated; + GArgument value; + + name = g_base_info_get_name ((GIBaseInfo *)info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + + xml_start_element (file, "constant"); + xml_printf (file, " name=\"%s\"", name); + + type = g_constant_info_get_type (info); + xml_printf (file, " value=\""); + + g_constant_info_get_value (info, &value); + write_constant_value (namespace, type, &value, file); + xml_printf (file, "\""); + + write_type_info (namespace, type, file); + + write_attributes (file, (GIBaseInfo*) info); + + xml_end_element (file, "constant"); + + g_base_info_unref ((GIBaseInfo *)type); +} + + +static void +write_enum_info (const gchar *namespace, + GIEnumInfo *info, + Xml *file) +{ + const gchar *name; + 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); + + 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) + xml_start_element (file, "enumeration"); + else + xml_start_element (file, "bitfield"); + xml_printf (file, " name=\"%s\"", name); + + if (type_init) + xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + write_attributes (file, (GIBaseInfo*) info); + + for (i = 0; i < g_enum_info_get_n_values (info); i++) + { + GIValueInfo *value = g_enum_info_get_value (info, i); + write_value_info (namespace, value, file); + g_base_info_unref ((GIBaseInfo *)value); + } + + xml_end_element_unchecked (file); +} + +static void +write_signal_info (const gchar *namespace, + GISignalInfo *info, + Xml *file) +{ + GSignalFlags flags; + const gchar *name; + gboolean deprecated; + + name = g_base_info_get_name ((GIBaseInfo *)info); + flags = g_signal_info_get_flags (info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + + xml_start_element (file, "glib:signal"); + xml_printf (file, " name=\"%s\"", name); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + if (flags & G_SIGNAL_RUN_FIRST) + xml_printf (file, " when=\"FIRST\""); + else if (flags & G_SIGNAL_RUN_LAST) + xml_printf (file, " when=\"LAST\""); + else if (flags & G_SIGNAL_RUN_CLEANUP) + xml_printf (file, " when=\"CLEANUP\""); + + if (flags & G_SIGNAL_NO_RECURSE) + xml_printf (file, " no-recurse=\"1\""); + + if (flags & G_SIGNAL_DETAILED) + xml_printf (file, " detailed=\"1\""); + + if (flags & G_SIGNAL_ACTION) + xml_printf (file, " action=\"1\""); + + if (flags & G_SIGNAL_NO_HOOKS) + xml_printf (file, " no-hooks=\"1\""); + + write_callable_info (namespace, (GICallableInfo*)info, file); + + xml_end_element (file, "glib:signal"); +} + +static void +write_vfunc_info (const gchar *namespace, + GIVFuncInfo *info, + Xml *file) +{ + GIVFuncInfoFlags flags; + const gchar *name; + GIFunctionInfo *invoker; + gboolean deprecated; + gint offset; + + name = g_base_info_get_name ((GIBaseInfo *)info); + flags = g_vfunc_info_get_flags (info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + offset = g_vfunc_info_get_offset (info); + invoker = g_vfunc_info_get_invoker (info); + + xml_start_element (file, "virtual-method"); + xml_printf (file, " name=\"%s\"", name); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + if (flags & GI_VFUNC_MUST_CHAIN_UP) + xml_printf (file, " must-chain-up=\"1\""); + + if (flags & GI_VFUNC_MUST_OVERRIDE) + xml_printf (file, " override=\"always\""); + else if (flags & GI_VFUNC_MUST_NOT_OVERRIDE) + xml_printf (file, " override=\"never\""); + + xml_printf (file, " offset=\"%d\"", offset); + + if (invoker) + xml_printf (file, " invoker=\"%s\"", g_base_info_get_name ((GIBaseInfo*)invoker)); + + write_callable_info (namespace, (GICallableInfo*)info, file); + + xml_end_element (file, "virtual-method"); +} + +static void +write_property_info (const gchar *namespace, + GIPropertyInfo *info, + Xml *file) +{ + GParamFlags flags; + const gchar *name; + gboolean deprecated; + GITypeInfo *type; + + name = g_base_info_get_name ((GIBaseInfo *)info); + flags = g_property_info_get_flags (info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + + xml_start_element (file, "property"); + xml_printf (file, " name=\"%s\"", name); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + /* Properties are assumed to be read-only (see also girwriter.py) */ + if (!(flags & G_PARAM_READABLE)) + xml_printf (file, " readable=\"0\""); + if (flags & G_PARAM_WRITABLE) + xml_printf (file, " writable=\"1\""); + + if (flags & G_PARAM_CONSTRUCT) + xml_printf (file, " construct=\"1\""); + + if (flags & G_PARAM_CONSTRUCT_ONLY) + xml_printf (file, " construct-only=\"1\""); + + write_attributes (file, (GIBaseInfo*) info); + + type = g_property_info_get_type (info); + + write_type_info (namespace, type, file); + + xml_end_element (file, "property"); +} + +static void +write_object_info (const gchar *namespace, + GIObjectInfo *info, + Xml *file) +{ + const gchar *name; + const gchar *type_name; + const gchar *type_init; + gboolean deprecated; + gboolean is_abstract; + GIObjectInfo *pnode; + GIStructInfo *class_struct; + gint i; + + name = g_base_info_get_name ((GIBaseInfo *)info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + is_abstract = g_object_info_get_abstract (info); + + type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); + type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); + xml_start_element (file, "class"); + xml_printf (file, " name=\"%s\"", name); + + pnode = g_object_info_get_parent (info); + if (pnode) + { + write_type_name_attribute (namespace, (GIBaseInfo *)pnode, "parent", file); + g_base_info_unref ((GIBaseInfo *)pnode); + } + + class_struct = g_object_info_get_class_struct (info); + if (class_struct) + { + write_type_name_attribute (namespace, (GIBaseInfo*) class_struct, "glib:type-struct", file); + g_base_info_unref ((GIBaseInfo*)class_struct); + } + + if (is_abstract) + xml_printf (file, " abstract=\"1\""); + + xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + write_attributes (file, (GIBaseInfo*) info); + + if (g_object_info_get_n_interfaces (info) > 0) + { + for (i = 0; i < g_object_info_get_n_interfaces (info); i++) + { + GIInterfaceInfo *imp = g_object_info_get_interface (info, i); + xml_start_element (file, "implements"); + write_type_name_attribute (namespace, (GIBaseInfo *)imp, "name", file); + xml_end_element (file, "implements"); + g_base_info_unref ((GIBaseInfo*)imp); + } + } + + for (i = 0; i < g_object_info_get_n_fields (info); i++) + { + GIFieldInfo *field = g_object_info_get_field (info, i); + write_field_info (namespace, field, NULL, file); + g_base_info_unref ((GIBaseInfo *)field); + } + + for (i = 0; i < g_object_info_get_n_methods (info); i++) + { + GIFunctionInfo *function = g_object_info_get_method (info, i); + write_function_info (namespace, function, file); + g_base_info_unref ((GIBaseInfo *)function); + } + + for (i = 0; i < g_object_info_get_n_properties (info); i++) + { + GIPropertyInfo *prop = g_object_info_get_property (info, i); + write_property_info (namespace, prop, file); + g_base_info_unref ((GIBaseInfo *)prop); + } + + for (i = 0; i < g_object_info_get_n_signals (info); i++) + { + GISignalInfo *signal = g_object_info_get_signal (info, i); + write_signal_info (namespace, signal, file); + g_base_info_unref ((GIBaseInfo *)signal); + } + + for (i = 0; i < g_object_info_get_n_vfuncs (info); i++) + { + GIVFuncInfo *vfunc = g_object_info_get_vfunc (info, i); + write_vfunc_info (namespace, vfunc, file); + g_base_info_unref ((GIBaseInfo *)vfunc); + } + + for (i = 0; i < g_object_info_get_n_constants (info); i++) + { + GIConstantInfo *constant = g_object_info_get_constant (info, i); + write_constant_info (namespace, constant, file); + g_base_info_unref ((GIBaseInfo *)constant); + } + + xml_end_element (file, "class"); +} + +static void +write_interface_info (const gchar *namespace, + GIInterfaceInfo *info, + Xml *file) +{ + const gchar *name; + const gchar *type_name; + const gchar *type_init; + GIStructInfo *class_struct; + gboolean deprecated; + gint i; + + name = g_base_info_get_name ((GIBaseInfo *)info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + + type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); + type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); + xml_start_element (file, "interface"); + xml_printf (file, " name=\"%s\" glib:type-name=\"%s\" glib:get-type=\"%s\"", + name, type_name, type_init); + + class_struct = g_interface_info_get_iface_struct (info); + if (class_struct) + { + write_type_name_attribute (namespace, (GIBaseInfo*) class_struct, "glib:type-struct", file); + g_base_info_unref ((GIBaseInfo*)class_struct); + } + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + write_attributes (file, (GIBaseInfo*) info); + + if (g_interface_info_get_n_prerequisites (info) > 0) + { + for (i = 0; i < g_interface_info_get_n_prerequisites (info); i++) + { + GIBaseInfo *req = g_interface_info_get_prerequisite (info, i); + + xml_start_element (file, "prerequisite"); + write_type_name_attribute (namespace, req, "name", file); + + xml_end_element_unchecked (file); + g_base_info_unref (req); + } + } + + for (i = 0; i < g_interface_info_get_n_methods (info); i++) + { + GIFunctionInfo *function = g_interface_info_get_method (info, i); + write_function_info (namespace, function, file); + g_base_info_unref ((GIBaseInfo *)function); + } + + for (i = 0; i < g_interface_info_get_n_properties (info); i++) + { + GIPropertyInfo *prop = g_interface_info_get_property (info, i); + write_property_info (namespace, prop, file); + g_base_info_unref ((GIBaseInfo *)prop); + } + + for (i = 0; i < g_interface_info_get_n_signals (info); i++) + { + GISignalInfo *signal = g_interface_info_get_signal (info, i); + write_signal_info (namespace, signal, file); + g_base_info_unref ((GIBaseInfo *)signal); + } + + for (i = 0; i < g_interface_info_get_n_vfuncs (info); i++) + { + GIVFuncInfo *vfunc = g_interface_info_get_vfunc (info, i); + write_vfunc_info (namespace, vfunc, file); + g_base_info_unref ((GIBaseInfo *)vfunc); + } + + for (i = 0; i < g_interface_info_get_n_constants (info); i++) + { + GIConstantInfo *constant = g_interface_info_get_constant (info, i); + write_constant_info (namespace, constant, file); + g_base_info_unref ((GIBaseInfo *)constant); + } + + xml_end_element (file, "interface"); +} + +static void +write_error_domain_info (const gchar *namespace, + GIErrorDomainInfo *info, + Xml *file) +{ + GIBaseInfo *enum_; + const gchar *name, *quark; + + name = g_base_info_get_name ((GIBaseInfo *)info); + quark = g_error_domain_info_get_quark (info); + enum_ = (GIBaseInfo *)g_error_domain_info_get_codes (info); + xml_start_element (file, "errordomain"); + xml_printf (file, " name=\"%s\" get-quark=\"%s\"", + name, quark); + write_type_name_attribute (namespace, enum_, "codes", file); + xml_end_element (file, "errordomain"); + g_base_info_unref (enum_); +} + +static void +write_union_info (const gchar *namespace, + GIUnionInfo *info, + Xml *file) +{ + const gchar *name; + const gchar *type_name; + const gchar *type_init; + gboolean deprecated; + gint i; + gint size; + + name = g_base_info_get_name ((GIBaseInfo *)info); + deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); + + type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); + type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); + + xml_start_element (file, "union"); + xml_printf (file, " name=\"%s\"", name); + + if (type_name) + xml_printf (file, " type-name=\"%s\" get-type=\"%s\"", type_name, type_init); + + if (deprecated) + xml_printf (file, " deprecated=\"1\""); + + size = g_union_info_get_size (info); + if (file->show_all && size >= 0) + xml_printf (file, " size=\"%d\"", size); + + write_attributes (file, (GIBaseInfo*) info); + + if (g_union_info_is_discriminated (info)) + { + gint offset; + GITypeInfo *type; + + offset = g_union_info_get_discriminator_offset (info); + type = g_union_info_get_discriminator_type (info); + + xml_start_element (file, "discriminator"); + xml_printf (file, " offset=\"%d\" type=\"", offset); + write_type_info (namespace, type, file); + xml_end_element (file, "discriminator"); + g_base_info_unref ((GIBaseInfo *)type); + } + + for (i = 0; i < g_union_info_get_n_fields (info); i++) + { + GIFieldInfo *field = g_union_info_get_field (info, i); + GIConstantInfo *constant = g_union_info_get_discriminator (info, i); + write_field_info (namespace, field, constant, file); + g_base_info_unref ((GIBaseInfo *)field); + if (constant) + g_base_info_unref ((GIBaseInfo *)constant); + } + + for (i = 0; i < g_union_info_get_n_methods (info); i++) + { + GIFunctionInfo *function = g_union_info_get_method (info, i); + write_function_info (namespace, function, file); + g_base_info_unref ((GIBaseInfo *)function); + } + + xml_end_element (file, "union"); +} + + +/** + * gir_writer_write: + * @filename: filename to write to + * @namespace: GIR namespace to write + * @needs_prefix: + * @show_all: + * + * Writes the output of a typelib represented by @namespace + * into a GIR xml file named @filename. + */ +void +gir_writer_write (const char *filename, + const char *namespace, + gboolean needs_prefix, + gboolean show_all) +{ + FILE *ofile; + gint i, j; + char **dependencies; + GIRepository *repository; + Xml *xml; + + repository = g_irepository_get_default (); + + if (filename == NULL) + ofile = stdout; + else + { + gchar *full_filename; + + if (needs_prefix) + full_filename = g_strdup_printf ("%s-%s", namespace, filename); + else + full_filename = g_strdup (filename); + ofile = g_fopen (filename, "w"); + + if (ofile == NULL) + { + g_fprintf (stderr, "failed to open '%s': %s\n", + full_filename, g_strerror (errno)); + g_free (full_filename); + + return; + } + + g_free (full_filename); + } + + xml = xml_open (ofile); + xml->show_all = show_all; + xml_printf (xml, "\n"); + xml_start_element (xml, "repository"); + xml_printf (xml, " version=\"1.0\"\n" + " xmlns=\"http://www.gtk.org/introspection/core/1.0\"\n" + " xmlns:c=\"http://www.gtk.org/introspection/c/1.0\"\n" + " xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\""); + + dependencies = g_irepository_get_dependencies (repository, + namespace); + if (dependencies != NULL) + { + for (i = 0; dependencies[i]; i++) + { + char **parts = g_strsplit (dependencies[i], "-", 2); + xml_start_element (xml, "include"); + xml_printf (xml, " name=\"%s\" version=\"%s\"", parts[0], parts[1]); + xml_end_element (xml, "include"); + g_strfreev (parts); + } + } + + if (TRUE) + { + const gchar *shared_library; + const gchar *c_prefix; + const char *ns = namespace; + const char *version; + + version = g_irepository_get_version (repository, ns); + + shared_library = g_irepository_get_shared_library (repository, ns); + c_prefix = g_irepository_get_c_prefix (repository, ns); + xml_start_element (xml, "namespace"); + xml_printf (xml, " name=\"%s\" version=\"%s\"", ns, version); + if (shared_library) + xml_printf (xml, " shared-library=\"%s\"", shared_library); + if (c_prefix) + xml_printf (xml, " c:prefix=\"%s\"", c_prefix); + + for (j = 0; j < g_irepository_get_n_infos (repository, ns); j++) + { + GIBaseInfo *info = g_irepository_get_info (repository, ns, j); + switch (g_base_info_get_type (info)) + { + case GI_INFO_TYPE_FUNCTION: + write_function_info (ns, (GIFunctionInfo *)info, xml); + break; + + case GI_INFO_TYPE_CALLBACK: + write_callback_info (ns, (GICallbackInfo *)info, xml); + break; + + case GI_INFO_TYPE_STRUCT: + case GI_INFO_TYPE_BOXED: + write_struct_info (ns, (GIStructInfo *)info, xml); + break; + + case GI_INFO_TYPE_UNION: + write_union_info (ns, (GIUnionInfo *)info, xml); + break; + + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + write_enum_info (ns, (GIEnumInfo *)info, xml); + break; + + case GI_INFO_TYPE_CONSTANT: + write_constant_info (ns, (GIConstantInfo *)info, xml); + break; + + case GI_INFO_TYPE_OBJECT: + write_object_info (ns, (GIObjectInfo *)info, xml); + break; + + case GI_INFO_TYPE_INTERFACE: + write_interface_info (ns, (GIInterfaceInfo *)info, xml); + break; + + case GI_INFO_TYPE_ERROR_DOMAIN: + write_error_domain_info (ns, (GIErrorDomainInfo *)info, xml); + break; + + default: + g_error ("unknown info type %d\n", g_base_info_get_type (info)); + } + + g_base_info_unref (info); + } + + xml_end_element (xml, "namespace"); + } + + xml_end_element (xml, "repository"); + + xml_free (xml); +} diff --git a/girwriter.h b/girwriter.h index 5d41a0c6a..3ca7418b4 100644 --- a/girwriter.h +++ b/girwriter.h @@ -18,9 +18,12 @@ * Boston, MA 02111-1307, USA. */ -#ifndef __G_IDL_WRITER_H__ -#define __G_IDL_WRITER_H__ +#ifndef __GIRWRITER_H__ +#define __GIRWRITER_H__ -void g_idl_writer_save_file (GIdlModule *module, const gchar *filename); +void gir_writer_write (const char *filename, + const char *namespace, + gboolean needs_prefix, + gboolean show_all); -#endif /* __G_IDL_WRITER_H__ */ +#endif /* __GIRWRITER_H__ */ From 825c230941939166396120b659827fabf31315bc Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Mon, 7 Jun 2010 17:20:02 -0300 Subject: [PATCH 329/692] [gisignalinfo] Document and check parameters --- gisignalinfo.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/gisignalinfo.c b/gisignalinfo.c index 2333980a9..852dd5256 100644 --- a/gisignalinfo.c +++ b/gisignalinfo.c @@ -25,14 +25,38 @@ #include "girepository-private.h" #include "gitypelib-internal.h" +/** + * SECTION:gisignalinfo + * @Short_description: Struct representing a signal + * @Title: GISignalInfo + * + * GISignalInfo represents a signal. It's a sub-struct of #GICallableInfo + * and contains a set of flags and a class closure. + * + * See #GICallableInfo for information on how to retreive arguments + * and other metadata from the signal. + */ + +/** + * g_signal_info_get_flags: + * @info: a #GISignalInfo + * + * Obtain the flags for this signal info. See #GSignalFlags for + * more information about possible flag values. + * + * Returns: the flags + */ GSignalFlags g_signal_info_get_flags (GISignalInfo *info) { GSignalFlags flags; - GIRealInfo *rinfo = (GIRealInfo *)info; - SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; + SignalBlob *blob; + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_SIGNAL_INFO (info), 0); + + blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; flags = 0; if (blob->run_first) @@ -59,11 +83,26 @@ g_signal_info_get_flags (GISignalInfo *info) return flags; } +/** + * g_signal_info_get_class_closure: + * @info: a #GISignalInfo + * + * Obtain the class closure for this signal if one is set. The class + * closure is a virtual function on the type that the signal belongs to. + * If the signal lacks a closure %NULL will be returned. + * + * Returns: the class closure or %NULL + */ GIVFuncInfo * g_signal_info_get_class_closure (GISignalInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; + SignalBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_SIGNAL_INFO (info), 0); + + blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->has_class_closure) return g_interface_info_get_vfunc ((GIInterfaceInfo *)rinfo->container, blob->class_closure); @@ -71,11 +110,25 @@ g_signal_info_get_class_closure (GISignalInfo *info) return NULL; } +/** + * g_signal_info_true_stops_emit: + * @info: a #GISignalInfo + * + * Obtain if the returning true in the signal handler will + * stop the emission of the signal. + * + * Returns: %TRUE if returning true stops the signal emission + */ gboolean g_signal_info_true_stops_emit (GISignalInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; + SignalBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_SIGNAL_INFO (info), 0); + + blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->true_stops_emit; } From b2575e8210a270ba35559047501dfe680e147c5b Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 8 Jun 2010 11:25:12 -0300 Subject: [PATCH 330/692] Philip, you didn't write all of this --- girparser.c | 1 + 1 file changed, 1 insertion(+) diff --git a/girparser.c b/girparser.c index 678482c57..bda72e129 100644 --- a/girparser.c +++ b/girparser.c @@ -1,5 +1,6 @@ /* GObject introspection: A parser for the XML GIR format * + * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008 Philip Van Hoof * * This library is free software; you can redistribute it and/or From 518765acf3bd15e3f89df8eface7bdfe0f806a07 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Tue, 8 Jun 2010 16:40:35 +0200 Subject: [PATCH 331/692] Support the (transfer) annotation for properties. * girepository/*: Add g_property_info_get_ownership_transfer() and write the transfer attribute of properties into the typelib. * giscanner/*: Parse the (transfer) annotation and write it into the .gir. * tools/generate.c: Read the transfer annotation for properties and write to the .tgir. https://bugzilla.gnome.org/show_bug.cgi?id=620484 --- gipropertyinfo.c | 27 +++++++++++++++++++++++ gipropertyinfo.h | 1 + girnode.c | 2 ++ girnode.h | 2 ++ girparser.c | 42 +++++++++++++++++++++++++++++++++++ girwriter.c | 52 ++++++++++++++++++++------------------------ gitypelib-internal.h | 20 ++++++++++++----- gitypes.h | 28 +++++++++++++++++++----- 8 files changed, 134 insertions(+), 40 deletions(-) diff --git a/gipropertyinfo.c b/gipropertyinfo.c index 705a80bfa..224709d26 100644 --- a/gipropertyinfo.c +++ b/gipropertyinfo.c @@ -57,3 +57,30 @@ g_property_info_get_type (GIPropertyInfo *info) return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (PropertyBlob, type)); } +/** + * g_property_info_get_ownership_transfer: + * @info: a #GIPropertyInfo + * + * Obtain the ownership transfer for this property. See #GITransfer for more + * information about transfer values. + * + * Returns: the transfer + */ +GITransfer +g_property_info_get_ownership_transfer (GIPropertyInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + PropertyBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_PROPERTY_INFO (info), -1); + + blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->transfer_ownership) + return GI_TRANSFER_EVERYTHING; + else if (blob->transfer_container_ownership) + return GI_TRANSFER_CONTAINER; + else + return GI_TRANSFER_NOTHING; +} diff --git a/gipropertyinfo.h b/gipropertyinfo.h index 168b88ccd..487389cba 100644 --- a/gipropertyinfo.h +++ b/gipropertyinfo.h @@ -35,6 +35,7 @@ G_BEGIN_DECLS GParamFlags g_property_info_get_flags (GIPropertyInfo *info); GITypeInfo * g_property_info_get_type (GIPropertyInfo *info); +GITransfer g_property_info_get_ownership_transfer (GIPropertyInfo *info); G_END_DECLS diff --git a/girnode.c b/girnode.c index db029989d..0f5223fa0 100644 --- a/girnode.c +++ b/girnode.c @@ -1648,6 +1648,8 @@ g_ir_node_build_typelib (GIrNode *node, blob->writable = prop->writable; blob->construct = prop->construct; blob->construct_only = prop->construct_only; + blob->transfer_ownership = prop->transfer; + blob->transfer_container_ownership = prop->shallow_transfer; blob->reserved = 0; g_ir_node_build_typelib ((GIrNode *)prop->type, diff --git a/girnode.h b/girnode.h index 8c7b14eb1..038a53d78 100644 --- a/girnode.h +++ b/girnode.h @@ -178,6 +178,8 @@ struct _GIrNodeProperty gboolean writable; gboolean construct; gboolean construct_only; + gboolean transfer; + gboolean shallow_transfer; GIrNodeType *type; }; diff --git a/girparser.c b/girparser.c index bda72e129..65f038ceb 100644 --- a/girparser.c +++ b/girparser.c @@ -840,6 +840,44 @@ start_function (GMarkupParseContext *context, return TRUE; } +static void +parse_property_transfer (GIrNodeProperty *property, + const gchar *transfer, + ParseContext *ctx) +{ + if (transfer == NULL) + { + GIrNodeInterface *iface = (GIrNodeInterface *)CURRENT_NODE (ctx); + + g_warning ("required attribute 'transfer-ownership' for property '%s' in " + "type '%s.%s'", property->node.name, ctx->namespace, + iface->node.name); + } + else if (strcmp (transfer, "none") == 0) + { + property->transfer = FALSE; + property->shallow_transfer = FALSE; + } + else if (strcmp (transfer, "container") == 0) + { + property->transfer = FALSE; + property->shallow_transfer = TRUE; + } + else if (strcmp (transfer, "full") == 0) + { + property->transfer = TRUE; + property->shallow_transfer = FALSE; + } + else + { + GIrNodeInterface *iface = (GIrNodeInterface *)CURRENT_NODE (ctx); + + g_warning ("Unknown transfer-ownership value: '%s' for property '%s' in " + "type '%s.%s'", transfer, property->node.name, ctx->namespace, + iface->node.name); + } +} + static void parse_param_transfer (GIrNodeParam *param, const gchar *transfer, const gchar *name) { @@ -1237,12 +1275,14 @@ start_property (GMarkupParseContext *context, const gchar *writable; const gchar *construct; const gchar *construct_only; + const gchar *transfer; name = find_attribute ("name", attribute_names, attribute_values); readable = find_attribute ("readable", attribute_names, attribute_values); writable = find_attribute ("writable", attribute_names, attribute_values); construct = find_attribute ("construct", attribute_names, attribute_values); construct_only = find_attribute ("construct-only", attribute_names, attribute_values); + transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); @@ -1274,6 +1314,8 @@ start_property (GMarkupParseContext *context, else property->construct_only = FALSE; + parse_property_transfer (property, transfer, ctx); + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); iface->members = g_list_append (iface->members, property); diff --git a/girwriter.c b/girwriter.c index 6fa892db2..ca68f57bb 100644 --- a/girwriter.c +++ b/girwriter.c @@ -187,6 +187,26 @@ write_type_name_attribute (const gchar *namespace, xml_printf (file, "\""); } + static void +write_ownership_transfer (GITransfer transfer, + Xml *file) +{ + switch (transfer) + { + case GI_TRANSFER_NOTHING: + xml_printf (file, " transfer-ownership=\"none\""); + break; + case GI_TRANSFER_CONTAINER: + xml_printf (file, " transfer-ownership=\"container\""); + break; + case GI_TRANSFER_EVERYTHING: + xml_printf (file, " transfer-ownership=\"full\""); + break; + default: + g_assert_not_reached (); + } +} + static void write_type_info (const gchar *namespace, GITypeInfo *info, @@ -443,20 +463,7 @@ write_callable_info (const gchar *namespace, xml_start_element (file, "return-value"); - switch (g_callable_info_get_caller_owns (info)) - { - case GI_TRANSFER_NOTHING: - xml_printf (file, " transfer-ownership=\"none\""); - break; - case GI_TRANSFER_CONTAINER: - xml_printf (file, " transfer-ownership=\"container\""); - break; - case GI_TRANSFER_EVERYTHING: - xml_printf (file, " transfer-ownership=\"full\""); - break; - default: - g_assert_not_reached (); - } + write_ownership_transfer (g_callable_info_get_caller_owns (info), file); if (g_callable_info_may_return_null (info)) xml_printf (file, " allow-none=\"1\""); @@ -477,20 +484,7 @@ write_callable_info (const gchar *namespace, xml_printf (file, " name=\"%s\"", g_base_info_get_name ((GIBaseInfo *) arg)); - switch (g_arg_info_get_ownership_transfer (arg)) - { - case GI_TRANSFER_NOTHING: - xml_printf (file, " transfer-ownership=\"none\""); - break; - case GI_TRANSFER_CONTAINER: - xml_printf (file, " transfer-ownership=\"container\""); - break; - case GI_TRANSFER_EVERYTHING: - xml_printf (file, " transfer-ownership=\"full\""); - break; - default: - g_assert_not_reached (); - } + write_ownership_transfer (g_arg_info_get_ownership_transfer (arg), file); switch (g_arg_info_get_direction (arg)) { @@ -968,6 +962,8 @@ write_property_info (const gchar *namespace, if (flags & G_PARAM_CONSTRUCT_ONLY) xml_printf (file, " construct-only=\"1\""); + write_ownership_transfer (g_property_info_get_ownership_transfer (info), file); + write_attributes (file, (GIBaseInfo*) info); type = g_property_info_get_type (info); diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 0524efa13..bb920ac66 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -815,17 +815,25 @@ typedef struct { * @writable: * @construct: * @construct_only: The ParamFlags used when registering the property. + * @transfer_ownership: When writing, the type containing the property takes + * ownership of the value. When reading, the returned value needs to be released + * by the caller. + * @transfer_container_ownership: For container types indicates that the + * ownership of the container, but not of its contents, is transferred. This is + * typically the case when reading lists of statically allocated things. * @type: Describes the type of the property. */ typedef struct { guint32 name; - guint32 deprecated : 1; - guint32 readable : 1; - guint32 writable : 1; - guint32 construct : 1; - guint32 construct_only : 1; - guint32 reserved :27; + guint32 deprecated : 1; + guint32 readable : 1; + guint32 writable : 1; + guint32 construct : 1; + guint32 construct_only : 1; + guint32 transfer_ownership : 1; + guint32 transfer_container_ownership : 1; + guint32 reserved :25; guint32 reserved2; diff --git a/gitypes.h b/gitypes.h index 78becaef2..5ef64ca16 100644 --- a/gitypes.h +++ b/gitypes.h @@ -241,13 +241,29 @@ typedef enum /** * GITransfer: - * @GI_TRANSFER_NOTHING: transfer nothing to the caller - * @GI_TRANSFER_CONTAINER: transfer the container (eg list, array, - * hashtable), but no the contents to the caller. - * @GI_TRANSFER_EVERYTHING: transfer everything to the caller. + * @GI_TRANSFER_NOTHING: transfer nothing from the callee (function or the type + * instance the property belongs to) to the caller. The callee retains the + * ownership of the transfer and the caller doesn't need to do anything to free + * up the resources of this transfer. + * @GI_TRANSFER_CONTAINER: transfer the container (list, array, hash table) from + * the callee to the caller. The callee retains the ownership of the individual + * items in the container and the caller has to free up the container resources + * (g_list_free()/g_hash_table_destroy() etc) of this transfer. + * @GI_TRANSFER_EVERYTHING: transfer everything, eg the container and its + * contents from the callee to the caller. This is the case when the callee + * creates a copy of all the data it returns. The caller is responsible for + * cleaning up the container and item resources of this transfer. * - * Represent the transfer ownership information of a #GICallableInfo or - * a #GIArgInfo. + * The transfer is the exchange of data between two parts, from the callee to + * the caller. The callee is either a function/method/signal or an + * object/interface where a property is defined. The caller is the side + * accessing a property or calling a function. + * #GITransfer specifies who's responsible for freeing the resources after the + * ownership transfer is complete. In case of a containing type such as a list, + * an array or a hash table the container itself is specified differently from + * the items within the container itself. Each container is freed differently, + * check the documentation for the types themselves for information on how to + * free them. */ typedef enum { GI_TRANSFER_NOTHING, From ba97c98827016121ef27dc30a420844bfc3ebab2 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Tue, 8 Jun 2010 19:20:06 +0200 Subject: [PATCH 332/692] Use a default value for transfer-ownership in properties. --- girparser.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/girparser.c b/girparser.c index 65f038ceb..9823228ec 100644 --- a/girparser.c +++ b/girparser.c @@ -847,13 +847,16 @@ parse_property_transfer (GIrNodeProperty *property, { if (transfer == NULL) { +#if 0 GIrNodeInterface *iface = (GIrNodeInterface *)CURRENT_NODE (ctx); - g_warning ("required attribute 'transfer-ownership' for property '%s' in " - "type '%s.%s'", property->node.name, ctx->namespace, - iface->node.name); + g_debug ("required attribute 'transfer-ownership' is missing from " + "property '%s' in type '%s.%s'. Assuming 'none'\n", + property->node.name, ctx->namespace, iface->node.name); +#endif + transfer = "none"; } - else if (strcmp (transfer, "none") == 0) + if (strcmp (transfer, "none") == 0) { property->transfer = FALSE; property->shallow_transfer = FALSE; From d9bbf572b006c74844151694783bfa07f7cae713 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Wed, 9 Jun 2010 10:26:26 +0200 Subject: [PATCH 333/692] Allow for methods in GLib * girepository/gitypelib.c: Don't complain about constructors returning types other than objects or interfaces if the container type isn't an object or interface itself. * giscanner/glibtransformer.py: Don't give up parsing a method just because it's in the GLib namespace. https://bugzilla.gnome.org/show_bug.cgi?id=621069 --- gitypelib.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gitypelib.c b/gitypelib.c index 1b3f882ec..6aa3077c4 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -832,13 +832,16 @@ validate_function_blob (ValidateContext *ctx, iface_type = get_type_blob (typelib, simple, error); if (!iface_type) return FALSE; - if (!(iface_type->tag == GI_TYPE_TAG_INTERFACE)) + if (iface_type->tag != GI_TYPE_TAG_INTERFACE && + (container_type == BLOB_TYPE_OBJECT || + container_type == BLOB_TYPE_INTERFACE)) { g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID, - "Invalid return type %d for constructor", - iface_type->tag); + "Invalid return type '%s' for constructor '%s'", + g_type_tag_to_string (iface_type->tag), + get_string_nofail (typelib, blob->symbol)); return FALSE; } } From 4af59a4c04aae3f4b6b333a11f99a24f0a1d4056 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 11 Jun 2010 11:10:52 -0300 Subject: [PATCH 334/692] [GIPropertyInfo] Document and check args --- gipropertyinfo.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/gipropertyinfo.c b/gipropertyinfo.c index 224709d26..d5cfe22d3 100644 --- a/gipropertyinfo.c +++ b/gipropertyinfo.c @@ -25,12 +25,35 @@ #include "girepository-private.h" #include "gitypelib-internal.h" +/** + * SECTION:gipropertyinfo + * @Short_description: Struct representing a property + * @Title: GIPropertyInfo + * + * GIPropertyInfo represents a property. A property belongs to + * either a #GIObjectInfo or a #GIInterfaceInfo. + */ + +/** + * g_property_info_get_flags: + * @info: a #GIPropertyInfo + * + * Obtain the flags for this property info. See #GParamFags for + * more information about possible flag values. + * + * Returns: the flags + */ GParamFlags g_property_info_get_flags (GIPropertyInfo *info) { GParamFlags flags; GIRealInfo *rinfo = (GIRealInfo *)info; - PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset]; + PropertyBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_PROPERTY_INFO (info), 0); + + blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset]; flags = 0; @@ -49,12 +72,28 @@ g_property_info_get_flags (GIPropertyInfo *info) return flags; } +/** + * g_property_info_get_type: + * @info: a #GIPropertyInfo + * + * Obtain the type information for the property @info. + * + * Returns: (transfer full): the #GIPropertyInfo, free it with + * g_base_info_unref() when done. + * + * Returns: the type + */ GITypeInfo * g_property_info_get_type (GIPropertyInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (PropertyBlob, type)); + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_PROPERTY_INFO (info), NULL); + + return _g_type_info_new ((GIBaseInfo*)info, + rinfo->typelib, + rinfo->offset + G_STRUCT_OFFSET (PropertyBlob, type)); } /** From 5a0016133ae42ed042e0669a0ccab6ffde90d2dc Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 11 Jun 2010 11:11:01 -0300 Subject: [PATCH 335/692] [GIVFuncInfo] Document and check args --- givfuncinfo.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 6 deletions(-) diff --git a/givfuncinfo.c b/givfuncinfo.c index fe5c00cff..3990ea944 100644 --- a/givfuncinfo.c +++ b/givfuncinfo.c @@ -27,6 +27,15 @@ #include "girepository-private.h" #include "gitypelib-internal.h" +/** + * SECTION:givfuncinfo + * @Short_description: Struct representing a virtual function + * @Title: GIVFuncInfo + * + * GIVfuncInfo represents a virtual function. A property belongs to + * either a #GIObjectInfo or a #GIInterfaceInfo. + */ + GIVFuncInfo * _g_base_info_find_vfunc (GIRealInfo *rinfo, guint32 offset, @@ -52,13 +61,26 @@ _g_base_info_find_vfunc (GIRealInfo *rinfo, return NULL; } +/** + * g_vfunc_info_get_flags: + * @info: a #GIVFuncInfo + * + * Obtain the flags for this virtual function info. See #GIVFuncInfoFlags for + * more information about possible flag values. + * + * Returns: the flags + */ GIVFuncInfoFlags g_vfunc_info_get_flags (GIVFuncInfo *info) { GIVFuncInfoFlags flags; - GIRealInfo *rinfo = (GIRealInfo *)info; - VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; + VFuncBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_VFUNC_INFO (info), 0); + + blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; flags = 0; @@ -74,20 +96,49 @@ g_vfunc_info_get_flags (GIVFuncInfo *info) return flags; } +/** + * g_vfunc_info_get_offset: + * @info: a #GIVFuncInfo + * + * Obtain the offset of the function pointer in the class struct. The value + * 0xFFFF indicates that the struct offset is unknown. + * + * Returns: the struct offset or 0xFFFF if it's unknown + */ gint g_vfunc_info_get_offset (GIVFuncInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; + VFuncBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_VFUNC_INFO (info), 0); + + blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->struct_offset; } +/** + * g_vfunc_info_get_signal: + * @info: a #GIVFuncInfo + * + * Obtain the signal for the virtual function if one is set. + * The signal comes from the object or interface to which + * this virtual function belongs. + * + * Returns: the signal or %NULL if none set + */ GISignalInfo * g_vfunc_info_get_signal (GIVFuncInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; + VFuncBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_VFUNC_INFO (info), 0); + + blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->class_closure) return g_interface_info_get_signal ((GIInterfaceInfo *)rinfo->container, blob->signal); @@ -111,14 +162,20 @@ GIFunctionInfo * g_vfunc_info_get_invoker (GIVFuncInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; - GIBaseInfo *container = rinfo->container; + VFuncBlob *blob; + GIBaseInfo *container; GIInfoType parent_type; + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_VFUNC_INFO (info), 0); + + blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; + /* 1023 = 0x3ff is the maximum of the 10 bits for invoker index */ if (blob->invoker == 1023) return NULL; + container = rinfo->container; parent_type = g_base_info_get_type (container); if (parent_type == GI_INFO_TYPE_OBJECT) return g_object_info_get_method ((GIObjectInfo*)container, blob->invoker); From 1eca3abe67fd043c57d7dce2bd49711d604438e9 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 11 Jun 2010 20:16:00 -0300 Subject: [PATCH 336/692] [docs] Add struct hierarchy to each section --- giarginfo.c | 8 +++++++- gibaseinfo.c | 15 +++++++++++++++ gicallableinfo.c | 10 ++++++++++ giconstantinfo.c | 8 ++++++++ gienuminfo.c | 9 +++++++++ gierrordomaininfo.c | 8 ++++++++ gifieldinfo.c | 8 ++++++++ gifunctioninfo.c | 11 +++++++++++ gipropertyinfo.c | 8 ++++++++ giregisteredtypeinfo.c | 13 +++++++++++++ gisignalinfo.c | 11 +++++++++++ gitypeinfo.c | 8 ++++++++ givfuncinfo.c | 11 +++++++++++ 13 files changed, 127 insertions(+), 1 deletion(-) diff --git a/giarginfo.c b/giarginfo.c index 40dcd52b5..dc1d1162e 100644 --- a/giarginfo.c +++ b/giarginfo.c @@ -35,7 +35,13 @@ * GIArgInfo represents an argument. An argument is always * part of a #GICallableInfo. * - * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GIArgInfo + * + * */ /** diff --git a/gibaseinfo.c b/gibaseinfo.c index 5cb153234..c8444a5ea 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -180,6 +180,21 @@ _g_type_info_init (GIBaseInfo *info, * * * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GIArgInfo + * +----GICallableInfo + * +----GIConstantInfo + * +----GIErrorDomainInfo + * +----GIFieldInfo + * +----GIPropertyInfo + * +----GIRegisteredTypeInfo + * +----GITypeInfo + * + * + * */ /** diff --git a/gicallableinfo.c b/gicallableinfo.c index da6b50b05..845b3db9f 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -39,6 +39,16 @@ * A callable has a list of arguments (#GIArgInfo), a return type, * direction and a flag which decides if it returns null. * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GICallableInfo + * +----GIFunctionInfo + * +----GISignalInfo + * +----GIVFuncInfo + * + * */ static guint32 diff --git a/giconstantinfo.c b/giconstantinfo.c index 551e73cd5..4a3b838d7 100644 --- a/giconstantinfo.c +++ b/giconstantinfo.c @@ -33,6 +33,14 @@ * GIConstantInfo represents a constant. A constant has a type associated * which can be obtained by calling g_constant_info_get_type() and a value, * which can be obtained by calling g_constant_info_get_value(). + * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GIConstantInfo + * + * */ diff --git a/gienuminfo.c b/gienuminfo.c index ac8f09249..9ecbc2aba 100644 --- a/gienuminfo.c +++ b/gienuminfo.c @@ -33,6 +33,15 @@ * A GIEnumInfo represents an enumeration and a GIValueInfo struct represents a value * of an enumeration. The GIEnumInfo contains a set of values and a type * The GIValueInfo is fetched by calling g_enum_info_get_value() on a #GIEnumInfo. + * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GIRegisteredTypeInfo + * +----GIEnumInfo + * + * */ /** diff --git a/gierrordomaininfo.c b/gierrordomaininfo.c index aa06719ff..86e40c59b 100644 --- a/gierrordomaininfo.c +++ b/gierrordomaininfo.c @@ -33,6 +33,14 @@ * A GIErrorDomainInfo struct represents a domain of a #GError. * An error domain is associated with a #GQuark and contains a pointer * to an enum with all the error codes. + * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GIErrorDomainInfo + * + * */ /** diff --git a/gifieldinfo.c b/gifieldinfo.c index a902e6f67..14e371f87 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -37,6 +37,14 @@ * or g_object_info_get_value(). * A field has a size, type and a struct offset asssociated and a set of flags, * which is currently #GI_FIELD_IS_READABLE or #GI_FIELD_IS_WRITABLE. + * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GIFieldInfo + * + * */ /** diff --git a/gifunctioninfo.c b/gifunctioninfo.c index 33852801f..736537024 100644 --- a/gifunctioninfo.c +++ b/gifunctioninfo.c @@ -39,6 +39,17 @@ * * See also #GICallableInfo for information on how to retreive arguments and * other metadata. + * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GICallableInfo + * +----GIFunctionInfo + * +----GISignalInfo + * +----GIVFuncInfo + * + * */ GIFunctionInfo * diff --git a/gipropertyinfo.c b/gipropertyinfo.c index d5cfe22d3..9fe485c23 100644 --- a/gipropertyinfo.c +++ b/gipropertyinfo.c @@ -32,6 +32,14 @@ * * GIPropertyInfo represents a property. A property belongs to * either a #GIObjectInfo or a #GIInterfaceInfo. + * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GIPropertyInfo + * + * */ /** diff --git a/giregisteredtypeinfo.c b/giregisteredtypeinfo.c index fe159cf8d..cc43d284e 100644 --- a/giregisteredtypeinfo.c +++ b/giregisteredtypeinfo.c @@ -40,6 +40,19 @@ * To get the name call g_registered_type_info_get_type_name(). * Most users want to call g_registered_type_info_get_g_type() and don't worry * about the rest of the details. + * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GIRegisteredTypeInfo + * +----GIEnumInfo + * +----GIInterfaceInfo + * +----GIObjectInfo + * +----GIStructInfo + * +----GIUnionInfo + * + * */ /** diff --git a/gisignalinfo.c b/gisignalinfo.c index 852dd5256..b19d98e9c 100644 --- a/gisignalinfo.c +++ b/gisignalinfo.c @@ -35,6 +35,17 @@ * * See #GICallableInfo for information on how to retreive arguments * and other metadata from the signal. + * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GICallableInfo + * +----GIFunctionInfo + * +----GISignalInfo + * +----GIVFuncInfo + * + * */ /** diff --git a/gitypeinfo.c b/gitypeinfo.c index 68c3dc108..4904c2ba9 100644 --- a/gitypeinfo.c +++ b/gitypeinfo.c @@ -40,6 +40,14 @@ * g_type_info_get_interface() to get a reference to the base info for that * interface. * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GITypeInfo + * + * + * */ /** diff --git a/givfuncinfo.c b/givfuncinfo.c index 3990ea944..da86ed4df 100644 --- a/givfuncinfo.c +++ b/givfuncinfo.c @@ -34,6 +34,17 @@ * * GIVfuncInfo represents a virtual function. A property belongs to * either a #GIObjectInfo or a #GIInterfaceInfo. + * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GICallableInfo + * +----GIFunctionInfo + * +----GISignalInfo + * +----GIVFuncInfo + * + * */ GIVFuncInfo * From d89eb019747f75b352abc3cc91ddcc0bcf73e51f Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 11 Jun 2010 20:16:29 -0300 Subject: [PATCH 337/692] [GICallableInfo] Fix a typo in the doc --- gicallableinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gicallableinfo.c b/gicallableinfo.c index 845b3db9f..6097cb483 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -34,7 +34,7 @@ * * GICallableInfo represents an entity which is callable. * Currently a function (#GIFunctionInfo), virtual function, - * (#GIVirtualFunc) or callback (#GICallbackInfo). + * (#GIVFuncInfo) or callback (#GICallbackInfo). * * A callable has a list of arguments (#GIArgInfo), a return type, * direction and a flag which decides if it returns null. From 55c7dc37ac0d245d8fcd38f92bafc53561f01ca6 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 11 Jun 2010 20:51:32 -0300 Subject: [PATCH 338/692] [GIObjectInfo] Document and check types --- giobjectinfo.c | 364 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 333 insertions(+), 31 deletions(-) diff --git a/giobjectinfo.c b/giobjectinfo.c index 6f9e04612..dc26709ed 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -25,12 +25,46 @@ #include "girepository-private.h" #include "gitypelib-internal.h" -/* GIObjectInfo functions */ +/** + * SECTION:giobjectinfo + * @Short_description: Struct representing a GObject + * @Title: GIObjectInfo + * + * GIPropertyInfo represents a #GObject. This doesn't represent a specific + * instance of a GObject, instead this represent the object type (eg class). + * + * A GObject has methods, fields, properties, signals, interfaces, constants + * and virtual functions. + * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GIRegisteredTypeInfo + * +----GIObjectInfo + * + * + */ + +/** + * g_object_info_get_parent: + * @info: a #GIObjectInfo + * + * Obtain the parent of the object type. + * + * Returns: (transfer full): the #GIObjectInfo. Free the struct by calling + * g_base_info_unref() when done. + */ GIObjectInfo * g_object_info_get_parent (GIObjectInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->parent) return (GIObjectInfo *) _g_info_from_entry (rinfo->repository, @@ -39,69 +73,168 @@ g_object_info_get_parent (GIObjectInfo *info) return NULL; } +/** + * g_object_info_get_abstract: + * @info: a #GIObjectInfo + * + * Obtain if the object type is an abstract type, eg if it cannot be + * instantiated + * + * Returns: %TRUE if the object type is abstract + */ gboolean -g_object_info_get_abstract (GIObjectInfo *info) +g_object_info_get_abstract (GIObjectInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), FALSE); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + return blob->abstract != 0; } +/** + * g_object_info_get_type_name: + * @info: a #GIObjectInfo + * + * Obtain the name of the objects class/type. + * + * Returns: name of the objects type + */ const gchar * g_object_info_get_type_name (GIObjectInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return g_typelib_get_string (rinfo->typelib, blob->gtype_name); } +/** + * g_object_info_get_type_init: + * @info: a #GIObjectInfo + * + * Obtain the function which when called will return the GType + * function for which this object type is registered. + * + * Returns: the type init function + */ const gchar * g_object_info_get_type_init (GIObjectInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return g_typelib_get_string (rinfo->typelib, blob->gtype_init); } +/** + * g_object_info_get_n_interfaces: + * @info: a #GIObjectInfo + * + * Obtain the number of interfaces that this object type has. + * + * Returns: number of interfaces + */ gint g_object_info_get_n_interfaces (GIObjectInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_interfaces; } +/** + * g_object_info_get_interface: + * @info: a #GIObjectInfo + * @n: index of interface to get + * + * Obtain an object type interface at index @n. + * + * Returns: (transfer full): the #GIInterfaceInfo. Free the struct by calling + * g_base_info_unref() when done. + */ GIInterfaceInfo * g_object_info_get_interface (GIObjectInfo *info, gint n) { GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return (GIInterfaceInfo *) _g_info_from_entry (rinfo->repository, rinfo->typelib, blob->interfaces[n]); } +/** + * g_object_info_get_n_fields: + * @info: a #GIObjectInfo + * + * Obtain the number of fields that this object type has. + * + * Returns: number of fields + */ gint g_object_info_get_n_fields (GIObjectInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_fields; } +/** + * g_object_info_get_field: + * @info: a #GIObjectInfo + * @n: index of field to get + * + * Obtain an object type field at index @n. + * + * Returns: (transfer full): the #GIFieldInfo. Free the struct by calling + * g_base_info_unref() when done. + */ GIFieldInfo * g_object_info_get_field (GIObjectInfo *info, gint n) { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + header = (Header *)rinfo->typelib->data; + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 @@ -110,23 +243,51 @@ g_object_info_get_field (GIObjectInfo *info, return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, offset); } +/** + * g_object_info_get_n_properties: + * @info: a #GIObjectInfo + * + * Obtain the number of properties that this object type has. + * + * Returns: number of properties + */ gint g_object_info_get_n_properties (GIObjectInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + ObjectBlob *blob; + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_properties; } +/** + * g_object_info_get_property: + * @info: a #GIObjectInfo + * @n: index of property to get + * + * Obtain an object type property at index @n. + * + * Returns: (transfer full): the #GIPropertyInfo. Free the struct by calling + * g_base_info_unref() when done. + */ GIPropertyInfo * g_object_info_get_property (GIObjectInfo *info, gint n) { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + header = (Header *)rinfo->typelib->data; + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 @@ -137,23 +298,53 @@ g_object_info_get_property (GIObjectInfo *info, rinfo->typelib, offset); } +/** + * g_object_info_get_n_methods: + * @info: a #GIObjectInfo + * + * Obtain the number of methods that this object type has. + * + * Returns: number of methods + */ gint g_object_info_get_n_methods (GIObjectInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_methods; } +/** + * g_object_info_get_method: + * @info: a #GIObjectInfo + * @n: index of method to get + * + * Obtain an object type method at index @n. + * + * Returns: (transfer full): the #GIFunctionInfo. Free the struct by calling + * g_base_info_unref() when done. + */ GIFunctionInfo * g_object_info_get_method (GIObjectInfo *info, gint n) { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + header = (Header *)rinfo->typelib->data; + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 @@ -165,14 +356,27 @@ g_object_info_get_method (GIObjectInfo *info, rinfo->typelib, offset); } +/** + * g_object_info_find_method: + * @info: a #GIObjectInfo + * + * Returns: (transfer full): the #GIFunctionInfo. Free the struct by calling + * g_base_info_unref() when done. + */ GIFunctionInfo * g_object_info_find_method (GIObjectInfo *info, const gchar *name) { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0); + + header = (Header *)rinfo->typelib->data; + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 @@ -182,23 +386,52 @@ g_object_info_find_method (GIObjectInfo *info, return _g_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_methods, name); } +/** + * g_object_info_get_n_signals: + * @info: a #GIObjectInfo + * + * Obtain the number of signals that this object type has. + * + * Returns: number of signals + */ gint g_object_info_get_n_signals (GIObjectInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_signals; } +/** + * g_object_info_get_signal: + * @info: a #GIObjectInfo + * @n: index of signal to get + * + * Obtain an object type signal at index @n. + * + * Returns: (transfer full): the #GISignalInfo. Free the struct by calling + * g_base_info_unref() when done. + */ GISignalInfo * g_object_info_get_signal (GIObjectInfo *info, gint n) { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + header = (Header *)rinfo->typelib->data; + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 @@ -211,23 +444,52 @@ g_object_info_get_signal (GIObjectInfo *info, rinfo->typelib, offset); } +/** + * g_object_info_get_n_vfuncs: + * @info: a #GIObjectInfo + * + * Obtain the number of virtual functions that this object type has. + * + * Returns: number of virtual functions + */ gint g_object_info_get_n_vfuncs (GIObjectInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_vfuncs; } +/** + * g_object_info_get_vfunc: + * @info: a #GIObjectInfo + * @n: index of virtual function to get + * + * Obtain an object type virtual function at index @n. + * + * Returns: (transfer full): the #GIVFuncInfo. Free the struct by calling + * g_base_info_unref() when done. + */ GIVFuncInfo * g_object_info_get_vfunc (GIObjectInfo *info, gint n) { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + header = (Header *)rinfo->typelib->data; + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 @@ -263,8 +525,14 @@ g_object_info_find_vfunc (GIObjectInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + header = (Header *)rinfo->typelib->data; + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 @@ -276,23 +544,52 @@ g_object_info_find_vfunc (GIObjectInfo *info, return _g_base_info_find_vfunc (rinfo, offset, blob->n_vfuncs, name); } +/** + * g_object_info_get_n_constants: + * @info: a #GIObjectInfo + * + * Obtain the number of constants that this object type has. + * + * Returns: number of constants + */ gint g_object_info_get_n_constants (GIObjectInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_constants; } +/** + * g_object_info_get_constant: + * @info: a #GIObjectInfo + * @n: index of constant to get + * + * Obtain an object type constant at index @n. + * + * Returns: (transfer full): the #GIConstantInfo. Free the struct by calling + * g_base_info_unref() when done. + */ GIConstantInfo * g_object_info_get_constant (GIObjectInfo *info, gint n) { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + header = (Header *)rinfo->typelib->data; + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; offset = rinfo->offset + header->object_blob_size + (blob->n_interfaces + blob->n_interfaces % 2) * 2 @@ -321,7 +618,12 @@ GIStructInfo * g_object_info_get_class_struct (GIObjectInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->gtype_struct) return (GIStructInfo *) _g_info_from_entry (rinfo->repository, From bd0c9a41706683c8ee7bedc2123767d0786bcc48 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 11 Jun 2010 21:05:42 -0300 Subject: [PATCH 339/692] [gitypelib-internal.h] Add missing --- gitypelib-internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitypelib-internal.h b/gitypelib-internal.h index bb920ac66..90113ac2c 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -397,7 +397,7 @@ typedef struct { guint scope : 3; /* */ guint reserved :21; - + /* */ gint8 closure; gint8 destroy; From 2e570b770409950c2a3992b8b50e6a1942ce6fd5 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 11 Jun 2010 21:06:02 -0300 Subject: [PATCH 340/692] [g_property_info_get_flags] Document properly --- gipropertyinfo.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gipropertyinfo.c b/gipropertyinfo.c index 9fe485c23..552c0c3e2 100644 --- a/gipropertyinfo.c +++ b/gipropertyinfo.c @@ -86,10 +86,8 @@ g_property_info_get_flags (GIPropertyInfo *info) * * Obtain the type information for the property @info. * - * Returns: (transfer full): the #GIPropertyInfo, free it with + * Returns: (transfer full): the #GITypeInfo, free it with * g_base_info_unref() when done. - * - * Returns: the type */ GITypeInfo * g_property_info_get_type (GIPropertyInfo *info) From a9a1fdabd804c9947fe6ec6788169256aa57268d Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 11 Jun 2010 21:06:31 -0300 Subject: [PATCH 341/692] [gir_writer_write] Document properly --- girwriter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/girwriter.c b/girwriter.c index ca68f57bb..712456027 100644 --- a/girwriter.c +++ b/girwriter.c @@ -1254,8 +1254,8 @@ write_union_info (const gchar *namespace, * gir_writer_write: * @filename: filename to write to * @namespace: GIR namespace to write - * @needs_prefix: - * @show_all: + * @needs_prefix: if the filename needs prefixing + * @show_all: if field size calculations should be included * * Writes the output of a typelib represented by @namespace * into a GIR xml file named @filename. From 401baff470b3b24af7eb812f29b5d43a9e8446d4 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 12 Jun 2010 11:14:22 -0300 Subject: [PATCH 342/692] [GIObjectInfo] Fix a typo and document a func --- giobjectinfo.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/giobjectinfo.c b/giobjectinfo.c index dc26709ed..ace8d5d4b 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -30,7 +30,7 @@ * @Short_description: Struct representing a GObject * @Title: GIObjectInfo * - * GIPropertyInfo represents a #GObject. This doesn't represent a specific + * GIObjectInfo represents a #GObject. This doesn't represent a specific * instance of a GObject, instead this represent the object type (eg class). * * A GObject has methods, fields, properties, signals, interfaces, constants @@ -359,6 +359,10 @@ g_object_info_get_method (GIObjectInfo *info, /** * g_object_info_find_method: * @info: a #GIObjectInfo + * @name: name of method to obtain + * + * Obtain a method of the object type given a @name. %NULL will be + * returned if there's no method available with that name. * * Returns: (transfer full): the #GIFunctionInfo. Free the struct by calling * g_base_info_unref() when done. From 9313f23ed51ea8182e3842d75dc8fd03ac57ba18 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 12 Jun 2010 11:14:36 -0300 Subject: [PATCH 343/692] [GIVInterfaceInfo] Document and check args --- giinterfaceinfo.c | 259 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 238 insertions(+), 21 deletions(-) diff --git a/giinterfaceinfo.c b/giinterfaceinfo.c index ba8f43f85..e3e721d8b 100644 --- a/giinterfaceinfo.c +++ b/giinterfaceinfo.c @@ -25,44 +25,123 @@ #include "girepository-private.h" #include "gitypelib-internal.h" +/** + * SECTION:giinterfaceinfo + * @Short_description: Struct representing a GInterface + * @Title: GIInterfaceInfo + * + * GIInterfaceInfo represents a #GInterface type. + * + * A GInterface has methods, fields, properties, signals, interfaces, constants, + * virtual functions and prerequisites. + * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GIRegisteredTypeInfo + * +----GIInterfaceInfo + * + * + */ + +/** + * g_interface_info_get_n_prerequisites: + * @info: a #GIInterfaceInfo + * + * Obtain the number of prerequisites for this interface type. + * A prerequisites is another interface that needs to be implemented for + * interface, similar to an base class for GObjects. + * + * Returns: number of prerequisites + */ gint g_interface_info_get_n_prerequisites (GIInterfaceInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + InterfaceBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), 0); + + blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_prerequisites; } +/** + * g_interface_info_get_prerequisite: + * @info: a #GIInterfaceInfo + * @n: index of prerequisites to get + * + * Obtain an interface type prerequisites index @n. + * + * Returns: (transfer full): the prerequisites as a #GIBaseInfo. Free the struct by calling + * g_base_info_unref() when done. + */ GIBaseInfo * g_interface_info_get_prerequisite (GIInterfaceInfo *info, gint n) { GIRealInfo *rinfo = (GIRealInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + InterfaceBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL); + + blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; return _g_info_from_entry (rinfo->repository, rinfo->typelib, blob->prerequisites[n]); } +/** + * g_interface_info_get_n_properties: + * @info: a #GIInterfaceInfo + * + * Obtain the number of properties that this interface type has. + * + * Returns: number of properties + */ gint g_interface_info_get_n_properties (GIInterfaceInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + InterfaceBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), 0); + + blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_properties; } +/** + * g_interface_info_get_property: + * @info: a #GIInterfaceInfo + * @n: index of property to get + * + * Obtain an interface type property at index @n. + * + * Returns: (transfer full): the #GIPropertyInfo. Free the struct by calling + * g_base_info_unref() when done. + */ GIPropertyInfo * g_interface_info_get_property (GIInterfaceInfo *info, gint n) { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header; + InterfaceBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL); + + header = (Header *)rinfo->typelib->data; + blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 @@ -72,23 +151,52 @@ g_interface_info_get_property (GIInterfaceInfo *info, rinfo->typelib, offset); } +/** + * g_interface_info_get_n_methods: + * @info: a #GIInterfaceInfo + * + * Obtain the number of methods that this interface type has. + * + * Returns: number of methods + */ gint g_interface_info_get_n_methods (GIInterfaceInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + InterfaceBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), 0); + + blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_methods; } +/** + * g_interface_info_get_method: + * @info: a #GIInterfaceInfo + * @n: index of method to get + * + * Obtain an interface type method at index @n. + * + * Returns: (transfer full): the #GIFunctionInfo. Free the struct by calling + * g_base_info_unref() when done. + */ GIFunctionInfo * g_interface_info_get_method (GIInterfaceInfo *info, gint n) { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header; + InterfaceBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL); + + header = (Header *)rinfo->typelib->data; + blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 @@ -99,6 +207,17 @@ g_interface_info_get_method (GIInterfaceInfo *info, rinfo->typelib, offset); } +/** + * g_interface_info_find_method: + * @info: a #GIInterfaceInfo + * @name: name of method to obtain + * + * Obtain a method of the interface type given a @name. %NULL will be + * returned if there's no method available with that name. + * + * Returns: (transfer full): the #GIFunctionInfo or %NULL if none found. + * Free the struct by calling g_base_info_unref() when done. + */ GIFunctionInfo * g_interface_info_find_method (GIInterfaceInfo *info, const gchar *name) @@ -115,23 +234,52 @@ g_interface_info_find_method (GIInterfaceInfo *info, return _g_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_methods, name); } +/** + * g_interface_info_get_n_signals: + * @info: a #GIInterfaceInfo + * + * Obtain the number of signals that this interface type has. + * + * Returns: number of signals + */ gint g_interface_info_get_n_signals (GIInterfaceInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + InterfaceBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), 0); + + blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_signals; } +/** + * g_interface_info_get_signal: + * @info: a #GIInterfaceInfo + * @n: index of signal to get + * + * Obtain an interface type signal at index @n. + * + * Returns: (transfer full): the #GISignalInfo. Free the struct by calling + * g_base_info_unref() when done. + */ GISignalInfo * g_interface_info_get_signal (GIInterfaceInfo *info, gint n) { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header; + InterfaceBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL); + + header = (Header *)rinfo->typelib->data; + blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 @@ -143,23 +291,52 @@ g_interface_info_get_signal (GIInterfaceInfo *info, rinfo->typelib, offset); } +/** + * g_interface_info_get_n_vfuncs: + * @info: a #GIInterfaceInfo + * + * Obtain the number of virtual functions that this interface type has. + * + * Returns: number of virtual functions + */ gint g_interface_info_get_n_vfuncs (GIInterfaceInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + InterfaceBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), 0); + + blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_vfuncs; } +/** + * g_interface_info_get_vfunc: + * @info: a #GIInterfaceInfo + * @n: index of virtual function to get + * + * Obtain an interface type virtual function at index @n. + * + * Returns: (transfer full): the #GIVFuncInfo. Free the struct by calling + * g_base_info_unref() when done. + */ GIVFuncInfo * g_interface_info_get_vfunc (GIInterfaceInfo *info, gint n) { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header; + InterfaceBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL); + + header = (Header *)rinfo->typelib->data; + blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 @@ -174,7 +351,7 @@ g_interface_info_get_vfunc (GIInterfaceInfo *info, /** * g_interface_info_find_vfunc: - * @info: a #GIObjectInfo + * @info: a #GIInterfaceInfo * @name: The name of a virtual function to find. * * Locate a virtual function slot with name @name. See the documentation @@ -189,8 +366,14 @@ g_interface_info_find_vfunc (GIInterfaceInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header; + InterfaceBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL); + + header = (Header *)rinfo->typelib->data; + blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + blob->n_prerequisites % 2) * 2 @@ -201,23 +384,52 @@ g_interface_info_find_vfunc (GIInterfaceInfo *info, return _g_base_info_find_vfunc (rinfo, offset, blob->n_vfuncs, name); } +/** + * g_interface_info_get_n_constants: + * @info: a #GIInterfaceInfo + * + * Obtain the number of constants that this interface type has. + * + * Returns: number of constants + */ gint g_interface_info_get_n_constants (GIInterfaceInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + InterfaceBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), 0); + + blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->n_constants; } +/** + * g_interface_info_get_constant: + * @info: a #GIInterfaceInfo + * @n: index of constant to get + * + * Obtain an interface type constant at index @n. + * + * Returns: (transfer full): the #GIConstantInfo. Free the struct by calling + * g_base_info_unref() when done. + */ GIConstantInfo * g_interface_info_get_constant (GIInterfaceInfo *info, gint n) { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header; + InterfaceBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL); + + header = (Header *)rinfo->typelib->data; + blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; offset = rinfo->offset + header->interface_blob_size + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2 @@ -244,7 +456,12 @@ GIStructInfo * g_interface_info_get_iface_struct (GIInterfaceInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; - InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; + InterfaceBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_INTERFACE_INFO (info), NULL); + + blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset]; if (blob->gtype_struct) return (GIStructInfo *) _g_info_from_entry (rinfo->repository, From adcb85871b91232f43a7a3cf7424e573b339c6e1 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 12 Jun 2010 11:22:26 -0300 Subject: [PATCH 344/692] [girwriter] Use GSlice --- girwriter.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/girwriter.c b/girwriter.c index 712456027..b123a1345 100644 --- a/girwriter.c +++ b/girwriter.c @@ -1,4 +1,3 @@ - /* -*- Mode: C; c-file-style: "gnu"; -*- */ /* GObject introspection: IDL generator * @@ -49,7 +48,7 @@ xml_element_new (const char *name) { XmlElement *elem; - elem = g_new (XmlElement, 1); + elem = g_slice_new (XmlElement); elem->name = g_strdup (name); elem->has_children = FALSE; return elem; @@ -59,7 +58,7 @@ static void xml_element_free (XmlElement *elem) { g_free (elem->name); - g_free (elem); + g_slice_free (XmlElement, elem); } static void @@ -127,7 +126,7 @@ xml_open (FILE *file) { Xml *xml; - xml = g_new (Xml, 1); + xml = g_slice_new (Xml); xml->file = file; xml->stack = NULL; @@ -151,7 +150,7 @@ static void xml_free (Xml *xml) { xml_close (xml); - g_free (xml); + g_slice_free (Xml, xml); } From 1223ef35603402fd4419b619533b7fd64cdbae15 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 12 Jun 2010 11:31:06 -0300 Subject: [PATCH 345/692] [girparser] Annotate return transfer for public API --- girparser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/girparser.c b/girparser.c index 9823228ec..d0bd8aa36 100644 --- a/girparser.c +++ b/girparser.c @@ -3375,7 +3375,7 @@ post_filter (GIrModule *module) * Parse a string that holds a complete GIR XML file, and return a list of a * a #GirModule for each <namespace/> element within the file. * - * Returns: a newly allocated list of #GIrModule. The modules themselves + * Returns: (transfer container): a newly allocated list of #GIrModule. The modules themselves * are owned by the #GIrParser and will be freed along with the parser. */ GList * @@ -3446,7 +3446,7 @@ g_ir_parser_parse_string (GIrParser *parser, * Parse GIR XML file, and return a list of a a #GirModule for each * <namespace/> element within the file. * - * Returns: a newly allocated list of #GIrModule. The modules themselves + * Returns: (transfer container): a newly allocated list of #GIrModule. The modules themselves * are owned by the #GIrParser and will be freed along with the parser. */ GList * From 97c497bfeaed3994073e931a211a64762b4832df Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 16 Jun 2010 20:34:18 -0400 Subject: [PATCH 346/692] Support introspectable=no attribute, add warnings framework This work allows us to move closer to replacing gtk-doc, among other things. We add a generic attribute "introspectable", and inside the typelib compiler if we see "introspectable=no", we don't put it in the typelib. This replaces the hackish pre-filter for varargs with a much more generic mechanism. The varargs is now handled in the scanner, and we emit introspectable=no for them. Add generic metadata to Node with references to file/line/column, which currently comes from symbols. Add scanner options --Wall and --Werror. --- girparser.c | 1633 ++++++++++++++++++++++++--------------------------- girparser.h | 1 + 2 files changed, 764 insertions(+), 870 deletions(-) diff --git a/girparser.c b/girparser.c index d0bd8aa36..a0c1e21dd 100644 --- a/girparser.c +++ b/girparser.c @@ -72,10 +72,10 @@ typedef enum STATE_NAMESPACE_CONSTANT, STATE_CLASS_CONSTANT, STATE_INTERFACE_CONSTANT, - STATE_ALIAS, + STATE_ALIAS, /* 30 */ STATE_TYPE, STATE_ATTRIBUTE, - STATE_UNKNOWN + STATE_PASSTHROUGH } ParseState; typedef struct _ParseContext ParseContext; @@ -93,12 +93,12 @@ struct _ParseContext GHashTable *aliases; GHashTable *disguised_structures; + const char *file_path; const char *namespace; const char *c_prefix; GIrModule *current_module; GSList *node_stack; GIrNode *current_typed; - gboolean is_varargs; GList *type_stack; GList *type_parameters; int type_depth; @@ -317,7 +317,7 @@ find_attribute (const gchar *name, static void state_switch (ParseContext *ctx, ParseState newstate) { - g_debug ("State: %d", newstate); + g_assert (ctx->state != newstate); ctx->prev_state = ctx->state; ctx->state = newstate; } @@ -339,6 +339,7 @@ pop_node (ParseContext *ctx) static void push_node (ParseContext *ctx, GIrNode *node) { + g_assert (node != NULL); g_debug ("pushing node %d %s", node->type, node->name); ctx->node_stack = g_slist_prepend (ctx->node_stack, node); } @@ -629,6 +630,32 @@ parse_type (ParseContext *ctx, const gchar *type) return node; } +static gboolean +introspectable_prelude (GMarkupParseContext *context, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + ParseState new_state) +{ + const gchar *introspectable_arg; + gboolean introspectable; + + g_assert (ctx->state != STATE_PASSTHROUGH); + + introspectable_arg = find_attribute ("introspectable", attribute_names, attribute_values); + introspectable = !(introspectable_arg && atoi (introspectable_arg) == 0); + + if (introspectable) + state_switch (ctx, new_state); + else + { + state_switch (ctx, STATE_PASSTHROUGH); + ctx->unknown_depth = 1; + } + + return introspectable; +} + static gboolean start_glib_boxed (GMarkupParseContext *context, const gchar *element_name, @@ -647,6 +674,9 @@ start_glib_boxed (GMarkupParseContext *context, ctx->state == STATE_NAMESPACE)) return FALSE; + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_BOXED)) + return TRUE; + name = find_attribute ("glib:name", attribute_names, attribute_values); typename = find_attribute ("glib:type-name", attribute_names, attribute_values); typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); @@ -682,8 +712,6 @@ start_glib_boxed (GMarkupParseContext *context, ctx->current_module->entries = g_list_append (ctx->current_module->entries, boxed); - state_switch (ctx, STATE_BOXED); - return TRUE; } @@ -722,7 +750,6 @@ start_function (GMarkupParseContext *context, strcmp (element_name, "callback") == 0); break; case STATE_STRUCT_FIELD: - ctx->in_embedded_type = TRUE; found = (found || strcmp (element_name, "callback") == 0); break; default: @@ -732,6 +759,12 @@ start_function (GMarkupParseContext *context, if (!found) return FALSE; + if (ctx->state == STATE_STRUCT_FIELD) + ctx->in_embedded_type = TRUE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION)) + return TRUE; + name = find_attribute ("name", attribute_names, attribute_values); symbol = find_attribute ("c:identifier", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); @@ -835,7 +868,6 @@ start_function (GMarkupParseContext *context, } push_node(ctx, (GIrNode *)function); - state_switch (ctx, STATE_FUNCTION); return TRUE; } @@ -1218,47 +1250,47 @@ start_enum (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if ((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) || - (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE)) + const gchar *name; + const gchar *typename; + const gchar *typeinit; + const gchar *deprecated; + GIrNodeEnum *enum_; + + if (!((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) || + (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE))) + return FALSE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_ENUM)) + return TRUE; + + name = find_attribute ("name", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) { - const gchar *name; - const gchar *typename; - const gchar *typeinit; - const gchar *deprecated; - - name = find_attribute ("name", attribute_names, attribute_values); - typename = find_attribute ("glib:type-name", attribute_names, attribute_values); - typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { - GIrNodeEnum *enum_; - - if (strcmp (element_name, "enumeration") == 0) - enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM); - else - enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS); - ((GIrNode *)enum_)->name = g_strdup (name); - enum_->gtype_name = g_strdup (typename); - enum_->gtype_init = g_strdup (typeinit); - if (deprecated) - enum_->deprecated = TRUE; - else - enum_->deprecated = FALSE; - - push_node (ctx, (GIrNode *) enum_); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, enum_); - - state_switch (ctx, STATE_ENUM); - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; + + if (strcmp (element_name, "enumeration") == 0) + enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM); + else + enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS); + ((GIrNode *)enum_)->name = g_strdup (name); + enum_->gtype_name = g_strdup (typename); + enum_->gtype_init = g_strdup (typeinit); + if (deprecated) + enum_->deprecated = TRUE; + else + enum_->deprecated = FALSE; + + push_node (ctx, (GIrNode *) enum_); + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, enum_); + + return TRUE; } static gboolean @@ -1269,70 +1301,74 @@ start_property (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "property") == 0 && - (ctx->state == STATE_CLASS || - ctx->state == STATE_INTERFACE)) + ParseState target_state; + const gchar *name; + const gchar *readable; + const gchar *writable; + const gchar *construct; + const gchar *construct_only; + const gchar *transfer; + GIrNodeProperty *property; + GIrNodeInterface *iface; + + if (!(strcmp (element_name, "property") == 0 && + (ctx->state == STATE_CLASS || + ctx->state == STATE_INTERFACE))) + return FALSE; + + if (ctx->state == STATE_CLASS) + target_state = STATE_CLASS_PROPERTY; + else if (ctx->state == STATE_INTERFACE) + target_state = STATE_INTERFACE_PROPERTY; + else + g_assert_not_reached (); + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, target_state)) + return TRUE; + + + name = find_attribute ("name", attribute_names, attribute_values); + readable = find_attribute ("readable", attribute_names, attribute_values); + writable = find_attribute ("writable", attribute_names, attribute_values); + construct = find_attribute ("construct", attribute_names, attribute_values); + construct_only = find_attribute ("construct-only", attribute_names, attribute_values); + transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); + + if (name == NULL) { - const gchar *name; - const gchar *readable; - const gchar *writable; - const gchar *construct; - const gchar *construct_only; - const gchar *transfer; - - name = find_attribute ("name", attribute_names, attribute_values); - readable = find_attribute ("readable", attribute_names, attribute_values); - writable = find_attribute ("writable", attribute_names, attribute_values); - construct = find_attribute ("construct", attribute_names, attribute_values); - construct_only = find_attribute ("construct-only", attribute_names, attribute_values); - transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { - GIrNodeProperty *property; - GIrNodeInterface *iface; - - property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY); - ctx->current_typed = (GIrNode*) property; - - ((GIrNode *)property)->name = g_strdup (name); - - /* Assume properties are readable */ - if (readable == NULL || strcmp (readable, "1") == 0) - property->readable = TRUE; - else - property->readable = FALSE; - if (writable && strcmp (writable, "1") == 0) - property->writable = TRUE; - else - property->writable = FALSE; - if (construct && strcmp (construct, "1") == 0) - property->construct = TRUE; - else - property->construct = FALSE; - if (construct_only && strcmp (construct_only, "1") == 0) - property->construct_only = TRUE; - else - property->construct_only = FALSE; - - parse_property_transfer (property, transfer, ctx); - - iface = (GIrNodeInterface *)CURRENT_NODE (ctx); - iface->members = g_list_append (iface->members, property); - - if (ctx->state == STATE_CLASS) - state_switch (ctx, STATE_CLASS_PROPERTY); - else if (ctx->state == STATE_INTERFACE) - state_switch (ctx, STATE_INTERFACE_PROPERTY); - else - g_assert_not_reached (); - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; + + property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY); + ctx->current_typed = (GIrNode*) property; + + ((GIrNode *)property)->name = g_strdup (name); + + /* Assume properties are readable */ + if (readable == NULL || strcmp (readable, "1") == 0) + property->readable = TRUE; + else + property->readable = FALSE; + if (writable && strcmp (writable, "1") == 0) + property->writable = TRUE; + else + property->writable = FALSE; + if (construct && strcmp (construct, "1") == 0) + property->construct = TRUE; + else + property->construct = FALSE; + if (construct_only && strcmp (construct_only, "1") == 0) + property->construct_only = TRUE; + else + property->construct_only = FALSE; + + parse_property_transfer (property, transfer, ctx); + + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); + iface->members = g_list_append (iface->members, property); + + return TRUE; } static gint @@ -1366,42 +1402,41 @@ start_member (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "member") == 0 && - ctx->state == STATE_ENUM) + const gchar *name; + const gchar *value; + const gchar *deprecated; + GIrNodeEnum *enum_; + GIrNodeValue *value_; + + if (!(strcmp (element_name, "member") == 0 && + ctx->state == STATE_ENUM)) + return FALSE; + + name = find_attribute ("name", attribute_names, attribute_values); + value = find_attribute ("value", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) { - const gchar *name; - const gchar *value; - const gchar *deprecated; - - name = find_attribute ("name", attribute_names, attribute_values); - value = find_attribute ("value", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { - GIrNodeEnum *enum_; - GIrNodeValue *value_; - - value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE); - - ((GIrNode *)value_)->name = g_strdup (name); - - value_->value = parse_value (value); - - if (deprecated) - value_->deprecated = TRUE; - else - value_->deprecated = FALSE; - - enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx); - enum_->values = g_list_append (enum_->values, value_); - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; + + value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE); + + ((GIrNode *)value_)->name = g_strdup (name); + + value_->value = parse_value (value); + + if (deprecated) + value_->deprecated = TRUE; + else + value_->deprecated = FALSE; + + enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx); + enum_->values = g_list_append (enum_->values, value_); + + return TRUE; } static gboolean @@ -1412,73 +1447,81 @@ start_constant (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "constant") == 0 && - (ctx->state == STATE_NAMESPACE || - ctx->state == STATE_CLASS || - ctx->state == STATE_INTERFACE)) + ParseState prev_state; + ParseState target_state; + const gchar *name; + const gchar *value; + const gchar *deprecated; + GIrNodeConstant *constant; + + if (!(strcmp (element_name, "constant") == 0 && + (ctx->state == STATE_NAMESPACE || + ctx->state == STATE_CLASS || + ctx->state == STATE_INTERFACE))) + return FALSE; + + switch (ctx->state) { - const gchar *name; - const gchar *value; - const gchar *deprecated; - - name = find_attribute ("name", attribute_names, attribute_values); - value = find_attribute ("value", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else if (value == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "value"); - else - { - GIrNodeConstant *constant; - - constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT); - - ((GIrNode *)constant)->name = g_strdup (name); - constant->value = g_strdup (value); - - ctx->current_typed = (GIrNode*) constant; - - if (deprecated) - constant->deprecated = TRUE; - else - constant->deprecated = FALSE; - - if (ctx->state == STATE_NAMESPACE) - { - push_node (ctx, (GIrNode *) constant); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, constant); - } - else - { - GIrNodeInterface *iface; - - iface = (GIrNodeInterface *)CURRENT_NODE (ctx); - iface->members = g_list_append (iface->members, constant); - } - - switch (ctx->state) - { - case STATE_NAMESPACE: - state_switch (ctx, STATE_NAMESPACE_CONSTANT); - break; - case STATE_CLASS: - state_switch (ctx, STATE_CLASS_CONSTANT); - break; - case STATE_INTERFACE: - state_switch (ctx, STATE_INTERFACE_CONSTANT); - break; - default: - g_assert_not_reached (); - break; - } - } - - return TRUE; + case STATE_NAMESPACE: + target_state = STATE_NAMESPACE_CONSTANT; + break; + case STATE_CLASS: + target_state = STATE_CLASS_CONSTANT; + break; + case STATE_INTERFACE: + target_state = STATE_INTERFACE_CONSTANT; + break; + default: + g_assert_not_reached (); } - return FALSE; + + prev_state = ctx->state; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, target_state)) + return TRUE; + + name = find_attribute ("name", attribute_names, attribute_values); + value = find_attribute ("value", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; + } + else if (value == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "value"); + return FALSE; + } + + constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT); + + ((GIrNode *)constant)->name = g_strdup (name); + constant->value = g_strdup (value); + + ctx->current_typed = (GIrNode*) constant; + + if (deprecated) + constant->deprecated = TRUE; + else + constant->deprecated = FALSE; + + if (prev_state == STATE_NAMESPACE) + { + push_node (ctx, (GIrNode *) constant); + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, constant); + } + else + { + GIrNodeInterface *iface; + + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); + iface->members = g_list_append (iface->members, constant); + } + + return TRUE; } static gboolean @@ -1489,50 +1532,57 @@ start_errordomain (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "errordomain") == 0 && - ctx->state == STATE_NAMESPACE) + const gchar *name; + const gchar *getquark; + const gchar *codes; + const gchar *deprecated; + GIrNodeErrorDomain *domain; + + if (!(strcmp (element_name, "errordomain") == 0 && + ctx->state == STATE_NAMESPACE)) + return FALSE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_ERRORDOMAIN)) + return TRUE; + + + name = find_attribute ("name", attribute_names, attribute_values); + getquark = find_attribute ("get-quark", attribute_names, attribute_values); + codes = find_attribute ("codes", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) { - const gchar *name; - const gchar *getquark; - const gchar *codes; - const gchar *deprecated; - - name = find_attribute ("name", attribute_names, attribute_values); - getquark = find_attribute ("get-quark", attribute_names, attribute_values); - codes = find_attribute ("codes", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else if (getquark == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "getquark"); - else if (codes == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "codes"); - else - { - GIrNodeErrorDomain *domain; - - domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN); - - ((GIrNode *)domain)->name = g_strdup (name); - domain->getquark = g_strdup (getquark); - domain->codes = g_strdup (codes); - - if (deprecated) - domain->deprecated = TRUE; - else - domain->deprecated = FALSE; - - push_node (ctx, (GIrNode *) domain); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, domain); - - state_switch (ctx, STATE_ERRORDOMAIN); - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; + else if (getquark == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "getquark"); + return FALSE; + } + else if (codes == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "codes"); + return FALSE; + } + + domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN); + + ((GIrNode *)domain)->name = g_strdup (name); + domain->getquark = g_strdup (getquark); + domain->codes = g_strdup (codes); + + if (deprecated) + domain->deprecated = TRUE; + else + domain->deprecated = FALSE; + + push_node (ctx, (GIrNode *) domain); + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, domain); + + return TRUE; } static gboolean @@ -1543,52 +1593,57 @@ start_interface (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "interface") == 0 && - ctx->state == STATE_NAMESPACE) + const gchar *name; + const gchar *typename; + const gchar *typeinit; + const gchar *deprecated; + const gchar *glib_type_struct; + GIrNodeInterface *iface; + + if (!(strcmp (element_name, "interface") == 0 && + ctx->state == STATE_NAMESPACE)) + return FALSE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_INTERFACE)) + return TRUE; + + name = find_attribute ("name", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) { - const gchar *name; - const gchar *typename; - const gchar *typeinit; - const gchar *deprecated; - const gchar *glib_type_struct; - - name = find_attribute ("name", attribute_names, attribute_values); - typename = find_attribute ("glib:type-name", attribute_names, attribute_values); - typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); - glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else if (typename == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); - else if (typeinit == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); - else - { - GIrNodeInterface *iface; - - iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE); - ((GIrNode *)iface)->name = g_strdup (name); - iface->gtype_name = g_strdup (typename); - iface->gtype_init = g_strdup (typeinit); - iface->glib_type_struct = g_strdup (glib_type_struct); - if (deprecated) - iface->deprecated = TRUE; - else - iface->deprecated = FALSE; - - push_node (ctx, (GIrNode *) iface); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, iface); - - state_switch (ctx, STATE_INTERFACE); - - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; + else if (typename == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); + return FALSE; + } + else if (typeinit == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); + return FALSE; + } + + iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE); + ((GIrNode *)iface)->name = g_strdup (name); + iface->gtype_name = g_strdup (typename); + iface->gtype_init = g_strdup (typeinit); + iface->glib_type_struct = g_strdup (glib_type_struct); + if (deprecated) + iface->deprecated = TRUE; + else + iface->deprecated = FALSE; + + push_node (ctx, (GIrNode *) iface); + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, iface); + + return TRUE; } static gboolean @@ -1599,58 +1654,64 @@ start_class (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "class") == 0 && - ctx->state == STATE_NAMESPACE) + const gchar *name; + const gchar *parent; + const gchar *glib_type_struct; + const gchar *typename; + const gchar *typeinit; + const gchar *deprecated; + const gchar *abstract; + GIrNodeInterface *iface; + + if (!(strcmp (element_name, "class") == 0 && + ctx->state == STATE_NAMESPACE)) + return FALSE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_CLASS)) + return TRUE; + + name = find_attribute ("name", attribute_names, attribute_values); + parent = find_attribute ("parent", attribute_names, attribute_values); + glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + abstract = find_attribute ("abstract", attribute_names, attribute_values); + + if (name == NULL) { - const gchar *name; - const gchar *parent; - const gchar *glib_type_struct; - const gchar *typename; - const gchar *typeinit; - const gchar *deprecated; - const gchar *abstract; - - name = find_attribute ("name", attribute_names, attribute_values); - parent = find_attribute ("parent", attribute_names, attribute_values); - glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values); - typename = find_attribute ("glib:type-name", attribute_names, attribute_values); - typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - abstract = find_attribute ("abstract", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else if (typename == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); - else if (typeinit == NULL && strcmp (typename, "GObject")) - MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); - else - { - GIrNodeInterface *iface; - - iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT); - ((GIrNode *)iface)->name = g_strdup (name); - iface->gtype_name = g_strdup (typename); - iface->gtype_init = g_strdup (typeinit); - iface->parent = g_strdup (parent); - iface->glib_type_struct = g_strdup (glib_type_struct); - if (deprecated) - iface->deprecated = TRUE; - else - iface->deprecated = FALSE; - - iface->abstract = abstract && strcmp (abstract, "1") == 0; - - push_node (ctx, (GIrNode *) iface); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, iface); - - state_switch (ctx, STATE_CLASS); - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; + else if (typename == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); + return FALSE; + } + else if (typeinit == NULL && strcmp (typename, "GObject")) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); + return FALSE; + } + + iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT); + ((GIrNode *)iface)->name = g_strdup (name); + iface->gtype_name = g_strdup (typename); + iface->gtype_init = g_strdup (typeinit); + iface->parent = g_strdup (parent); + iface->glib_type_struct = g_strdup (glib_type_struct); + if (deprecated) + iface->deprecated = TRUE; + else + iface->deprecated = FALSE; + + iface->abstract = abstract && strcmp (abstract, "1") == 0; + + push_node (ctx, (GIrNode *) iface); + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, iface); + + return TRUE; } static gboolean @@ -1695,47 +1756,6 @@ start_type (GMarkupParseContext *context, { state_switch (ctx, STATE_TYPE); ctx->type_depth = 1; - if (is_varargs) - { - switch (CURRENT_NODE (ctx)->type) - { - case G_IR_NODE_FUNCTION: - case G_IR_NODE_CALLBACK: - { - GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx); - func->is_varargs = TRUE; - } - break; - case G_IR_NODE_VFUNC: - { - GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx); - vfunc->is_varargs = TRUE; - } - break; - /* list others individually rather than with default: so that compiler - * warns if new node types are added without adding them to the switch - */ - case G_IR_NODE_INVALID: - case G_IR_NODE_ENUM: - case G_IR_NODE_FLAGS: - case G_IR_NODE_CONSTANT: - case G_IR_NODE_ERROR_DOMAIN: - case G_IR_NODE_PARAM: - case G_IR_NODE_TYPE: - case G_IR_NODE_PROPERTY: - case G_IR_NODE_SIGNAL: - case G_IR_NODE_VALUE: - case G_IR_NODE_FIELD: - case G_IR_NODE_XREF: - case G_IR_NODE_STRUCT: - case G_IR_NODE_BOXED: - case G_IR_NODE_OBJECT: - case G_IR_NODE_INTERFACE: - case G_IR_NODE_UNION: - g_assert_not_reached (); - break; - } - } ctx->type_stack = NULL; ctx->type_parameters = NULL; } @@ -2005,53 +2025,51 @@ start_return_value (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "return-value") == 0 && - ctx->state == STATE_FUNCTION) + GIrNodeParam *param; + const gchar *transfer; + + if (!(strcmp (element_name, "return-value") == 0 && + ctx->state == STATE_FUNCTION)) + return FALSE; + + param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM); + param->in = FALSE; + param->out = FALSE; + param->retval = TRUE; + + ctx->current_typed = (GIrNode*) param; + + state_switch (ctx, STATE_FUNCTION_RETURN); + + transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); + parse_param_transfer (param, transfer, NULL); + + switch (CURRENT_NODE (ctx)->type) { - GIrNodeParam *param; - const gchar *transfer; - - param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM); - param->in = FALSE; - param->out = FALSE; - param->retval = TRUE; - - ctx->current_typed = (GIrNode*) param; - - state_switch (ctx, STATE_FUNCTION_RETURN); - - transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); - parse_param_transfer (param, transfer, NULL); - - switch (CURRENT_NODE (ctx)->type) - { - case G_IR_NODE_FUNCTION: - case G_IR_NODE_CALLBACK: - { - GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx); - func->result = param; - } - break; - case G_IR_NODE_SIGNAL: - { - GIrNodeSignal *signal = (GIrNodeSignal *)CURRENT_NODE (ctx); - signal->result = param; - } - break; - case G_IR_NODE_VFUNC: - { - GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx); - vfunc->result = param; - } - break; - default: - g_assert_not_reached (); - } - - return TRUE; + case G_IR_NODE_FUNCTION: + case G_IR_NODE_CALLBACK: + { + GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx); + func->result = param; + } + break; + case G_IR_NODE_SIGNAL: + { + GIrNodeSignal *signal = (GIrNodeSignal *)CURRENT_NODE (ctx); + signal->result = param; + } + break; + case G_IR_NODE_VFUNC: + { + GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx); + vfunc->result = param; + } + break; + default: + g_assert_not_reached (); } - return FALSE; + return TRUE; } static gboolean @@ -2092,78 +2110,78 @@ start_glib_signal (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "glib:signal") == 0 && - (ctx->state == STATE_CLASS || - ctx->state == STATE_INTERFACE)) + const gchar *name; + const gchar *when; + const gchar *no_recurse; + const gchar *detailed; + const gchar *action; + const gchar *no_hooks; + const gchar *has_class_closure; + GIrNodeInterface *iface; + GIrNodeSignal *signal; + + if (!(strcmp (element_name, "glib:signal") == 0 && + (ctx->state == STATE_CLASS || + ctx->state == STATE_INTERFACE))) + return FALSE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION)) + return TRUE; + + name = find_attribute ("name", attribute_names, attribute_values); + when = find_attribute ("when", attribute_names, attribute_values); + no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values); + detailed = find_attribute ("detailed", attribute_names, attribute_values); + action = find_attribute ("action", attribute_names, attribute_values); + no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values); + has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values); + + if (name == NULL) { - const gchar *name; - const gchar *when; - const gchar *no_recurse; - const gchar *detailed; - const gchar *action; - const gchar *no_hooks; - const gchar *has_class_closure; - - name = find_attribute ("name", attribute_names, attribute_values); - when = find_attribute ("when", attribute_names, attribute_values); - no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values); - detailed = find_attribute ("detailed", attribute_names, attribute_values); - action = find_attribute ("action", attribute_names, attribute_values); - no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values); - has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { - GIrNodeInterface *iface; - GIrNodeSignal *signal; - - signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL); - - ((GIrNode *)signal)->name = g_strdup (name); - - signal->run_first = FALSE; - signal->run_last = FALSE; - signal->run_cleanup = FALSE; - if (when == NULL || strcmp (when, "LAST") == 0) - signal->run_last = TRUE; - else if (strcmp (when, "FIRST") == 0) - signal->run_first = TRUE; - else - signal->run_cleanup = TRUE; - - if (no_recurse && strcmp (no_recurse, "1") == 0) - signal->no_recurse = TRUE; - else - signal->no_recurse = FALSE; - if (detailed && strcmp (detailed, "1") == 0) - signal->detailed = TRUE; - else - signal->detailed = FALSE; - if (action && strcmp (action, "1") == 0) - signal->action = TRUE; - else - signal->action = FALSE; - if (no_hooks && strcmp (no_hooks, "1") == 0) - signal->no_hooks = TRUE; - else - signal->no_hooks = FALSE; - if (has_class_closure && strcmp (has_class_closure, "1") == 0) - signal->has_class_closure = TRUE; - else - signal->has_class_closure = FALSE; - - iface = (GIrNodeInterface *)CURRENT_NODE (ctx); - iface->members = g_list_append (iface->members, signal); - - push_node (ctx, (GIrNode *)signal); - state_switch (ctx, STATE_FUNCTION); - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; + signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL); + + ((GIrNode *)signal)->name = g_strdup (name); + + signal->run_first = FALSE; + signal->run_last = FALSE; + signal->run_cleanup = FALSE; + if (when == NULL || strcmp (when, "LAST") == 0) + signal->run_last = TRUE; + else if (strcmp (when, "FIRST") == 0) + signal->run_first = TRUE; + else + signal->run_cleanup = TRUE; + + if (no_recurse && strcmp (no_recurse, "1") == 0) + signal->no_recurse = TRUE; + else + signal->no_recurse = FALSE; + if (detailed && strcmp (detailed, "1") == 0) + signal->detailed = TRUE; + else + signal->detailed = FALSE; + if (action && strcmp (action, "1") == 0) + signal->action = TRUE; + else + signal->action = FALSE; + if (no_hooks && strcmp (no_hooks, "1") == 0) + signal->no_hooks = TRUE; + else + signal->no_hooks = FALSE; + if (has_class_closure && strcmp (has_class_closure, "1") == 0) + signal->has_class_closure = TRUE; + else + signal->has_class_closure = FALSE; + + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); + iface->members = g_list_append (iface->members, signal); + + push_node (ctx, (GIrNode *)signal); + + return TRUE; } static gboolean @@ -2174,80 +2192,80 @@ start_vfunc (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "virtual-method") == 0 && - (ctx->state == STATE_CLASS || - ctx->state == STATE_INTERFACE)) + const gchar *name; + const gchar *must_chain_up; + const gchar *override; + const gchar *is_class_closure; + const gchar *offset; + const gchar *invoker; + GIrNodeInterface *iface; + GIrNodeVFunc *vfunc; + + if (!(strcmp (element_name, "virtual-method") == 0 && + (ctx->state == STATE_CLASS || + ctx->state == STATE_INTERFACE))) + return FALSE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION)) + return TRUE; + + name = find_attribute ("name", attribute_names, attribute_values); + must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values); + override = find_attribute ("override", attribute_names, attribute_values); + is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values); + offset = find_attribute ("offset", attribute_names, attribute_values); + invoker = find_attribute ("invoker", attribute_names, attribute_values); + + if (name == NULL) { - const gchar *name; - const gchar *must_chain_up; - const gchar *override; - const gchar *is_class_closure; - const gchar *offset; - const gchar *invoker; - - name = find_attribute ("name", attribute_names, attribute_values); - must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values); - override = find_attribute ("override", attribute_names, attribute_values); - is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values); - offset = find_attribute ("offset", attribute_names, attribute_values); - invoker = find_attribute ("invoker", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { - GIrNodeInterface *iface; - GIrNodeVFunc *vfunc; - - vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC); - - ((GIrNode *)vfunc)->name = g_strdup (name); - - if (must_chain_up && strcmp (must_chain_up, "1") == 0) - vfunc->must_chain_up = TRUE; - else - vfunc->must_chain_up = FALSE; - - if (override && strcmp (override, "always") == 0) - { - vfunc->must_be_implemented = TRUE; - vfunc->must_not_be_implemented = FALSE; - } - else if (override && strcmp (override, "never") == 0) - { - vfunc->must_be_implemented = FALSE; - vfunc->must_not_be_implemented = TRUE; - } - else - { - vfunc->must_be_implemented = FALSE; - vfunc->must_not_be_implemented = FALSE; - } - - if (is_class_closure && strcmp (is_class_closure, "1") == 0) - vfunc->is_class_closure = TRUE; - else - vfunc->is_class_closure = FALSE; - - if (offset) - vfunc->offset = atoi (offset); - else - vfunc->offset = 0; - - vfunc->invoker = g_strdup (invoker); - - iface = (GIrNodeInterface *)CURRENT_NODE (ctx); - iface->members = g_list_append (iface->members, vfunc); - - push_node (ctx, (GIrNode *)vfunc); - state_switch (ctx, STATE_FUNCTION); - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; -} + vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC); + + ((GIrNode *)vfunc)->name = g_strdup (name); + + if (must_chain_up && strcmp (must_chain_up, "1") == 0) + vfunc->must_chain_up = TRUE; + else + vfunc->must_chain_up = FALSE; + + if (override && strcmp (override, "always") == 0) + { + vfunc->must_be_implemented = TRUE; + vfunc->must_not_be_implemented = FALSE; + } + else if (override && strcmp (override, "never") == 0) + { + vfunc->must_be_implemented = FALSE; + vfunc->must_not_be_implemented = TRUE; + } + else + { + vfunc->must_be_implemented = FALSE; + vfunc->must_not_be_implemented = FALSE; + } + + if (is_class_closure && strcmp (is_class_closure, "1") == 0) + vfunc->is_class_closure = TRUE; + else + vfunc->is_class_closure = FALSE; + + if (offset) + vfunc->offset = atoi (offset); + else + vfunc->offset = 0; + + vfunc->invoker = g_strdup (invoker); + + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); + iface->members = g_list_append (iface->members, vfunc); + + push_node (ctx, (GIrNode *)vfunc); + + return TRUE; +} static gboolean start_struct (GMarkupParseContext *context, @@ -2257,74 +2275,73 @@ start_struct (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "record") == 0 && - (ctx->state == STATE_NAMESPACE || - ctx->state == STATE_UNION || - ctx->state == STATE_STRUCT || - ctx->state == STATE_CLASS)) + const gchar *name; + const gchar *deprecated; + const gchar *disguised; + const gchar *gtype_name; + const gchar *gtype_init; + const gchar *gtype_struct; + const gchar *foreign; + GIrNodeStruct *struct_; + + if (!(strcmp (element_name, "record") == 0 && + (ctx->state == STATE_NAMESPACE || + ctx->state == STATE_UNION || + ctx->state == STATE_STRUCT || + ctx->state == STATE_CLASS))) + return FALSE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_STRUCT)) + return TRUE; + + name = find_attribute ("name", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + disguised = find_attribute ("disguised", attribute_names, attribute_values); + gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values); + gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values); + gtype_struct = find_attribute ("glib:is-gtype-struct-for", attribute_names, attribute_values); + foreign = find_attribute ("foreign", attribute_names, attribute_values); + + if (name == NULL && ctx->node_stack == NULL) { - const gchar *name; - const gchar *deprecated; - const gchar *disguised; - const gchar *gtype_name; - const gchar *gtype_init; - const gchar *gtype_struct; - const gchar *foreign; - GIrNodeStruct *struct_; - - name = find_attribute ("name", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - disguised = find_attribute ("disguised", attribute_names, attribute_values); - gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values); - gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values); - gtype_struct = find_attribute ("glib:is-gtype-struct-for", attribute_names, attribute_values); - foreign = find_attribute ("foreign", attribute_names, attribute_values); - - if (name == NULL && ctx->node_stack == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "name"); - return FALSE; - } - if ((gtype_name == NULL && gtype_init != NULL)) - { - MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); - return FALSE; - } - if ((gtype_name != NULL && gtype_init == NULL)) - { - MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); - return FALSE; - } - - struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT); - - ((GIrNode *)struct_)->name = g_strdup (name ? name : ""); - if (deprecated) - struct_->deprecated = TRUE; - else - struct_->deprecated = FALSE; - - if (disguised && strcmp (disguised, "1") == 0) - struct_->disguised = TRUE; - - struct_->is_gtype_struct = gtype_struct != NULL; - - struct_->gtype_name = g_strdup (gtype_name); - struct_->gtype_init = g_strdup (gtype_init); - - struct_->foreign = (g_strcmp0 (foreign, "1") == 0); - - if (ctx->node_stack == NULL) - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, struct_); - push_node (ctx, (GIrNode *)struct_); - - state_switch (ctx, STATE_STRUCT); - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; + } + if ((gtype_name == NULL && gtype_init != NULL)) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); + return FALSE; + } + if ((gtype_name != NULL && gtype_init == NULL)) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); + return FALSE; } - return FALSE; -} + struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT); + + ((GIrNode *)struct_)->name = g_strdup (name ? name : ""); + if (deprecated) + struct_->deprecated = TRUE; + else + struct_->deprecated = FALSE; + + if (disguised && strcmp (disguised, "1") == 0) + struct_->disguised = TRUE; + + struct_->is_gtype_struct = gtype_struct != NULL; + + struct_->gtype_name = g_strdup (gtype_name); + struct_->gtype_init = g_strdup (gtype_init); + + struct_->foreign = (g_strcmp0 (foreign, "1") == 0); + + if (ctx->node_stack == NULL) + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, struct_); + push_node (ctx, (GIrNode *)struct_); + return TRUE; +} static gboolean start_union (GMarkupParseContext *context, @@ -2334,48 +2351,48 @@ start_union (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "union") == 0 && - (ctx->state == STATE_NAMESPACE || - ctx->state == STATE_UNION || - ctx->state == STATE_STRUCT || - ctx->state == STATE_CLASS)) + const gchar *name; + const gchar *deprecated; + const gchar *typename; + const gchar *typeinit; + GIrNodeUnion *union_; + + if (!(strcmp (element_name, "union") == 0 && + (ctx->state == STATE_NAMESPACE || + ctx->state == STATE_UNION || + ctx->state == STATE_STRUCT || + ctx->state == STATE_CLASS))) + return FALSE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_UNION)) + return TRUE; + + name = find_attribute ("name", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + + if (name == NULL && ctx->node_stack == NULL) { - const gchar *name; - const gchar *deprecated; - const gchar *typename; - const gchar *typeinit; - - name = find_attribute ("name", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - typename = find_attribute ("glib:type-name", attribute_names, attribute_values); - typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); - - if (name == NULL && ctx->node_stack == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { - GIrNodeUnion *union_; - - union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION); - - ((GIrNode *)union_)->name = g_strdup (name ? name : ""); - union_->gtype_name = g_strdup (typename); - union_->gtype_init = g_strdup (typeinit); - if (deprecated) - union_->deprecated = TRUE; - else - union_->deprecated = FALSE; - - if (ctx->node_stack == NULL) - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, union_); - push_node (ctx, (GIrNode *)union_); - - state_switch (ctx, STATE_UNION); - } - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; + + union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION); + + ((GIrNode *)union_)->name = g_strdup (name ? name : ""); + union_->gtype_name = g_strdup (typename); + union_->gtype_init = g_strdup (typeinit); + if (deprecated) + union_->deprecated = TRUE; + else + union_->deprecated = FALSE; + + if (ctx->node_stack == NULL) + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, union_); + push_node (ctx, (GIrNode *)union_); + return TRUE; } static gboolean @@ -2386,42 +2403,43 @@ start_discriminator (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "discriminator") == 0 && - ctx->state == STATE_UNION) + const gchar *type; + const gchar *offset; + if (!(strcmp (element_name, "discriminator") == 0 && + ctx->state == STATE_UNION)) + return FALSE; + + type = find_attribute ("type", attribute_names, attribute_values); + offset = find_attribute ("offset", attribute_names, attribute_values); + if (type == NULL) { - const gchar *type; - const gchar *offset; - - type = find_attribute ("type", attribute_names, attribute_values); - offset = find_attribute ("offset", attribute_names, attribute_values); - if (type == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "type"); - else if (offset == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "offset"); - { - ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type - = parse_type (ctx, type); - ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset - = atoi (offset); - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "type"); + return FALSE; + } + else if (offset == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "offset"); + return FALSE; } - return FALSE; + ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type + = parse_type (ctx, type); + ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset + = atoi (offset); + + return TRUE; } static gboolean parse_include (GMarkupParseContext *context, ParseContext *ctx, const char *name, - const char *version, - GError **error) + const char *version) { + GError *error = NULL; gchar *buffer; gsize length; gchar *girpath, *girname; - gboolean success = FALSE; GList *modules; GList *l; @@ -2439,11 +2457,8 @@ parse_include (GMarkupParseContext *context, } else { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Module '%s' imported with conflicting versions '%s' and '%s'", - name, m->version, version); + g_printerr ("Module '%s' imported with conflicting versions '%s' and '%s'\n", + name, m->version, version); return FALSE; } } @@ -2454,10 +2469,7 @@ parse_include (GMarkupParseContext *context, if (girpath == NULL) { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Could not find GIR file '%s'; check XDG_DATA_DIRS or use --includedir", + g_printerr ("Could not find GIR file '%s'; check XDG_DATA_DIRS or use --includedir\n", girname); g_free (girname); return FALSE; @@ -2466,22 +2478,31 @@ parse_include (GMarkupParseContext *context, g_debug ("Parsing include %s", girpath); - if (!g_file_get_contents (girpath, &buffer, &length, error)) + if (!g_file_get_contents (girpath, &buffer, &length, &error)) { + g_printerr ("%s: %s\n", girpath, error->message); + g_clear_error (&error); + g_free (girpath); + return FALSE; + } + + modules = g_ir_parser_parse_string (ctx->parser, name, girpath, buffer, length, &error); + g_free (buffer); + if (error != NULL) + { + int line_number, char_number; + g_markup_parse_context_get_position (context, &line_number, &char_number); + g_printerr ("%s:%d:%d: error: %s\n", girpath, line_number, char_number, error->message); + g_clear_error (&error); g_free (girpath); return FALSE; } g_free (girpath); - modules = g_ir_parser_parse_string (ctx->parser, name, buffer, length, error); - success = error != NULL; - ctx->include_modules = g_list_concat (ctx->include_modules, modules); - g_free (buffer); - - return success; + return TRUE; } extern GLogLevelFlags logged_levels; @@ -2515,6 +2536,12 @@ start_element_handler (GMarkupParseContext *context, g_string_free (tags, TRUE); } + if (ctx->state == STATE_PASSTHROUGH) + { + ctx->unknown_depth += 1; + return; + } + switch (element_name[0]) { case 'a': @@ -2614,8 +2641,16 @@ start_element_handler (GMarkupParseContext *context, break; } - if (!parse_include (context, ctx, name, version, error)) - break; + if (!parse_include (context, ctx, name, version)) + { + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Failed to parse included gir %s-%s", + name, + version); + return; + } ctx->dependencies = g_list_prepend (ctx->dependencies, g_strdup_printf ("%s-%s", name, version)); @@ -2801,22 +2836,22 @@ start_element_handler (GMarkupParseContext *context, break; } - if (ctx->state != STATE_UNKNOWN) + if (ctx->state != STATE_PASSTHROUGH) { - state_switch (ctx, STATE_UNKNOWN); + g_markup_parse_context_get_position (context, &line_number, &char_number); + if (!g_str_has_prefix (element_name, "c:")) + g_printerr ("%s:%d:%d: warning: dropping to PASSTHROUGH\n", + ctx->file_path, line_number, char_number); + state_switch (ctx, STATE_PASSTHROUGH); ctx->unknown_depth = 1; } - else - { - ctx->unknown_depth += 1; - } out: if (*error) { g_markup_parse_context_get_position (context, &line_number, &char_number); - fprintf (stderr, "Error at line %d, character %d: %s\n", line_number, char_number, (*error)->message); + g_printerr ("%s:%d:%d: error: %s\n", ctx->file_path, line_number, char_number, (*error)->message); backtrace_stderr (); } } @@ -3189,7 +3224,7 @@ end_element_handler (GMarkupParseContext *context, } break; - case STATE_UNKNOWN: + case STATE_PASSTHROUGH: ctx->unknown_depth -= 1; if (ctx->unknown_depth == 0) state_switch (ctx, ctx->prev_state); @@ -3225,149 +3260,11 @@ cleanup (GMarkupParseContext *context, ctx->current_module = NULL; } -static GList * -post_filter_toplevel_varargs_functions (GList *list, - GList **varargs_callbacks_out) -{ - GList *iter; - GList *varargs_callbacks = *varargs_callbacks_out; - - iter = list; - while (iter) - { - GList *link = iter; - GIrNode *node = iter->data; - - iter = iter->next; - - if (node->type == G_IR_NODE_FUNCTION) - { - if (((GIrNodeFunction*)node)->is_varargs) - { - list = g_list_delete_link (list, link); - } - } - if (node->type == G_IR_NODE_CALLBACK) - { - if (((GIrNodeFunction*)node)->is_varargs) - { - varargs_callbacks = g_list_append (varargs_callbacks, - node); - list = g_list_delete_link (list, link); - } - } - } - - *varargs_callbacks_out = varargs_callbacks; - - return list; -} - -static GList * -post_filter_varargs_functions (GList *list, GList ** varargs_callbacks_out) -{ - GList *iter; - GList *varargs_callbacks; - - list = post_filter_toplevel_varargs_functions (list, varargs_callbacks_out); - - varargs_callbacks = *varargs_callbacks_out; - - iter = list; - while (iter) - { - GList *link = iter; - GIrNode *node = iter->data; - - iter = iter->next; - - if (node->type == G_IR_NODE_FUNCTION) - { - GList *param; - gboolean function_done = FALSE; - - for (param = ((GIrNodeFunction *)node)->parameters; - param; - param = param->next) - { - GIrNodeParam *node = (GIrNodeParam *)param->data; - - if (function_done) - break; - - if (node->type->is_interface) - { - GList *callback; - for (callback = varargs_callbacks; - callback; - callback = callback->next) - { - if (!strcmp (node->type->interface, - ((GIrNode *)varargs_callbacks->data)->name)) - { - list = g_list_delete_link (list, link); - function_done = TRUE; - break; - } - } - } - } - } - } - - *varargs_callbacks_out = varargs_callbacks; - - return list; -} - -static void -post_filter (GIrModule *module) -{ - GList *iter; - GList *varargs_callbacks = NULL; - - module->entries = post_filter_varargs_functions (module->entries, - &varargs_callbacks); - iter = module->entries; - while (iter) - { - GIrNode *node = iter->data; - - iter = iter->next; - - if (node->type == G_IR_NODE_OBJECT || - node->type == G_IR_NODE_INTERFACE) - { - GIrNodeInterface *iface = (GIrNodeInterface*)node; - iface->members = post_filter_varargs_functions (iface->members, - &varargs_callbacks); - } - else if (node->type == G_IR_NODE_BOXED) - { - GIrNodeBoxed *boxed = (GIrNodeBoxed*)node; - boxed->members = post_filter_varargs_functions (boxed->members, - &varargs_callbacks); - } - else if (node->type == G_IR_NODE_STRUCT) - { - GIrNodeStruct *iface = (GIrNodeStruct*)node; - iface->members = post_filter_varargs_functions (iface->members, - &varargs_callbacks); - } - else if (node->type == G_IR_NODE_UNION) - { - GIrNodeUnion *iface = (GIrNodeUnion*)node; - iface->members = post_filter_varargs_functions (iface->members, - &varargs_callbacks); - } - } - g_list_free (varargs_callbacks); -} - /** * g_ir_parser_parse_string: * @parser: a #GIrParser * @namespace: the namespace of the string + * @filename: (allow-none): Path to parsed file, or %NULL * @buffer: the data containing the XML * @length: length of the data * @error: return location for a #GError, or %NULL @@ -3381,6 +3278,7 @@ post_filter (GIrModule *module) GList * g_ir_parser_parse_string (GIrParser *parser, const gchar *namespace, + const gchar *filename, const gchar *buffer, gssize length, GError **error) @@ -3390,6 +3288,7 @@ g_ir_parser_parse_string (GIrParser *parser, ctx.parser = parser; ctx.state = STATE_START; + ctx.file_path = filename; ctx.namespace = namespace; ctx.include_modules = NULL; ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); @@ -3457,7 +3356,6 @@ g_ir_parser_parse_file (GIrParser *parser, gchar *buffer; gsize length; GList *modules; - GList *iter; const char *slash; char *dash; char *namespace; @@ -3488,12 +3386,7 @@ g_ir_parser_parse_file (GIrParser *parser, if (!g_file_get_contents (filename, &buffer, &length, error)) return NULL; - modules = g_ir_parser_parse_string (parser, namespace, buffer, length, error); - - for (iter = modules; iter; iter = iter->next) - { - post_filter ((GIrModule*)iter->data); - } + modules = g_ir_parser_parse_string (parser, namespace, filename, buffer, length, error); g_free (namespace); diff --git a/girparser.h b/girparser.h index ac0d216b2..6fca1b3da 100644 --- a/girparser.h +++ b/girparser.h @@ -34,6 +34,7 @@ void g_ir_parser_set_includes (GIrParser *parser, GList *g_ir_parser_parse_string (GIrParser *parser, const gchar *namespace, + const gchar *filename, const gchar *buffer, gssize length, GError **error); From c3790c1af7c0a9597c7b01ac6b24cba6689bbcdd Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Thu, 17 Jun 2010 09:14:04 -0300 Subject: [PATCH 347/692] Revert "Support introspectable=no attribute, add warnings framework" This reverts commit 074192b89c6afcdd7f062f03989972e44334b8bf. --- girparser.c | 1629 +++++++++++++++++++++++++++------------------------ girparser.h | 1 - 2 files changed, 868 insertions(+), 762 deletions(-) diff --git a/girparser.c b/girparser.c index a0c1e21dd..d0bd8aa36 100644 --- a/girparser.c +++ b/girparser.c @@ -72,10 +72,10 @@ typedef enum STATE_NAMESPACE_CONSTANT, STATE_CLASS_CONSTANT, STATE_INTERFACE_CONSTANT, - STATE_ALIAS, /* 30 */ + STATE_ALIAS, STATE_TYPE, STATE_ATTRIBUTE, - STATE_PASSTHROUGH + STATE_UNKNOWN } ParseState; typedef struct _ParseContext ParseContext; @@ -93,12 +93,12 @@ struct _ParseContext GHashTable *aliases; GHashTable *disguised_structures; - const char *file_path; const char *namespace; const char *c_prefix; GIrModule *current_module; GSList *node_stack; GIrNode *current_typed; + gboolean is_varargs; GList *type_stack; GList *type_parameters; int type_depth; @@ -317,7 +317,7 @@ find_attribute (const gchar *name, static void state_switch (ParseContext *ctx, ParseState newstate) { - g_assert (ctx->state != newstate); + g_debug ("State: %d", newstate); ctx->prev_state = ctx->state; ctx->state = newstate; } @@ -339,7 +339,6 @@ pop_node (ParseContext *ctx) static void push_node (ParseContext *ctx, GIrNode *node) { - g_assert (node != NULL); g_debug ("pushing node %d %s", node->type, node->name); ctx->node_stack = g_slist_prepend (ctx->node_stack, node); } @@ -630,32 +629,6 @@ parse_type (ParseContext *ctx, const gchar *type) return node; } -static gboolean -introspectable_prelude (GMarkupParseContext *context, - const gchar **attribute_names, - const gchar **attribute_values, - ParseContext *ctx, - ParseState new_state) -{ - const gchar *introspectable_arg; - gboolean introspectable; - - g_assert (ctx->state != STATE_PASSTHROUGH); - - introspectable_arg = find_attribute ("introspectable", attribute_names, attribute_values); - introspectable = !(introspectable_arg && atoi (introspectable_arg) == 0); - - if (introspectable) - state_switch (ctx, new_state); - else - { - state_switch (ctx, STATE_PASSTHROUGH); - ctx->unknown_depth = 1; - } - - return introspectable; -} - static gboolean start_glib_boxed (GMarkupParseContext *context, const gchar *element_name, @@ -674,9 +647,6 @@ start_glib_boxed (GMarkupParseContext *context, ctx->state == STATE_NAMESPACE)) return FALSE; - if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_BOXED)) - return TRUE; - name = find_attribute ("glib:name", attribute_names, attribute_values); typename = find_attribute ("glib:type-name", attribute_names, attribute_values); typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); @@ -712,6 +682,8 @@ start_glib_boxed (GMarkupParseContext *context, ctx->current_module->entries = g_list_append (ctx->current_module->entries, boxed); + state_switch (ctx, STATE_BOXED); + return TRUE; } @@ -750,6 +722,7 @@ start_function (GMarkupParseContext *context, strcmp (element_name, "callback") == 0); break; case STATE_STRUCT_FIELD: + ctx->in_embedded_type = TRUE; found = (found || strcmp (element_name, "callback") == 0); break; default: @@ -759,12 +732,6 @@ start_function (GMarkupParseContext *context, if (!found) return FALSE; - if (ctx->state == STATE_STRUCT_FIELD) - ctx->in_embedded_type = TRUE; - - if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION)) - return TRUE; - name = find_attribute ("name", attribute_names, attribute_values); symbol = find_attribute ("c:identifier", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); @@ -868,6 +835,7 @@ start_function (GMarkupParseContext *context, } push_node(ctx, (GIrNode *)function); + state_switch (ctx, STATE_FUNCTION); return TRUE; } @@ -1250,47 +1218,47 @@ start_enum (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - const gchar *name; - const gchar *typename; - const gchar *typeinit; - const gchar *deprecated; - GIrNodeEnum *enum_; - - if (!((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) || - (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE))) - return FALSE; - - if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_ENUM)) - return TRUE; - - name = find_attribute ("name", attribute_names, attribute_values); - typename = find_attribute ("glib:type-name", attribute_names, attribute_values); - typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) + if ((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) || + (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE)) { - MISSING_ATTRIBUTE (context, error, element_name, "name"); - return FALSE; + const gchar *name; + const gchar *typename; + const gchar *typeinit; + const gchar *deprecated; + + name = find_attribute ("name", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeEnum *enum_; + + if (strcmp (element_name, "enumeration") == 0) + enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM); + else + enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS); + ((GIrNode *)enum_)->name = g_strdup (name); + enum_->gtype_name = g_strdup (typename); + enum_->gtype_init = g_strdup (typeinit); + if (deprecated) + enum_->deprecated = TRUE; + else + enum_->deprecated = FALSE; + + push_node (ctx, (GIrNode *) enum_); + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, enum_); + + state_switch (ctx, STATE_ENUM); + } + + return TRUE; } - - if (strcmp (element_name, "enumeration") == 0) - enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM); - else - enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS); - ((GIrNode *)enum_)->name = g_strdup (name); - enum_->gtype_name = g_strdup (typename); - enum_->gtype_init = g_strdup (typeinit); - if (deprecated) - enum_->deprecated = TRUE; - else - enum_->deprecated = FALSE; - - push_node (ctx, (GIrNode *) enum_); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, enum_); - - return TRUE; + return FALSE; } static gboolean @@ -1301,74 +1269,70 @@ start_property (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - ParseState target_state; - const gchar *name; - const gchar *readable; - const gchar *writable; - const gchar *construct; - const gchar *construct_only; - const gchar *transfer; - GIrNodeProperty *property; - GIrNodeInterface *iface; - - if (!(strcmp (element_name, "property") == 0 && - (ctx->state == STATE_CLASS || - ctx->state == STATE_INTERFACE))) - return FALSE; - - if (ctx->state == STATE_CLASS) - target_state = STATE_CLASS_PROPERTY; - else if (ctx->state == STATE_INTERFACE) - target_state = STATE_INTERFACE_PROPERTY; - else - g_assert_not_reached (); - - if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, target_state)) - return TRUE; - - - name = find_attribute ("name", attribute_names, attribute_values); - readable = find_attribute ("readable", attribute_names, attribute_values); - writable = find_attribute ("writable", attribute_names, attribute_values); - construct = find_attribute ("construct", attribute_names, attribute_values); - construct_only = find_attribute ("construct-only", attribute_names, attribute_values); - transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); - - if (name == NULL) + if (strcmp (element_name, "property") == 0 && + (ctx->state == STATE_CLASS || + ctx->state == STATE_INTERFACE)) { - MISSING_ATTRIBUTE (context, error, element_name, "name"); - return FALSE; + const gchar *name; + const gchar *readable; + const gchar *writable; + const gchar *construct; + const gchar *construct_only; + const gchar *transfer; + + name = find_attribute ("name", attribute_names, attribute_values); + readable = find_attribute ("readable", attribute_names, attribute_values); + writable = find_attribute ("writable", attribute_names, attribute_values); + construct = find_attribute ("construct", attribute_names, attribute_values); + construct_only = find_attribute ("construct-only", attribute_names, attribute_values); + transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeProperty *property; + GIrNodeInterface *iface; + + property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY); + ctx->current_typed = (GIrNode*) property; + + ((GIrNode *)property)->name = g_strdup (name); + + /* Assume properties are readable */ + if (readable == NULL || strcmp (readable, "1") == 0) + property->readable = TRUE; + else + property->readable = FALSE; + if (writable && strcmp (writable, "1") == 0) + property->writable = TRUE; + else + property->writable = FALSE; + if (construct && strcmp (construct, "1") == 0) + property->construct = TRUE; + else + property->construct = FALSE; + if (construct_only && strcmp (construct_only, "1") == 0) + property->construct_only = TRUE; + else + property->construct_only = FALSE; + + parse_property_transfer (property, transfer, ctx); + + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); + iface->members = g_list_append (iface->members, property); + + if (ctx->state == STATE_CLASS) + state_switch (ctx, STATE_CLASS_PROPERTY); + else if (ctx->state == STATE_INTERFACE) + state_switch (ctx, STATE_INTERFACE_PROPERTY); + else + g_assert_not_reached (); + } + + return TRUE; } - - property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY); - ctx->current_typed = (GIrNode*) property; - - ((GIrNode *)property)->name = g_strdup (name); - - /* Assume properties are readable */ - if (readable == NULL || strcmp (readable, "1") == 0) - property->readable = TRUE; - else - property->readable = FALSE; - if (writable && strcmp (writable, "1") == 0) - property->writable = TRUE; - else - property->writable = FALSE; - if (construct && strcmp (construct, "1") == 0) - property->construct = TRUE; - else - property->construct = FALSE; - if (construct_only && strcmp (construct_only, "1") == 0) - property->construct_only = TRUE; - else - property->construct_only = FALSE; - - parse_property_transfer (property, transfer, ctx); - - iface = (GIrNodeInterface *)CURRENT_NODE (ctx); - iface->members = g_list_append (iface->members, property); - - return TRUE; + return FALSE; } static gint @@ -1402,41 +1366,42 @@ start_member (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - const gchar *name; - const gchar *value; - const gchar *deprecated; - GIrNodeEnum *enum_; - GIrNodeValue *value_; - - if (!(strcmp (element_name, "member") == 0 && - ctx->state == STATE_ENUM)) - return FALSE; - - name = find_attribute ("name", attribute_names, attribute_values); - value = find_attribute ("value", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) + if (strcmp (element_name, "member") == 0 && + ctx->state == STATE_ENUM) { - MISSING_ATTRIBUTE (context, error, element_name, "name"); - return FALSE; + const gchar *name; + const gchar *value; + const gchar *deprecated; + + name = find_attribute ("name", attribute_names, attribute_values); + value = find_attribute ("value", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeEnum *enum_; + GIrNodeValue *value_; + + value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE); + + ((GIrNode *)value_)->name = g_strdup (name); + + value_->value = parse_value (value); + + if (deprecated) + value_->deprecated = TRUE; + else + value_->deprecated = FALSE; + + enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx); + enum_->values = g_list_append (enum_->values, value_); + } + + return TRUE; } - - value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE); - - ((GIrNode *)value_)->name = g_strdup (name); - - value_->value = parse_value (value); - - if (deprecated) - value_->deprecated = TRUE; - else - value_->deprecated = FALSE; - - enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx); - enum_->values = g_list_append (enum_->values, value_); - - return TRUE; + return FALSE; } static gboolean @@ -1447,81 +1412,73 @@ start_constant (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - ParseState prev_state; - ParseState target_state; - const gchar *name; - const gchar *value; - const gchar *deprecated; - GIrNodeConstant *constant; - - if (!(strcmp (element_name, "constant") == 0 && - (ctx->state == STATE_NAMESPACE || - ctx->state == STATE_CLASS || - ctx->state == STATE_INTERFACE))) - return FALSE; - - switch (ctx->state) + if (strcmp (element_name, "constant") == 0 && + (ctx->state == STATE_NAMESPACE || + ctx->state == STATE_CLASS || + ctx->state == STATE_INTERFACE)) { - case STATE_NAMESPACE: - target_state = STATE_NAMESPACE_CONSTANT; - break; - case STATE_CLASS: - target_state = STATE_CLASS_CONSTANT; - break; - case STATE_INTERFACE: - target_state = STATE_INTERFACE_CONSTANT; - break; - default: - g_assert_not_reached (); + const gchar *name; + const gchar *value; + const gchar *deprecated; + + name = find_attribute ("name", attribute_names, attribute_values); + value = find_attribute ("value", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else if (value == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "value"); + else + { + GIrNodeConstant *constant; + + constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT); + + ((GIrNode *)constant)->name = g_strdup (name); + constant->value = g_strdup (value); + + ctx->current_typed = (GIrNode*) constant; + + if (deprecated) + constant->deprecated = TRUE; + else + constant->deprecated = FALSE; + + if (ctx->state == STATE_NAMESPACE) + { + push_node (ctx, (GIrNode *) constant); + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, constant); + } + else + { + GIrNodeInterface *iface; + + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); + iface->members = g_list_append (iface->members, constant); + } + + switch (ctx->state) + { + case STATE_NAMESPACE: + state_switch (ctx, STATE_NAMESPACE_CONSTANT); + break; + case STATE_CLASS: + state_switch (ctx, STATE_CLASS_CONSTANT); + break; + case STATE_INTERFACE: + state_switch (ctx, STATE_INTERFACE_CONSTANT); + break; + default: + g_assert_not_reached (); + break; + } + } + + return TRUE; } - - prev_state = ctx->state; - - if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, target_state)) - return TRUE; - - name = find_attribute ("name", attribute_names, attribute_values); - value = find_attribute ("value", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "name"); - return FALSE; - } - else if (value == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "value"); - return FALSE; - } - - constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT); - - ((GIrNode *)constant)->name = g_strdup (name); - constant->value = g_strdup (value); - - ctx->current_typed = (GIrNode*) constant; - - if (deprecated) - constant->deprecated = TRUE; - else - constant->deprecated = FALSE; - - if (prev_state == STATE_NAMESPACE) - { - push_node (ctx, (GIrNode *) constant); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, constant); - } - else - { - GIrNodeInterface *iface; - - iface = (GIrNodeInterface *)CURRENT_NODE (ctx); - iface->members = g_list_append (iface->members, constant); - } - - return TRUE; + return FALSE; } static gboolean @@ -1532,57 +1489,50 @@ start_errordomain (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - const gchar *name; - const gchar *getquark; - const gchar *codes; - const gchar *deprecated; - GIrNodeErrorDomain *domain; - - if (!(strcmp (element_name, "errordomain") == 0 && - ctx->state == STATE_NAMESPACE)) - return FALSE; - - if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_ERRORDOMAIN)) - return TRUE; - - - name = find_attribute ("name", attribute_names, attribute_values); - getquark = find_attribute ("get-quark", attribute_names, attribute_values); - codes = find_attribute ("codes", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) + if (strcmp (element_name, "errordomain") == 0 && + ctx->state == STATE_NAMESPACE) { - MISSING_ATTRIBUTE (context, error, element_name, "name"); - return FALSE; + const gchar *name; + const gchar *getquark; + const gchar *codes; + const gchar *deprecated; + + name = find_attribute ("name", attribute_names, attribute_values); + getquark = find_attribute ("get-quark", attribute_names, attribute_values); + codes = find_attribute ("codes", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else if (getquark == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "getquark"); + else if (codes == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "codes"); + else + { + GIrNodeErrorDomain *domain; + + domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN); + + ((GIrNode *)domain)->name = g_strdup (name); + domain->getquark = g_strdup (getquark); + domain->codes = g_strdup (codes); + + if (deprecated) + domain->deprecated = TRUE; + else + domain->deprecated = FALSE; + + push_node (ctx, (GIrNode *) domain); + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, domain); + + state_switch (ctx, STATE_ERRORDOMAIN); + } + + return TRUE; } - else if (getquark == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "getquark"); - return FALSE; - } - else if (codes == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "codes"); - return FALSE; - } - - domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN); - - ((GIrNode *)domain)->name = g_strdup (name); - domain->getquark = g_strdup (getquark); - domain->codes = g_strdup (codes); - - if (deprecated) - domain->deprecated = TRUE; - else - domain->deprecated = FALSE; - - push_node (ctx, (GIrNode *) domain); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, domain); - - return TRUE; + return FALSE; } static gboolean @@ -1593,57 +1543,52 @@ start_interface (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - const gchar *name; - const gchar *typename; - const gchar *typeinit; - const gchar *deprecated; - const gchar *glib_type_struct; - GIrNodeInterface *iface; - - if (!(strcmp (element_name, "interface") == 0 && - ctx->state == STATE_NAMESPACE)) - return FALSE; - - if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_INTERFACE)) - return TRUE; - - name = find_attribute ("name", attribute_names, attribute_values); - typename = find_attribute ("glib:type-name", attribute_names, attribute_values); - typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); - glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) + if (strcmp (element_name, "interface") == 0 && + ctx->state == STATE_NAMESPACE) { - MISSING_ATTRIBUTE (context, error, element_name, "name"); - return FALSE; - } - else if (typename == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); - return FALSE; - } - else if (typeinit == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); - return FALSE; - } + const gchar *name; + const gchar *typename; + const gchar *typeinit; + const gchar *deprecated; + const gchar *glib_type_struct; - iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE); - ((GIrNode *)iface)->name = g_strdup (name); - iface->gtype_name = g_strdup (typename); - iface->gtype_init = g_strdup (typeinit); - iface->glib_type_struct = g_strdup (glib_type_struct); - if (deprecated) - iface->deprecated = TRUE; - else - iface->deprecated = FALSE; + name = find_attribute ("name", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - push_node (ctx, (GIrNode *) iface); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, iface); + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else if (typename == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); + else if (typeinit == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); + else + { + GIrNodeInterface *iface; - return TRUE; + iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE); + ((GIrNode *)iface)->name = g_strdup (name); + iface->gtype_name = g_strdup (typename); + iface->gtype_init = g_strdup (typeinit); + iface->glib_type_struct = g_strdup (glib_type_struct); + if (deprecated) + iface->deprecated = TRUE; + else + iface->deprecated = FALSE; + + push_node (ctx, (GIrNode *) iface); + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, iface); + + state_switch (ctx, STATE_INTERFACE); + + } + + return TRUE; + } + return FALSE; } static gboolean @@ -1654,64 +1599,58 @@ start_class (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - const gchar *name; - const gchar *parent; - const gchar *glib_type_struct; - const gchar *typename; - const gchar *typeinit; - const gchar *deprecated; - const gchar *abstract; - GIrNodeInterface *iface; - - if (!(strcmp (element_name, "class") == 0 && - ctx->state == STATE_NAMESPACE)) - return FALSE; - - if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_CLASS)) - return TRUE; - - name = find_attribute ("name", attribute_names, attribute_values); - parent = find_attribute ("parent", attribute_names, attribute_values); - glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values); - typename = find_attribute ("glib:type-name", attribute_names, attribute_values); - typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - abstract = find_attribute ("abstract", attribute_names, attribute_values); - - if (name == NULL) + if (strcmp (element_name, "class") == 0 && + ctx->state == STATE_NAMESPACE) { - MISSING_ATTRIBUTE (context, error, element_name, "name"); - return FALSE; + const gchar *name; + const gchar *parent; + const gchar *glib_type_struct; + const gchar *typename; + const gchar *typeinit; + const gchar *deprecated; + const gchar *abstract; + + name = find_attribute ("name", attribute_names, attribute_values); + parent = find_attribute ("parent", attribute_names, attribute_values); + glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + abstract = find_attribute ("abstract", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else if (typename == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); + else if (typeinit == NULL && strcmp (typename, "GObject")) + MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); + else + { + GIrNodeInterface *iface; + + iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT); + ((GIrNode *)iface)->name = g_strdup (name); + iface->gtype_name = g_strdup (typename); + iface->gtype_init = g_strdup (typeinit); + iface->parent = g_strdup (parent); + iface->glib_type_struct = g_strdup (glib_type_struct); + if (deprecated) + iface->deprecated = TRUE; + else + iface->deprecated = FALSE; + + iface->abstract = abstract && strcmp (abstract, "1") == 0; + + push_node (ctx, (GIrNode *) iface); + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, iface); + + state_switch (ctx, STATE_CLASS); + } + + return TRUE; } - else if (typename == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); - return FALSE; - } - else if (typeinit == NULL && strcmp (typename, "GObject")) - { - MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); - return FALSE; - } - - iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT); - ((GIrNode *)iface)->name = g_strdup (name); - iface->gtype_name = g_strdup (typename); - iface->gtype_init = g_strdup (typeinit); - iface->parent = g_strdup (parent); - iface->glib_type_struct = g_strdup (glib_type_struct); - if (deprecated) - iface->deprecated = TRUE; - else - iface->deprecated = FALSE; - - iface->abstract = abstract && strcmp (abstract, "1") == 0; - - push_node (ctx, (GIrNode *) iface); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, iface); - - return TRUE; + return FALSE; } static gboolean @@ -1756,6 +1695,47 @@ start_type (GMarkupParseContext *context, { state_switch (ctx, STATE_TYPE); ctx->type_depth = 1; + if (is_varargs) + { + switch (CURRENT_NODE (ctx)->type) + { + case G_IR_NODE_FUNCTION: + case G_IR_NODE_CALLBACK: + { + GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx); + func->is_varargs = TRUE; + } + break; + case G_IR_NODE_VFUNC: + { + GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx); + vfunc->is_varargs = TRUE; + } + break; + /* list others individually rather than with default: so that compiler + * warns if new node types are added without adding them to the switch + */ + case G_IR_NODE_INVALID: + case G_IR_NODE_ENUM: + case G_IR_NODE_FLAGS: + case G_IR_NODE_CONSTANT: + case G_IR_NODE_ERROR_DOMAIN: + case G_IR_NODE_PARAM: + case G_IR_NODE_TYPE: + case G_IR_NODE_PROPERTY: + case G_IR_NODE_SIGNAL: + case G_IR_NODE_VALUE: + case G_IR_NODE_FIELD: + case G_IR_NODE_XREF: + case G_IR_NODE_STRUCT: + case G_IR_NODE_BOXED: + case G_IR_NODE_OBJECT: + case G_IR_NODE_INTERFACE: + case G_IR_NODE_UNION: + g_assert_not_reached (); + break; + } + } ctx->type_stack = NULL; ctx->type_parameters = NULL; } @@ -2025,51 +2005,53 @@ start_return_value (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - GIrNodeParam *param; - const gchar *transfer; - - if (!(strcmp (element_name, "return-value") == 0 && - ctx->state == STATE_FUNCTION)) - return FALSE; - - param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM); - param->in = FALSE; - param->out = FALSE; - param->retval = TRUE; - - ctx->current_typed = (GIrNode*) param; - - state_switch (ctx, STATE_FUNCTION_RETURN); - - transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); - parse_param_transfer (param, transfer, NULL); - - switch (CURRENT_NODE (ctx)->type) + if (strcmp (element_name, "return-value") == 0 && + ctx->state == STATE_FUNCTION) { - case G_IR_NODE_FUNCTION: - case G_IR_NODE_CALLBACK: - { - GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx); - func->result = param; - } - break; - case G_IR_NODE_SIGNAL: - { - GIrNodeSignal *signal = (GIrNodeSignal *)CURRENT_NODE (ctx); - signal->result = param; - } - break; - case G_IR_NODE_VFUNC: - { - GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx); - vfunc->result = param; - } - break; - default: - g_assert_not_reached (); + GIrNodeParam *param; + const gchar *transfer; + + param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM); + param->in = FALSE; + param->out = FALSE; + param->retval = TRUE; + + ctx->current_typed = (GIrNode*) param; + + state_switch (ctx, STATE_FUNCTION_RETURN); + + transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); + parse_param_transfer (param, transfer, NULL); + + switch (CURRENT_NODE (ctx)->type) + { + case G_IR_NODE_FUNCTION: + case G_IR_NODE_CALLBACK: + { + GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx); + func->result = param; + } + break; + case G_IR_NODE_SIGNAL: + { + GIrNodeSignal *signal = (GIrNodeSignal *)CURRENT_NODE (ctx); + signal->result = param; + } + break; + case G_IR_NODE_VFUNC: + { + GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx); + vfunc->result = param; + } + break; + default: + g_assert_not_reached (); + } + + return TRUE; } - return TRUE; + return FALSE; } static gboolean @@ -2110,78 +2092,78 @@ start_glib_signal (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - const gchar *name; - const gchar *when; - const gchar *no_recurse; - const gchar *detailed; - const gchar *action; - const gchar *no_hooks; - const gchar *has_class_closure; - GIrNodeInterface *iface; - GIrNodeSignal *signal; - - if (!(strcmp (element_name, "glib:signal") == 0 && - (ctx->state == STATE_CLASS || - ctx->state == STATE_INTERFACE))) - return FALSE; - - if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION)) - return TRUE; - - name = find_attribute ("name", attribute_names, attribute_values); - when = find_attribute ("when", attribute_names, attribute_values); - no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values); - detailed = find_attribute ("detailed", attribute_names, attribute_values); - action = find_attribute ("action", attribute_names, attribute_values); - no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values); - has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values); - - if (name == NULL) + if (strcmp (element_name, "glib:signal") == 0 && + (ctx->state == STATE_CLASS || + ctx->state == STATE_INTERFACE)) { - MISSING_ATTRIBUTE (context, error, element_name, "name"); - return FALSE; + const gchar *name; + const gchar *when; + const gchar *no_recurse; + const gchar *detailed; + const gchar *action; + const gchar *no_hooks; + const gchar *has_class_closure; + + name = find_attribute ("name", attribute_names, attribute_values); + when = find_attribute ("when", attribute_names, attribute_values); + no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values); + detailed = find_attribute ("detailed", attribute_names, attribute_values); + action = find_attribute ("action", attribute_names, attribute_values); + no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values); + has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeInterface *iface; + GIrNodeSignal *signal; + + signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL); + + ((GIrNode *)signal)->name = g_strdup (name); + + signal->run_first = FALSE; + signal->run_last = FALSE; + signal->run_cleanup = FALSE; + if (when == NULL || strcmp (when, "LAST") == 0) + signal->run_last = TRUE; + else if (strcmp (when, "FIRST") == 0) + signal->run_first = TRUE; + else + signal->run_cleanup = TRUE; + + if (no_recurse && strcmp (no_recurse, "1") == 0) + signal->no_recurse = TRUE; + else + signal->no_recurse = FALSE; + if (detailed && strcmp (detailed, "1") == 0) + signal->detailed = TRUE; + else + signal->detailed = FALSE; + if (action && strcmp (action, "1") == 0) + signal->action = TRUE; + else + signal->action = FALSE; + if (no_hooks && strcmp (no_hooks, "1") == 0) + signal->no_hooks = TRUE; + else + signal->no_hooks = FALSE; + if (has_class_closure && strcmp (has_class_closure, "1") == 0) + signal->has_class_closure = TRUE; + else + signal->has_class_closure = FALSE; + + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); + iface->members = g_list_append (iface->members, signal); + + push_node (ctx, (GIrNode *)signal); + state_switch (ctx, STATE_FUNCTION); + } + + return TRUE; } - signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL); - - ((GIrNode *)signal)->name = g_strdup (name); - - signal->run_first = FALSE; - signal->run_last = FALSE; - signal->run_cleanup = FALSE; - if (when == NULL || strcmp (when, "LAST") == 0) - signal->run_last = TRUE; - else if (strcmp (when, "FIRST") == 0) - signal->run_first = TRUE; - else - signal->run_cleanup = TRUE; - - if (no_recurse && strcmp (no_recurse, "1") == 0) - signal->no_recurse = TRUE; - else - signal->no_recurse = FALSE; - if (detailed && strcmp (detailed, "1") == 0) - signal->detailed = TRUE; - else - signal->detailed = FALSE; - if (action && strcmp (action, "1") == 0) - signal->action = TRUE; - else - signal->action = FALSE; - if (no_hooks && strcmp (no_hooks, "1") == 0) - signal->no_hooks = TRUE; - else - signal->no_hooks = FALSE; - if (has_class_closure && strcmp (has_class_closure, "1") == 0) - signal->has_class_closure = TRUE; - else - signal->has_class_closure = FALSE; - - iface = (GIrNodeInterface *)CURRENT_NODE (ctx); - iface->members = g_list_append (iface->members, signal); - - push_node (ctx, (GIrNode *)signal); - - return TRUE; + return FALSE; } static gboolean @@ -2192,81 +2174,81 @@ start_vfunc (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - const gchar *name; - const gchar *must_chain_up; - const gchar *override; - const gchar *is_class_closure; - const gchar *offset; - const gchar *invoker; - GIrNodeInterface *iface; - GIrNodeVFunc *vfunc; - - if (!(strcmp (element_name, "virtual-method") == 0 && - (ctx->state == STATE_CLASS || - ctx->state == STATE_INTERFACE))) - return FALSE; - - if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION)) - return TRUE; - - name = find_attribute ("name", attribute_names, attribute_values); - must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values); - override = find_attribute ("override", attribute_names, attribute_values); - is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values); - offset = find_attribute ("offset", attribute_names, attribute_values); - invoker = find_attribute ("invoker", attribute_names, attribute_values); - - if (name == NULL) + if (strcmp (element_name, "virtual-method") == 0 && + (ctx->state == STATE_CLASS || + ctx->state == STATE_INTERFACE)) { - MISSING_ATTRIBUTE (context, error, element_name, "name"); - return FALSE; + const gchar *name; + const gchar *must_chain_up; + const gchar *override; + const gchar *is_class_closure; + const gchar *offset; + const gchar *invoker; + + name = find_attribute ("name", attribute_names, attribute_values); + must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values); + override = find_attribute ("override", attribute_names, attribute_values); + is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values); + offset = find_attribute ("offset", attribute_names, attribute_values); + invoker = find_attribute ("invoker", attribute_names, attribute_values); + + if (name == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeInterface *iface; + GIrNodeVFunc *vfunc; + + vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC); + + ((GIrNode *)vfunc)->name = g_strdup (name); + + if (must_chain_up && strcmp (must_chain_up, "1") == 0) + vfunc->must_chain_up = TRUE; + else + vfunc->must_chain_up = FALSE; + + if (override && strcmp (override, "always") == 0) + { + vfunc->must_be_implemented = TRUE; + vfunc->must_not_be_implemented = FALSE; + } + else if (override && strcmp (override, "never") == 0) + { + vfunc->must_be_implemented = FALSE; + vfunc->must_not_be_implemented = TRUE; + } + else + { + vfunc->must_be_implemented = FALSE; + vfunc->must_not_be_implemented = FALSE; + } + + if (is_class_closure && strcmp (is_class_closure, "1") == 0) + vfunc->is_class_closure = TRUE; + else + vfunc->is_class_closure = FALSE; + + if (offset) + vfunc->offset = atoi (offset); + else + vfunc->offset = 0; + + vfunc->invoker = g_strdup (invoker); + + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); + iface->members = g_list_append (iface->members, vfunc); + + push_node (ctx, (GIrNode *)vfunc); + state_switch (ctx, STATE_FUNCTION); + } + + return TRUE; } - - vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC); - - ((GIrNode *)vfunc)->name = g_strdup (name); - - if (must_chain_up && strcmp (must_chain_up, "1") == 0) - vfunc->must_chain_up = TRUE; - else - vfunc->must_chain_up = FALSE; - - if (override && strcmp (override, "always") == 0) - { - vfunc->must_be_implemented = TRUE; - vfunc->must_not_be_implemented = FALSE; - } - else if (override && strcmp (override, "never") == 0) - { - vfunc->must_be_implemented = FALSE; - vfunc->must_not_be_implemented = TRUE; - } - else - { - vfunc->must_be_implemented = FALSE; - vfunc->must_not_be_implemented = FALSE; - } - - if (is_class_closure && strcmp (is_class_closure, "1") == 0) - vfunc->is_class_closure = TRUE; - else - vfunc->is_class_closure = FALSE; - - if (offset) - vfunc->offset = atoi (offset); - else - vfunc->offset = 0; - - vfunc->invoker = g_strdup (invoker); - - iface = (GIrNodeInterface *)CURRENT_NODE (ctx); - iface->members = g_list_append (iface->members, vfunc); - - push_node (ctx, (GIrNode *)vfunc); - - return TRUE; + return FALSE; } + static gboolean start_struct (GMarkupParseContext *context, const gchar *element_name, @@ -2275,74 +2257,75 @@ start_struct (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - const gchar *name; - const gchar *deprecated; - const gchar *disguised; - const gchar *gtype_name; - const gchar *gtype_init; - const gchar *gtype_struct; - const gchar *foreign; - GIrNodeStruct *struct_; - - if (!(strcmp (element_name, "record") == 0 && - (ctx->state == STATE_NAMESPACE || - ctx->state == STATE_UNION || - ctx->state == STATE_STRUCT || - ctx->state == STATE_CLASS))) - return FALSE; - - if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_STRUCT)) - return TRUE; - - name = find_attribute ("name", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - disguised = find_attribute ("disguised", attribute_names, attribute_values); - gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values); - gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values); - gtype_struct = find_attribute ("glib:is-gtype-struct-for", attribute_names, attribute_values); - foreign = find_attribute ("foreign", attribute_names, attribute_values); - - if (name == NULL && ctx->node_stack == NULL) + if (strcmp (element_name, "record") == 0 && + (ctx->state == STATE_NAMESPACE || + ctx->state == STATE_UNION || + ctx->state == STATE_STRUCT || + ctx->state == STATE_CLASS)) { - MISSING_ATTRIBUTE (context, error, element_name, "name"); - return FALSE; + const gchar *name; + const gchar *deprecated; + const gchar *disguised; + const gchar *gtype_name; + const gchar *gtype_init; + const gchar *gtype_struct; + const gchar *foreign; + GIrNodeStruct *struct_; + + name = find_attribute ("name", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + disguised = find_attribute ("disguised", attribute_names, attribute_values); + gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values); + gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values); + gtype_struct = find_attribute ("glib:is-gtype-struct-for", attribute_names, attribute_values); + foreign = find_attribute ("foreign", attribute_names, attribute_values); + + if (name == NULL && ctx->node_stack == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; + } + if ((gtype_name == NULL && gtype_init != NULL)) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); + return FALSE; + } + if ((gtype_name != NULL && gtype_init == NULL)) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); + return FALSE; + } + + struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT); + + ((GIrNode *)struct_)->name = g_strdup (name ? name : ""); + if (deprecated) + struct_->deprecated = TRUE; + else + struct_->deprecated = FALSE; + + if (disguised && strcmp (disguised, "1") == 0) + struct_->disguised = TRUE; + + struct_->is_gtype_struct = gtype_struct != NULL; + + struct_->gtype_name = g_strdup (gtype_name); + struct_->gtype_init = g_strdup (gtype_init); + + struct_->foreign = (g_strcmp0 (foreign, "1") == 0); + + if (ctx->node_stack == NULL) + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, struct_); + push_node (ctx, (GIrNode *)struct_); + + state_switch (ctx, STATE_STRUCT); + return TRUE; } - if ((gtype_name == NULL && gtype_init != NULL)) - { - MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); - return FALSE; - } - if ((gtype_name != NULL && gtype_init == NULL)) - { - MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); - return FALSE; - } - - struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT); - - ((GIrNode *)struct_)->name = g_strdup (name ? name : ""); - if (deprecated) - struct_->deprecated = TRUE; - else - struct_->deprecated = FALSE; - - if (disguised && strcmp (disguised, "1") == 0) - struct_->disguised = TRUE; - - struct_->is_gtype_struct = gtype_struct != NULL; - - struct_->gtype_name = g_strdup (gtype_name); - struct_->gtype_init = g_strdup (gtype_init); - - struct_->foreign = (g_strcmp0 (foreign, "1") == 0); - - if (ctx->node_stack == NULL) - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, struct_); - push_node (ctx, (GIrNode *)struct_); - return TRUE; + return FALSE; } + static gboolean start_union (GMarkupParseContext *context, const gchar *element_name, @@ -2351,48 +2334,48 @@ start_union (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - const gchar *name; - const gchar *deprecated; - const gchar *typename; - const gchar *typeinit; - GIrNodeUnion *union_; - - if (!(strcmp (element_name, "union") == 0 && - (ctx->state == STATE_NAMESPACE || - ctx->state == STATE_UNION || - ctx->state == STATE_STRUCT || - ctx->state == STATE_CLASS))) - return FALSE; - - if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_UNION)) - return TRUE; - - name = find_attribute ("name", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - typename = find_attribute ("glib:type-name", attribute_names, attribute_values); - typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); - - if (name == NULL && ctx->node_stack == NULL) + if (strcmp (element_name, "union") == 0 && + (ctx->state == STATE_NAMESPACE || + ctx->state == STATE_UNION || + ctx->state == STATE_STRUCT || + ctx->state == STATE_CLASS)) { - MISSING_ATTRIBUTE (context, error, element_name, "name"); - return FALSE; + const gchar *name; + const gchar *deprecated; + const gchar *typename; + const gchar *typeinit; + + name = find_attribute ("name", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + + if (name == NULL && ctx->node_stack == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "name"); + else + { + GIrNodeUnion *union_; + + union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION); + + ((GIrNode *)union_)->name = g_strdup (name ? name : ""); + union_->gtype_name = g_strdup (typename); + union_->gtype_init = g_strdup (typeinit); + if (deprecated) + union_->deprecated = TRUE; + else + union_->deprecated = FALSE; + + if (ctx->node_stack == NULL) + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, union_); + push_node (ctx, (GIrNode *)union_); + + state_switch (ctx, STATE_UNION); + } + return TRUE; } - - union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION); - - ((GIrNode *)union_)->name = g_strdup (name ? name : ""); - union_->gtype_name = g_strdup (typename); - union_->gtype_init = g_strdup (typeinit); - if (deprecated) - union_->deprecated = TRUE; - else - union_->deprecated = FALSE; - - if (ctx->node_stack == NULL) - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, union_); - push_node (ctx, (GIrNode *)union_); - return TRUE; + return FALSE; } static gboolean @@ -2403,43 +2386,42 @@ start_discriminator (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - const gchar *type; - const gchar *offset; - if (!(strcmp (element_name, "discriminator") == 0 && - ctx->state == STATE_UNION)) - return FALSE; + if (strcmp (element_name, "discriminator") == 0 && + ctx->state == STATE_UNION) + { + const gchar *type; + const gchar *offset; - type = find_attribute ("type", attribute_names, attribute_values); - offset = find_attribute ("offset", attribute_names, attribute_values); - if (type == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "type"); - return FALSE; - } - else if (offset == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "offset"); - return FALSE; + type = find_attribute ("type", attribute_names, attribute_values); + offset = find_attribute ("offset", attribute_names, attribute_values); + if (type == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "type"); + else if (offset == NULL) + MISSING_ATTRIBUTE (context, error, element_name, "offset"); + { + ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type + = parse_type (ctx, type); + ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset + = atoi (offset); + } + + return TRUE; } - ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type - = parse_type (ctx, type); - ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset - = atoi (offset); - - return TRUE; + return FALSE; } static gboolean parse_include (GMarkupParseContext *context, ParseContext *ctx, const char *name, - const char *version) + const char *version, + GError **error) { - GError *error = NULL; gchar *buffer; gsize length; gchar *girpath, *girname; + gboolean success = FALSE; GList *modules; GList *l; @@ -2457,8 +2439,11 @@ parse_include (GMarkupParseContext *context, } else { - g_printerr ("Module '%s' imported with conflicting versions '%s' and '%s'\n", - name, m->version, version); + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Module '%s' imported with conflicting versions '%s' and '%s'", + name, m->version, version); return FALSE; } } @@ -2469,7 +2454,10 @@ parse_include (GMarkupParseContext *context, if (girpath == NULL) { - g_printerr ("Could not find GIR file '%s'; check XDG_DATA_DIRS or use --includedir\n", + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Could not find GIR file '%s'; check XDG_DATA_DIRS or use --includedir", girname); g_free (girname); return FALSE; @@ -2478,31 +2466,22 @@ parse_include (GMarkupParseContext *context, g_debug ("Parsing include %s", girpath); - if (!g_file_get_contents (girpath, &buffer, &length, &error)) + if (!g_file_get_contents (girpath, &buffer, &length, error)) { - g_printerr ("%s: %s\n", girpath, error->message); - g_clear_error (&error); - g_free (girpath); - return FALSE; - } - - modules = g_ir_parser_parse_string (ctx->parser, name, girpath, buffer, length, &error); - g_free (buffer); - if (error != NULL) - { - int line_number, char_number; - g_markup_parse_context_get_position (context, &line_number, &char_number); - g_printerr ("%s:%d:%d: error: %s\n", girpath, line_number, char_number, error->message); - g_clear_error (&error); g_free (girpath); return FALSE; } g_free (girpath); + modules = g_ir_parser_parse_string (ctx->parser, name, buffer, length, error); + success = error != NULL; + ctx->include_modules = g_list_concat (ctx->include_modules, modules); - return TRUE; + g_free (buffer); + + return success; } extern GLogLevelFlags logged_levels; @@ -2536,12 +2515,6 @@ start_element_handler (GMarkupParseContext *context, g_string_free (tags, TRUE); } - if (ctx->state == STATE_PASSTHROUGH) - { - ctx->unknown_depth += 1; - return; - } - switch (element_name[0]) { case 'a': @@ -2641,16 +2614,8 @@ start_element_handler (GMarkupParseContext *context, break; } - if (!parse_include (context, ctx, name, version)) - { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Failed to parse included gir %s-%s", - name, - version); - return; - } + if (!parse_include (context, ctx, name, version, error)) + break; ctx->dependencies = g_list_prepend (ctx->dependencies, g_strdup_printf ("%s-%s", name, version)); @@ -2836,22 +2801,22 @@ start_element_handler (GMarkupParseContext *context, break; } - if (ctx->state != STATE_PASSTHROUGH) + if (ctx->state != STATE_UNKNOWN) { - g_markup_parse_context_get_position (context, &line_number, &char_number); - if (!g_str_has_prefix (element_name, "c:")) - g_printerr ("%s:%d:%d: warning: dropping to PASSTHROUGH\n", - ctx->file_path, line_number, char_number); - state_switch (ctx, STATE_PASSTHROUGH); + state_switch (ctx, STATE_UNKNOWN); ctx->unknown_depth = 1; } + else + { + ctx->unknown_depth += 1; + } out: if (*error) { g_markup_parse_context_get_position (context, &line_number, &char_number); - g_printerr ("%s:%d:%d: error: %s\n", ctx->file_path, line_number, char_number, (*error)->message); + fprintf (stderr, "Error at line %d, character %d: %s\n", line_number, char_number, (*error)->message); backtrace_stderr (); } } @@ -3224,7 +3189,7 @@ end_element_handler (GMarkupParseContext *context, } break; - case STATE_PASSTHROUGH: + case STATE_UNKNOWN: ctx->unknown_depth -= 1; if (ctx->unknown_depth == 0) state_switch (ctx, ctx->prev_state); @@ -3260,11 +3225,149 @@ cleanup (GMarkupParseContext *context, ctx->current_module = NULL; } +static GList * +post_filter_toplevel_varargs_functions (GList *list, + GList **varargs_callbacks_out) +{ + GList *iter; + GList *varargs_callbacks = *varargs_callbacks_out; + + iter = list; + while (iter) + { + GList *link = iter; + GIrNode *node = iter->data; + + iter = iter->next; + + if (node->type == G_IR_NODE_FUNCTION) + { + if (((GIrNodeFunction*)node)->is_varargs) + { + list = g_list_delete_link (list, link); + } + } + if (node->type == G_IR_NODE_CALLBACK) + { + if (((GIrNodeFunction*)node)->is_varargs) + { + varargs_callbacks = g_list_append (varargs_callbacks, + node); + list = g_list_delete_link (list, link); + } + } + } + + *varargs_callbacks_out = varargs_callbacks; + + return list; +} + +static GList * +post_filter_varargs_functions (GList *list, GList ** varargs_callbacks_out) +{ + GList *iter; + GList *varargs_callbacks; + + list = post_filter_toplevel_varargs_functions (list, varargs_callbacks_out); + + varargs_callbacks = *varargs_callbacks_out; + + iter = list; + while (iter) + { + GList *link = iter; + GIrNode *node = iter->data; + + iter = iter->next; + + if (node->type == G_IR_NODE_FUNCTION) + { + GList *param; + gboolean function_done = FALSE; + + for (param = ((GIrNodeFunction *)node)->parameters; + param; + param = param->next) + { + GIrNodeParam *node = (GIrNodeParam *)param->data; + + if (function_done) + break; + + if (node->type->is_interface) + { + GList *callback; + for (callback = varargs_callbacks; + callback; + callback = callback->next) + { + if (!strcmp (node->type->interface, + ((GIrNode *)varargs_callbacks->data)->name)) + { + list = g_list_delete_link (list, link); + function_done = TRUE; + break; + } + } + } + } + } + } + + *varargs_callbacks_out = varargs_callbacks; + + return list; +} + +static void +post_filter (GIrModule *module) +{ + GList *iter; + GList *varargs_callbacks = NULL; + + module->entries = post_filter_varargs_functions (module->entries, + &varargs_callbacks); + iter = module->entries; + while (iter) + { + GIrNode *node = iter->data; + + iter = iter->next; + + if (node->type == G_IR_NODE_OBJECT || + node->type == G_IR_NODE_INTERFACE) + { + GIrNodeInterface *iface = (GIrNodeInterface*)node; + iface->members = post_filter_varargs_functions (iface->members, + &varargs_callbacks); + } + else if (node->type == G_IR_NODE_BOXED) + { + GIrNodeBoxed *boxed = (GIrNodeBoxed*)node; + boxed->members = post_filter_varargs_functions (boxed->members, + &varargs_callbacks); + } + else if (node->type == G_IR_NODE_STRUCT) + { + GIrNodeStruct *iface = (GIrNodeStruct*)node; + iface->members = post_filter_varargs_functions (iface->members, + &varargs_callbacks); + } + else if (node->type == G_IR_NODE_UNION) + { + GIrNodeUnion *iface = (GIrNodeUnion*)node; + iface->members = post_filter_varargs_functions (iface->members, + &varargs_callbacks); + } + } + g_list_free (varargs_callbacks); +} + /** * g_ir_parser_parse_string: * @parser: a #GIrParser * @namespace: the namespace of the string - * @filename: (allow-none): Path to parsed file, or %NULL * @buffer: the data containing the XML * @length: length of the data * @error: return location for a #GError, or %NULL @@ -3278,7 +3381,6 @@ cleanup (GMarkupParseContext *context, GList * g_ir_parser_parse_string (GIrParser *parser, const gchar *namespace, - const gchar *filename, const gchar *buffer, gssize length, GError **error) @@ -3288,7 +3390,6 @@ g_ir_parser_parse_string (GIrParser *parser, ctx.parser = parser; ctx.state = STATE_START; - ctx.file_path = filename; ctx.namespace = namespace; ctx.include_modules = NULL; ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); @@ -3356,6 +3457,7 @@ g_ir_parser_parse_file (GIrParser *parser, gchar *buffer; gsize length; GList *modules; + GList *iter; const char *slash; char *dash; char *namespace; @@ -3386,7 +3488,12 @@ g_ir_parser_parse_file (GIrParser *parser, if (!g_file_get_contents (filename, &buffer, &length, error)) return NULL; - modules = g_ir_parser_parse_string (parser, namespace, filename, buffer, length, error); + modules = g_ir_parser_parse_string (parser, namespace, buffer, length, error); + + for (iter = modules; iter; iter = iter->next) + { + post_filter ((GIrModule*)iter->data); + } g_free (namespace); diff --git a/girparser.h b/girparser.h index 6fca1b3da..ac0d216b2 100644 --- a/girparser.h +++ b/girparser.h @@ -34,7 +34,6 @@ void g_ir_parser_set_includes (GIrParser *parser, GList *g_ir_parser_parse_string (GIrParser *parser, const gchar *namespace, - const gchar *filename, const gchar *buffer, gssize length, GError **error); From 911d98bb9d6706e76f3a6042117fb9dbe9196b85 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 17 Jun 2010 10:38:39 -0400 Subject: [PATCH 348/692] More explicitly document how we'll use the version= attribute on repository I want to start bumping it on incompatible .gir changes. https://bugzilla.gnome.org/show_bug.cgi?id=621895 --- girparser.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index d0bd8aa36..f9c1fb665 100644 --- a/girparser.c +++ b/girparser.c @@ -30,6 +30,11 @@ #include "gitypelib-internal.h" #include "config.h" +/* This is a "major" version in the sense that it's only bumped + * for incompatible changes. + */ +#define SUPPORTED_GIR_VERSION "1.0" + #if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS) # include #endif @@ -2754,7 +2759,7 @@ start_element_handler (GMarkupParseContext *context, if (version == NULL) MISSING_ATTRIBUTE (context, error, element_name, "version"); - else if (strcmp (version, "1.0") != 0) + else if (strcmp (version, SUPPORTED_GIR_VERSION) != 0) g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, From 2f11782f51bfab2dc1396821d8d41ce10cd9fb30 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 16 Jun 2010 20:34:18 -0400 Subject: [PATCH 349/692] Support introspectable=no attribute, add warnings framework This work allows us to move closer to replacing gtk-doc, among other things. We add a generic attribute "introspectable", and inside the typelib compiler if we see "introspectable=no", we don't put it in the typelib. This replaces the hackish pre-filter for varargs with a much more generic mechanism. The varargs is now handled in the scanner, and we emit introspectable=no for them. Add generic metadata to Node with references to file/line/column, which currently comes from symbols. Add scanner options --warn-all and --warn-error. https://bugzilla.gnome.org/show_bug.cgi?id=621570 --- girparser.c | 1635 ++++++++++++++++++++++++--------------------------- girparser.h | 1 + 2 files changed, 765 insertions(+), 871 deletions(-) diff --git a/girparser.c b/girparser.c index f9c1fb665..1badfd7e8 100644 --- a/girparser.c +++ b/girparser.c @@ -33,7 +33,7 @@ /* This is a "major" version in the sense that it's only bumped * for incompatible changes. */ -#define SUPPORTED_GIR_VERSION "1.0" +#define SUPPORTED_GIR_VERSION "1.1" #if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS) # include @@ -77,10 +77,10 @@ typedef enum STATE_NAMESPACE_CONSTANT, STATE_CLASS_CONSTANT, STATE_INTERFACE_CONSTANT, - STATE_ALIAS, + STATE_ALIAS, /* 30 */ STATE_TYPE, STATE_ATTRIBUTE, - STATE_UNKNOWN + STATE_PASSTHROUGH } ParseState; typedef struct _ParseContext ParseContext; @@ -98,12 +98,12 @@ struct _ParseContext GHashTable *aliases; GHashTable *disguised_structures; + const char *file_path; const char *namespace; const char *c_prefix; GIrModule *current_module; GSList *node_stack; GIrNode *current_typed; - gboolean is_varargs; GList *type_stack; GList *type_parameters; int type_depth; @@ -322,7 +322,7 @@ find_attribute (const gchar *name, static void state_switch (ParseContext *ctx, ParseState newstate) { - g_debug ("State: %d", newstate); + g_assert (ctx->state != newstate); ctx->prev_state = ctx->state; ctx->state = newstate; } @@ -344,6 +344,7 @@ pop_node (ParseContext *ctx) static void push_node (ParseContext *ctx, GIrNode *node) { + g_assert (node != NULL); g_debug ("pushing node %d %s", node->type, node->name); ctx->node_stack = g_slist_prepend (ctx->node_stack, node); } @@ -634,6 +635,32 @@ parse_type (ParseContext *ctx, const gchar *type) return node; } +static gboolean +introspectable_prelude (GMarkupParseContext *context, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + ParseState new_state) +{ + const gchar *introspectable_arg; + gboolean introspectable; + + g_assert (ctx->state != STATE_PASSTHROUGH); + + introspectable_arg = find_attribute ("introspectable", attribute_names, attribute_values); + introspectable = !(introspectable_arg && atoi (introspectable_arg) == 0); + + if (introspectable) + state_switch (ctx, new_state); + else + { + state_switch (ctx, STATE_PASSTHROUGH); + ctx->unknown_depth = 1; + } + + return introspectable; +} + static gboolean start_glib_boxed (GMarkupParseContext *context, const gchar *element_name, @@ -652,6 +679,9 @@ start_glib_boxed (GMarkupParseContext *context, ctx->state == STATE_NAMESPACE)) return FALSE; + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_BOXED)) + return TRUE; + name = find_attribute ("glib:name", attribute_names, attribute_values); typename = find_attribute ("glib:type-name", attribute_names, attribute_values); typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); @@ -687,8 +717,6 @@ start_glib_boxed (GMarkupParseContext *context, ctx->current_module->entries = g_list_append (ctx->current_module->entries, boxed); - state_switch (ctx, STATE_BOXED); - return TRUE; } @@ -727,7 +755,6 @@ start_function (GMarkupParseContext *context, strcmp (element_name, "callback") == 0); break; case STATE_STRUCT_FIELD: - ctx->in_embedded_type = TRUE; found = (found || strcmp (element_name, "callback") == 0); break; default: @@ -737,6 +764,12 @@ start_function (GMarkupParseContext *context, if (!found) return FALSE; + if (ctx->state == STATE_STRUCT_FIELD) + ctx->in_embedded_type = TRUE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION)) + return TRUE; + name = find_attribute ("name", attribute_names, attribute_values); symbol = find_attribute ("c:identifier", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); @@ -840,7 +873,6 @@ start_function (GMarkupParseContext *context, } push_node(ctx, (GIrNode *)function); - state_switch (ctx, STATE_FUNCTION); return TRUE; } @@ -1223,47 +1255,47 @@ start_enum (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if ((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) || - (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE)) + const gchar *name; + const gchar *typename; + const gchar *typeinit; + const gchar *deprecated; + GIrNodeEnum *enum_; + + if (!((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) || + (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE))) + return FALSE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_ENUM)) + return TRUE; + + name = find_attribute ("name", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) { - const gchar *name; - const gchar *typename; - const gchar *typeinit; - const gchar *deprecated; - - name = find_attribute ("name", attribute_names, attribute_values); - typename = find_attribute ("glib:type-name", attribute_names, attribute_values); - typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { - GIrNodeEnum *enum_; - - if (strcmp (element_name, "enumeration") == 0) - enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM); - else - enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS); - ((GIrNode *)enum_)->name = g_strdup (name); - enum_->gtype_name = g_strdup (typename); - enum_->gtype_init = g_strdup (typeinit); - if (deprecated) - enum_->deprecated = TRUE; - else - enum_->deprecated = FALSE; - - push_node (ctx, (GIrNode *) enum_); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, enum_); - - state_switch (ctx, STATE_ENUM); - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; + + if (strcmp (element_name, "enumeration") == 0) + enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM); + else + enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS); + ((GIrNode *)enum_)->name = g_strdup (name); + enum_->gtype_name = g_strdup (typename); + enum_->gtype_init = g_strdup (typeinit); + if (deprecated) + enum_->deprecated = TRUE; + else + enum_->deprecated = FALSE; + + push_node (ctx, (GIrNode *) enum_); + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, enum_); + + return TRUE; } static gboolean @@ -1274,70 +1306,74 @@ start_property (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "property") == 0 && - (ctx->state == STATE_CLASS || - ctx->state == STATE_INTERFACE)) + ParseState target_state; + const gchar *name; + const gchar *readable; + const gchar *writable; + const gchar *construct; + const gchar *construct_only; + const gchar *transfer; + GIrNodeProperty *property; + GIrNodeInterface *iface; + + if (!(strcmp (element_name, "property") == 0 && + (ctx->state == STATE_CLASS || + ctx->state == STATE_INTERFACE))) + return FALSE; + + if (ctx->state == STATE_CLASS) + target_state = STATE_CLASS_PROPERTY; + else if (ctx->state == STATE_INTERFACE) + target_state = STATE_INTERFACE_PROPERTY; + else + g_assert_not_reached (); + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, target_state)) + return TRUE; + + + name = find_attribute ("name", attribute_names, attribute_values); + readable = find_attribute ("readable", attribute_names, attribute_values); + writable = find_attribute ("writable", attribute_names, attribute_values); + construct = find_attribute ("construct", attribute_names, attribute_values); + construct_only = find_attribute ("construct-only", attribute_names, attribute_values); + transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); + + if (name == NULL) { - const gchar *name; - const gchar *readable; - const gchar *writable; - const gchar *construct; - const gchar *construct_only; - const gchar *transfer; - - name = find_attribute ("name", attribute_names, attribute_values); - readable = find_attribute ("readable", attribute_names, attribute_values); - writable = find_attribute ("writable", attribute_names, attribute_values); - construct = find_attribute ("construct", attribute_names, attribute_values); - construct_only = find_attribute ("construct-only", attribute_names, attribute_values); - transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { - GIrNodeProperty *property; - GIrNodeInterface *iface; - - property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY); - ctx->current_typed = (GIrNode*) property; - - ((GIrNode *)property)->name = g_strdup (name); - - /* Assume properties are readable */ - if (readable == NULL || strcmp (readable, "1") == 0) - property->readable = TRUE; - else - property->readable = FALSE; - if (writable && strcmp (writable, "1") == 0) - property->writable = TRUE; - else - property->writable = FALSE; - if (construct && strcmp (construct, "1") == 0) - property->construct = TRUE; - else - property->construct = FALSE; - if (construct_only && strcmp (construct_only, "1") == 0) - property->construct_only = TRUE; - else - property->construct_only = FALSE; - - parse_property_transfer (property, transfer, ctx); - - iface = (GIrNodeInterface *)CURRENT_NODE (ctx); - iface->members = g_list_append (iface->members, property); - - if (ctx->state == STATE_CLASS) - state_switch (ctx, STATE_CLASS_PROPERTY); - else if (ctx->state == STATE_INTERFACE) - state_switch (ctx, STATE_INTERFACE_PROPERTY); - else - g_assert_not_reached (); - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; + + property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY); + ctx->current_typed = (GIrNode*) property; + + ((GIrNode *)property)->name = g_strdup (name); + + /* Assume properties are readable */ + if (readable == NULL || strcmp (readable, "1") == 0) + property->readable = TRUE; + else + property->readable = FALSE; + if (writable && strcmp (writable, "1") == 0) + property->writable = TRUE; + else + property->writable = FALSE; + if (construct && strcmp (construct, "1") == 0) + property->construct = TRUE; + else + property->construct = FALSE; + if (construct_only && strcmp (construct_only, "1") == 0) + property->construct_only = TRUE; + else + property->construct_only = FALSE; + + parse_property_transfer (property, transfer, ctx); + + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); + iface->members = g_list_append (iface->members, property); + + return TRUE; } static gint @@ -1371,42 +1407,41 @@ start_member (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "member") == 0 && - ctx->state == STATE_ENUM) + const gchar *name; + const gchar *value; + const gchar *deprecated; + GIrNodeEnum *enum_; + GIrNodeValue *value_; + + if (!(strcmp (element_name, "member") == 0 && + ctx->state == STATE_ENUM)) + return FALSE; + + name = find_attribute ("name", attribute_names, attribute_values); + value = find_attribute ("value", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) { - const gchar *name; - const gchar *value; - const gchar *deprecated; - - name = find_attribute ("name", attribute_names, attribute_values); - value = find_attribute ("value", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { - GIrNodeEnum *enum_; - GIrNodeValue *value_; - - value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE); - - ((GIrNode *)value_)->name = g_strdup (name); - - value_->value = parse_value (value); - - if (deprecated) - value_->deprecated = TRUE; - else - value_->deprecated = FALSE; - - enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx); - enum_->values = g_list_append (enum_->values, value_); - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; + + value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE); + + ((GIrNode *)value_)->name = g_strdup (name); + + value_->value = parse_value (value); + + if (deprecated) + value_->deprecated = TRUE; + else + value_->deprecated = FALSE; + + enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx); + enum_->values = g_list_append (enum_->values, value_); + + return TRUE; } static gboolean @@ -1417,73 +1452,81 @@ start_constant (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "constant") == 0 && - (ctx->state == STATE_NAMESPACE || - ctx->state == STATE_CLASS || - ctx->state == STATE_INTERFACE)) + ParseState prev_state; + ParseState target_state; + const gchar *name; + const gchar *value; + const gchar *deprecated; + GIrNodeConstant *constant; + + if (!(strcmp (element_name, "constant") == 0 && + (ctx->state == STATE_NAMESPACE || + ctx->state == STATE_CLASS || + ctx->state == STATE_INTERFACE))) + return FALSE; + + switch (ctx->state) { - const gchar *name; - const gchar *value; - const gchar *deprecated; - - name = find_attribute ("name", attribute_names, attribute_values); - value = find_attribute ("value", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else if (value == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "value"); - else - { - GIrNodeConstant *constant; - - constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT); - - ((GIrNode *)constant)->name = g_strdup (name); - constant->value = g_strdup (value); - - ctx->current_typed = (GIrNode*) constant; - - if (deprecated) - constant->deprecated = TRUE; - else - constant->deprecated = FALSE; - - if (ctx->state == STATE_NAMESPACE) - { - push_node (ctx, (GIrNode *) constant); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, constant); - } - else - { - GIrNodeInterface *iface; - - iface = (GIrNodeInterface *)CURRENT_NODE (ctx); - iface->members = g_list_append (iface->members, constant); - } - - switch (ctx->state) - { - case STATE_NAMESPACE: - state_switch (ctx, STATE_NAMESPACE_CONSTANT); - break; - case STATE_CLASS: - state_switch (ctx, STATE_CLASS_CONSTANT); - break; - case STATE_INTERFACE: - state_switch (ctx, STATE_INTERFACE_CONSTANT); - break; - default: - g_assert_not_reached (); - break; - } - } - - return TRUE; + case STATE_NAMESPACE: + target_state = STATE_NAMESPACE_CONSTANT; + break; + case STATE_CLASS: + target_state = STATE_CLASS_CONSTANT; + break; + case STATE_INTERFACE: + target_state = STATE_INTERFACE_CONSTANT; + break; + default: + g_assert_not_reached (); } - return FALSE; + + prev_state = ctx->state; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, target_state)) + return TRUE; + + name = find_attribute ("name", attribute_names, attribute_values); + value = find_attribute ("value", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; + } + else if (value == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "value"); + return FALSE; + } + + constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT); + + ((GIrNode *)constant)->name = g_strdup (name); + constant->value = g_strdup (value); + + ctx->current_typed = (GIrNode*) constant; + + if (deprecated) + constant->deprecated = TRUE; + else + constant->deprecated = FALSE; + + if (prev_state == STATE_NAMESPACE) + { + push_node (ctx, (GIrNode *) constant); + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, constant); + } + else + { + GIrNodeInterface *iface; + + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); + iface->members = g_list_append (iface->members, constant); + } + + return TRUE; } static gboolean @@ -1494,50 +1537,57 @@ start_errordomain (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "errordomain") == 0 && - ctx->state == STATE_NAMESPACE) + const gchar *name; + const gchar *getquark; + const gchar *codes; + const gchar *deprecated; + GIrNodeErrorDomain *domain; + + if (!(strcmp (element_name, "errordomain") == 0 && + ctx->state == STATE_NAMESPACE)) + return FALSE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_ERRORDOMAIN)) + return TRUE; + + + name = find_attribute ("name", attribute_names, attribute_values); + getquark = find_attribute ("get-quark", attribute_names, attribute_values); + codes = find_attribute ("codes", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) { - const gchar *name; - const gchar *getquark; - const gchar *codes; - const gchar *deprecated; - - name = find_attribute ("name", attribute_names, attribute_values); - getquark = find_attribute ("get-quark", attribute_names, attribute_values); - codes = find_attribute ("codes", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else if (getquark == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "getquark"); - else if (codes == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "codes"); - else - { - GIrNodeErrorDomain *domain; - - domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN); - - ((GIrNode *)domain)->name = g_strdup (name); - domain->getquark = g_strdup (getquark); - domain->codes = g_strdup (codes); - - if (deprecated) - domain->deprecated = TRUE; - else - domain->deprecated = FALSE; - - push_node (ctx, (GIrNode *) domain); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, domain); - - state_switch (ctx, STATE_ERRORDOMAIN); - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; + else if (getquark == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "getquark"); + return FALSE; + } + else if (codes == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "codes"); + return FALSE; + } + + domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN); + + ((GIrNode *)domain)->name = g_strdup (name); + domain->getquark = g_strdup (getquark); + domain->codes = g_strdup (codes); + + if (deprecated) + domain->deprecated = TRUE; + else + domain->deprecated = FALSE; + + push_node (ctx, (GIrNode *) domain); + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, domain); + + return TRUE; } static gboolean @@ -1548,52 +1598,57 @@ start_interface (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "interface") == 0 && - ctx->state == STATE_NAMESPACE) + const gchar *name; + const gchar *typename; + const gchar *typeinit; + const gchar *deprecated; + const gchar *glib_type_struct; + GIrNodeInterface *iface; + + if (!(strcmp (element_name, "interface") == 0 && + ctx->state == STATE_NAMESPACE)) + return FALSE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_INTERFACE)) + return TRUE; + + name = find_attribute ("name", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + + if (name == NULL) { - const gchar *name; - const gchar *typename; - const gchar *typeinit; - const gchar *deprecated; - const gchar *glib_type_struct; - - name = find_attribute ("name", attribute_names, attribute_values); - typename = find_attribute ("glib:type-name", attribute_names, attribute_values); - typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); - glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else if (typename == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); - else if (typeinit == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); - else - { - GIrNodeInterface *iface; - - iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE); - ((GIrNode *)iface)->name = g_strdup (name); - iface->gtype_name = g_strdup (typename); - iface->gtype_init = g_strdup (typeinit); - iface->glib_type_struct = g_strdup (glib_type_struct); - if (deprecated) - iface->deprecated = TRUE; - else - iface->deprecated = FALSE; - - push_node (ctx, (GIrNode *) iface); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, iface); - - state_switch (ctx, STATE_INTERFACE); - - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; + else if (typename == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); + return FALSE; + } + else if (typeinit == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); + return FALSE; + } + + iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE); + ((GIrNode *)iface)->name = g_strdup (name); + iface->gtype_name = g_strdup (typename); + iface->gtype_init = g_strdup (typeinit); + iface->glib_type_struct = g_strdup (glib_type_struct); + if (deprecated) + iface->deprecated = TRUE; + else + iface->deprecated = FALSE; + + push_node (ctx, (GIrNode *) iface); + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, iface); + + return TRUE; } static gboolean @@ -1604,58 +1659,64 @@ start_class (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "class") == 0 && - ctx->state == STATE_NAMESPACE) + const gchar *name; + const gchar *parent; + const gchar *glib_type_struct; + const gchar *typename; + const gchar *typeinit; + const gchar *deprecated; + const gchar *abstract; + GIrNodeInterface *iface; + + if (!(strcmp (element_name, "class") == 0 && + ctx->state == STATE_NAMESPACE)) + return FALSE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_CLASS)) + return TRUE; + + name = find_attribute ("name", attribute_names, attribute_values); + parent = find_attribute ("parent", attribute_names, attribute_values); + glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + abstract = find_attribute ("abstract", attribute_names, attribute_values); + + if (name == NULL) { - const gchar *name; - const gchar *parent; - const gchar *glib_type_struct; - const gchar *typename; - const gchar *typeinit; - const gchar *deprecated; - const gchar *abstract; - - name = find_attribute ("name", attribute_names, attribute_values); - parent = find_attribute ("parent", attribute_names, attribute_values); - glib_type_struct = find_attribute ("glib:type-struct", attribute_names, attribute_values); - typename = find_attribute ("glib:type-name", attribute_names, attribute_values); - typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - abstract = find_attribute ("abstract", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else if (typename == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); - else if (typeinit == NULL && strcmp (typename, "GObject")) - MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); - else - { - GIrNodeInterface *iface; - - iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT); - ((GIrNode *)iface)->name = g_strdup (name); - iface->gtype_name = g_strdup (typename); - iface->gtype_init = g_strdup (typeinit); - iface->parent = g_strdup (parent); - iface->glib_type_struct = g_strdup (glib_type_struct); - if (deprecated) - iface->deprecated = TRUE; - else - iface->deprecated = FALSE; - - iface->abstract = abstract && strcmp (abstract, "1") == 0; - - push_node (ctx, (GIrNode *) iface); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, iface); - - state_switch (ctx, STATE_CLASS); - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; + else if (typename == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); + return FALSE; + } + else if (typeinit == NULL && strcmp (typename, "GObject")) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); + return FALSE; + } + + iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT); + ((GIrNode *)iface)->name = g_strdup (name); + iface->gtype_name = g_strdup (typename); + iface->gtype_init = g_strdup (typeinit); + iface->parent = g_strdup (parent); + iface->glib_type_struct = g_strdup (glib_type_struct); + if (deprecated) + iface->deprecated = TRUE; + else + iface->deprecated = FALSE; + + iface->abstract = abstract && strcmp (abstract, "1") == 0; + + push_node (ctx, (GIrNode *) iface); + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, iface); + + return TRUE; } static gboolean @@ -1700,47 +1761,6 @@ start_type (GMarkupParseContext *context, { state_switch (ctx, STATE_TYPE); ctx->type_depth = 1; - if (is_varargs) - { - switch (CURRENT_NODE (ctx)->type) - { - case G_IR_NODE_FUNCTION: - case G_IR_NODE_CALLBACK: - { - GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx); - func->is_varargs = TRUE; - } - break; - case G_IR_NODE_VFUNC: - { - GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx); - vfunc->is_varargs = TRUE; - } - break; - /* list others individually rather than with default: so that compiler - * warns if new node types are added without adding them to the switch - */ - case G_IR_NODE_INVALID: - case G_IR_NODE_ENUM: - case G_IR_NODE_FLAGS: - case G_IR_NODE_CONSTANT: - case G_IR_NODE_ERROR_DOMAIN: - case G_IR_NODE_PARAM: - case G_IR_NODE_TYPE: - case G_IR_NODE_PROPERTY: - case G_IR_NODE_SIGNAL: - case G_IR_NODE_VALUE: - case G_IR_NODE_FIELD: - case G_IR_NODE_XREF: - case G_IR_NODE_STRUCT: - case G_IR_NODE_BOXED: - case G_IR_NODE_OBJECT: - case G_IR_NODE_INTERFACE: - case G_IR_NODE_UNION: - g_assert_not_reached (); - break; - } - } ctx->type_stack = NULL; ctx->type_parameters = NULL; } @@ -2010,53 +2030,51 @@ start_return_value (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "return-value") == 0 && - ctx->state == STATE_FUNCTION) + GIrNodeParam *param; + const gchar *transfer; + + if (!(strcmp (element_name, "return-value") == 0 && + ctx->state == STATE_FUNCTION)) + return FALSE; + + param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM); + param->in = FALSE; + param->out = FALSE; + param->retval = TRUE; + + ctx->current_typed = (GIrNode*) param; + + state_switch (ctx, STATE_FUNCTION_RETURN); + + transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); + parse_param_transfer (param, transfer, NULL); + + switch (CURRENT_NODE (ctx)->type) { - GIrNodeParam *param; - const gchar *transfer; - - param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM); - param->in = FALSE; - param->out = FALSE; - param->retval = TRUE; - - ctx->current_typed = (GIrNode*) param; - - state_switch (ctx, STATE_FUNCTION_RETURN); - - transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); - parse_param_transfer (param, transfer, NULL); - - switch (CURRENT_NODE (ctx)->type) - { - case G_IR_NODE_FUNCTION: - case G_IR_NODE_CALLBACK: - { - GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx); - func->result = param; - } - break; - case G_IR_NODE_SIGNAL: - { - GIrNodeSignal *signal = (GIrNodeSignal *)CURRENT_NODE (ctx); - signal->result = param; - } - break; - case G_IR_NODE_VFUNC: - { - GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx); - vfunc->result = param; - } - break; - default: - g_assert_not_reached (); - } - - return TRUE; + case G_IR_NODE_FUNCTION: + case G_IR_NODE_CALLBACK: + { + GIrNodeFunction *func = (GIrNodeFunction *)CURRENT_NODE (ctx); + func->result = param; + } + break; + case G_IR_NODE_SIGNAL: + { + GIrNodeSignal *signal = (GIrNodeSignal *)CURRENT_NODE (ctx); + signal->result = param; + } + break; + case G_IR_NODE_VFUNC: + { + GIrNodeVFunc *vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx); + vfunc->result = param; + } + break; + default: + g_assert_not_reached (); } - return FALSE; + return TRUE; } static gboolean @@ -2097,78 +2115,78 @@ start_glib_signal (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "glib:signal") == 0 && - (ctx->state == STATE_CLASS || - ctx->state == STATE_INTERFACE)) + const gchar *name; + const gchar *when; + const gchar *no_recurse; + const gchar *detailed; + const gchar *action; + const gchar *no_hooks; + const gchar *has_class_closure; + GIrNodeInterface *iface; + GIrNodeSignal *signal; + + if (!(strcmp (element_name, "glib:signal") == 0 && + (ctx->state == STATE_CLASS || + ctx->state == STATE_INTERFACE))) + return FALSE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION)) + return TRUE; + + name = find_attribute ("name", attribute_names, attribute_values); + when = find_attribute ("when", attribute_names, attribute_values); + no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values); + detailed = find_attribute ("detailed", attribute_names, attribute_values); + action = find_attribute ("action", attribute_names, attribute_values); + no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values); + has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values); + + if (name == NULL) { - const gchar *name; - const gchar *when; - const gchar *no_recurse; - const gchar *detailed; - const gchar *action; - const gchar *no_hooks; - const gchar *has_class_closure; - - name = find_attribute ("name", attribute_names, attribute_values); - when = find_attribute ("when", attribute_names, attribute_values); - no_recurse = find_attribute ("no-recurse", attribute_names, attribute_values); - detailed = find_attribute ("detailed", attribute_names, attribute_values); - action = find_attribute ("action", attribute_names, attribute_values); - no_hooks = find_attribute ("no-hooks", attribute_names, attribute_values); - has_class_closure = find_attribute ("has-class-closure", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { - GIrNodeInterface *iface; - GIrNodeSignal *signal; - - signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL); - - ((GIrNode *)signal)->name = g_strdup (name); - - signal->run_first = FALSE; - signal->run_last = FALSE; - signal->run_cleanup = FALSE; - if (when == NULL || strcmp (when, "LAST") == 0) - signal->run_last = TRUE; - else if (strcmp (when, "FIRST") == 0) - signal->run_first = TRUE; - else - signal->run_cleanup = TRUE; - - if (no_recurse && strcmp (no_recurse, "1") == 0) - signal->no_recurse = TRUE; - else - signal->no_recurse = FALSE; - if (detailed && strcmp (detailed, "1") == 0) - signal->detailed = TRUE; - else - signal->detailed = FALSE; - if (action && strcmp (action, "1") == 0) - signal->action = TRUE; - else - signal->action = FALSE; - if (no_hooks && strcmp (no_hooks, "1") == 0) - signal->no_hooks = TRUE; - else - signal->no_hooks = FALSE; - if (has_class_closure && strcmp (has_class_closure, "1") == 0) - signal->has_class_closure = TRUE; - else - signal->has_class_closure = FALSE; - - iface = (GIrNodeInterface *)CURRENT_NODE (ctx); - iface->members = g_list_append (iface->members, signal); - - push_node (ctx, (GIrNode *)signal); - state_switch (ctx, STATE_FUNCTION); - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; + signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL); + + ((GIrNode *)signal)->name = g_strdup (name); + + signal->run_first = FALSE; + signal->run_last = FALSE; + signal->run_cleanup = FALSE; + if (when == NULL || strcmp (when, "LAST") == 0) + signal->run_last = TRUE; + else if (strcmp (when, "FIRST") == 0) + signal->run_first = TRUE; + else + signal->run_cleanup = TRUE; + + if (no_recurse && strcmp (no_recurse, "1") == 0) + signal->no_recurse = TRUE; + else + signal->no_recurse = FALSE; + if (detailed && strcmp (detailed, "1") == 0) + signal->detailed = TRUE; + else + signal->detailed = FALSE; + if (action && strcmp (action, "1") == 0) + signal->action = TRUE; + else + signal->action = FALSE; + if (no_hooks && strcmp (no_hooks, "1") == 0) + signal->no_hooks = TRUE; + else + signal->no_hooks = FALSE; + if (has_class_closure && strcmp (has_class_closure, "1") == 0) + signal->has_class_closure = TRUE; + else + signal->has_class_closure = FALSE; + + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); + iface->members = g_list_append (iface->members, signal); + + push_node (ctx, (GIrNode *)signal); + + return TRUE; } static gboolean @@ -2179,80 +2197,80 @@ start_vfunc (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "virtual-method") == 0 && - (ctx->state == STATE_CLASS || - ctx->state == STATE_INTERFACE)) + const gchar *name; + const gchar *must_chain_up; + const gchar *override; + const gchar *is_class_closure; + const gchar *offset; + const gchar *invoker; + GIrNodeInterface *iface; + GIrNodeVFunc *vfunc; + + if (!(strcmp (element_name, "virtual-method") == 0 && + (ctx->state == STATE_CLASS || + ctx->state == STATE_INTERFACE))) + return FALSE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION)) + return TRUE; + + name = find_attribute ("name", attribute_names, attribute_values); + must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values); + override = find_attribute ("override", attribute_names, attribute_values); + is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values); + offset = find_attribute ("offset", attribute_names, attribute_values); + invoker = find_attribute ("invoker", attribute_names, attribute_values); + + if (name == NULL) { - const gchar *name; - const gchar *must_chain_up; - const gchar *override; - const gchar *is_class_closure; - const gchar *offset; - const gchar *invoker; - - name = find_attribute ("name", attribute_names, attribute_values); - must_chain_up = find_attribute ("must-chain-up", attribute_names, attribute_values); - override = find_attribute ("override", attribute_names, attribute_values); - is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values); - offset = find_attribute ("offset", attribute_names, attribute_values); - invoker = find_attribute ("invoker", attribute_names, attribute_values); - - if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { - GIrNodeInterface *iface; - GIrNodeVFunc *vfunc; - - vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC); - - ((GIrNode *)vfunc)->name = g_strdup (name); - - if (must_chain_up && strcmp (must_chain_up, "1") == 0) - vfunc->must_chain_up = TRUE; - else - vfunc->must_chain_up = FALSE; - - if (override && strcmp (override, "always") == 0) - { - vfunc->must_be_implemented = TRUE; - vfunc->must_not_be_implemented = FALSE; - } - else if (override && strcmp (override, "never") == 0) - { - vfunc->must_be_implemented = FALSE; - vfunc->must_not_be_implemented = TRUE; - } - else - { - vfunc->must_be_implemented = FALSE; - vfunc->must_not_be_implemented = FALSE; - } - - if (is_class_closure && strcmp (is_class_closure, "1") == 0) - vfunc->is_class_closure = TRUE; - else - vfunc->is_class_closure = FALSE; - - if (offset) - vfunc->offset = atoi (offset); - else - vfunc->offset = 0; - - vfunc->invoker = g_strdup (invoker); - - iface = (GIrNodeInterface *)CURRENT_NODE (ctx); - iface->members = g_list_append (iface->members, vfunc); - - push_node (ctx, (GIrNode *)vfunc); - state_switch (ctx, STATE_FUNCTION); - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; -} + vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC); + + ((GIrNode *)vfunc)->name = g_strdup (name); + + if (must_chain_up && strcmp (must_chain_up, "1") == 0) + vfunc->must_chain_up = TRUE; + else + vfunc->must_chain_up = FALSE; + + if (override && strcmp (override, "always") == 0) + { + vfunc->must_be_implemented = TRUE; + vfunc->must_not_be_implemented = FALSE; + } + else if (override && strcmp (override, "never") == 0) + { + vfunc->must_be_implemented = FALSE; + vfunc->must_not_be_implemented = TRUE; + } + else + { + vfunc->must_be_implemented = FALSE; + vfunc->must_not_be_implemented = FALSE; + } + + if (is_class_closure && strcmp (is_class_closure, "1") == 0) + vfunc->is_class_closure = TRUE; + else + vfunc->is_class_closure = FALSE; + + if (offset) + vfunc->offset = atoi (offset); + else + vfunc->offset = 0; + + vfunc->invoker = g_strdup (invoker); + + iface = (GIrNodeInterface *)CURRENT_NODE (ctx); + iface->members = g_list_append (iface->members, vfunc); + + push_node (ctx, (GIrNode *)vfunc); + + return TRUE; +} static gboolean start_struct (GMarkupParseContext *context, @@ -2262,74 +2280,73 @@ start_struct (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "record") == 0 && - (ctx->state == STATE_NAMESPACE || - ctx->state == STATE_UNION || - ctx->state == STATE_STRUCT || - ctx->state == STATE_CLASS)) + const gchar *name; + const gchar *deprecated; + const gchar *disguised; + const gchar *gtype_name; + const gchar *gtype_init; + const gchar *gtype_struct; + const gchar *foreign; + GIrNodeStruct *struct_; + + if (!(strcmp (element_name, "record") == 0 && + (ctx->state == STATE_NAMESPACE || + ctx->state == STATE_UNION || + ctx->state == STATE_STRUCT || + ctx->state == STATE_CLASS))) + return FALSE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_STRUCT)) + return TRUE; + + name = find_attribute ("name", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + disguised = find_attribute ("disguised", attribute_names, attribute_values); + gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values); + gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values); + gtype_struct = find_attribute ("glib:is-gtype-struct-for", attribute_names, attribute_values); + foreign = find_attribute ("foreign", attribute_names, attribute_values); + + if (name == NULL && ctx->node_stack == NULL) { - const gchar *name; - const gchar *deprecated; - const gchar *disguised; - const gchar *gtype_name; - const gchar *gtype_init; - const gchar *gtype_struct; - const gchar *foreign; - GIrNodeStruct *struct_; - - name = find_attribute ("name", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - disguised = find_attribute ("disguised", attribute_names, attribute_values); - gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values); - gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values); - gtype_struct = find_attribute ("glib:is-gtype-struct-for", attribute_names, attribute_values); - foreign = find_attribute ("foreign", attribute_names, attribute_values); - - if (name == NULL && ctx->node_stack == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "name"); - return FALSE; - } - if ((gtype_name == NULL && gtype_init != NULL)) - { - MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); - return FALSE; - } - if ((gtype_name != NULL && gtype_init == NULL)) - { - MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); - return FALSE; - } - - struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT); - - ((GIrNode *)struct_)->name = g_strdup (name ? name : ""); - if (deprecated) - struct_->deprecated = TRUE; - else - struct_->deprecated = FALSE; - - if (disguised && strcmp (disguised, "1") == 0) - struct_->disguised = TRUE; - - struct_->is_gtype_struct = gtype_struct != NULL; - - struct_->gtype_name = g_strdup (gtype_name); - struct_->gtype_init = g_strdup (gtype_init); - - struct_->foreign = (g_strcmp0 (foreign, "1") == 0); - - if (ctx->node_stack == NULL) - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, struct_); - push_node (ctx, (GIrNode *)struct_); - - state_switch (ctx, STATE_STRUCT); - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; + } + if ((gtype_name == NULL && gtype_init != NULL)) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:type-name"); + return FALSE; + } + if ((gtype_name != NULL && gtype_init == NULL)) + { + MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type"); + return FALSE; } - return FALSE; -} + struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT); + + ((GIrNode *)struct_)->name = g_strdup (name ? name : ""); + if (deprecated) + struct_->deprecated = TRUE; + else + struct_->deprecated = FALSE; + + if (disguised && strcmp (disguised, "1") == 0) + struct_->disguised = TRUE; + + struct_->is_gtype_struct = gtype_struct != NULL; + + struct_->gtype_name = g_strdup (gtype_name); + struct_->gtype_init = g_strdup (gtype_init); + + struct_->foreign = (g_strcmp0 (foreign, "1") == 0); + + if (ctx->node_stack == NULL) + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, struct_); + push_node (ctx, (GIrNode *)struct_); + return TRUE; +} static gboolean start_union (GMarkupParseContext *context, @@ -2339,48 +2356,48 @@ start_union (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "union") == 0 && - (ctx->state == STATE_NAMESPACE || - ctx->state == STATE_UNION || - ctx->state == STATE_STRUCT || - ctx->state == STATE_CLASS)) + const gchar *name; + const gchar *deprecated; + const gchar *typename; + const gchar *typeinit; + GIrNodeUnion *union_; + + if (!(strcmp (element_name, "union") == 0 && + (ctx->state == STATE_NAMESPACE || + ctx->state == STATE_UNION || + ctx->state == STATE_STRUCT || + ctx->state == STATE_CLASS))) + return FALSE; + + if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_UNION)) + return TRUE; + + name = find_attribute ("name", attribute_names, attribute_values); + deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + typename = find_attribute ("glib:type-name", attribute_names, attribute_values); + typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + + if (name == NULL && ctx->node_stack == NULL) { - const gchar *name; - const gchar *deprecated; - const gchar *typename; - const gchar *typeinit; - - name = find_attribute ("name", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - typename = find_attribute ("glib:type-name", attribute_names, attribute_values); - typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); - - if (name == NULL && ctx->node_stack == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); - else - { - GIrNodeUnion *union_; - - union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION); - - ((GIrNode *)union_)->name = g_strdup (name ? name : ""); - union_->gtype_name = g_strdup (typename); - union_->gtype_init = g_strdup (typeinit); - if (deprecated) - union_->deprecated = TRUE; - else - union_->deprecated = FALSE; - - if (ctx->node_stack == NULL) - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, union_); - push_node (ctx, (GIrNode *)union_); - - state_switch (ctx, STATE_UNION); - } - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; } - return FALSE; + + union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION); + + ((GIrNode *)union_)->name = g_strdup (name ? name : ""); + union_->gtype_name = g_strdup (typename); + union_->gtype_init = g_strdup (typeinit); + if (deprecated) + union_->deprecated = TRUE; + else + union_->deprecated = FALSE; + + if (ctx->node_stack == NULL) + ctx->current_module->entries = + g_list_append (ctx->current_module->entries, union_); + push_node (ctx, (GIrNode *)union_); + return TRUE; } static gboolean @@ -2391,42 +2408,43 @@ start_discriminator (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "discriminator") == 0 && - ctx->state == STATE_UNION) + const gchar *type; + const gchar *offset; + if (!(strcmp (element_name, "discriminator") == 0 && + ctx->state == STATE_UNION)) + return FALSE; + + type = find_attribute ("type", attribute_names, attribute_values); + offset = find_attribute ("offset", attribute_names, attribute_values); + if (type == NULL) { - const gchar *type; - const gchar *offset; - - type = find_attribute ("type", attribute_names, attribute_values); - offset = find_attribute ("offset", attribute_names, attribute_values); - if (type == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "type"); - else if (offset == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "offset"); - { - ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type - = parse_type (ctx, type); - ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset - = atoi (offset); - } - - return TRUE; + MISSING_ATTRIBUTE (context, error, element_name, "type"); + return FALSE; + } + else if (offset == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "offset"); + return FALSE; } - return FALSE; + ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type + = parse_type (ctx, type); + ((GIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset + = atoi (offset); + + return TRUE; } static gboolean parse_include (GMarkupParseContext *context, ParseContext *ctx, const char *name, - const char *version, - GError **error) + const char *version) { + GError *error = NULL; gchar *buffer; gsize length; gchar *girpath, *girname; - gboolean success = FALSE; GList *modules; GList *l; @@ -2444,11 +2462,8 @@ parse_include (GMarkupParseContext *context, } else { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Module '%s' imported with conflicting versions '%s' and '%s'", - name, m->version, version); + g_printerr ("Module '%s' imported with conflicting versions '%s' and '%s'\n", + name, m->version, version); return FALSE; } } @@ -2459,10 +2474,7 @@ parse_include (GMarkupParseContext *context, if (girpath == NULL) { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Could not find GIR file '%s'; check XDG_DATA_DIRS or use --includedir", + g_printerr ("Could not find GIR file '%s'; check XDG_DATA_DIRS or use --includedir\n", girname); g_free (girname); return FALSE; @@ -2471,22 +2483,31 @@ parse_include (GMarkupParseContext *context, g_debug ("Parsing include %s", girpath); - if (!g_file_get_contents (girpath, &buffer, &length, error)) + if (!g_file_get_contents (girpath, &buffer, &length, &error)) { + g_printerr ("%s: %s\n", girpath, error->message); + g_clear_error (&error); + g_free (girpath); + return FALSE; + } + + modules = g_ir_parser_parse_string (ctx->parser, name, girpath, buffer, length, &error); + g_free (buffer); + if (error != NULL) + { + int line_number, char_number; + g_markup_parse_context_get_position (context, &line_number, &char_number); + g_printerr ("%s:%d:%d: error: %s\n", girpath, line_number, char_number, error->message); + g_clear_error (&error); g_free (girpath); return FALSE; } g_free (girpath); - modules = g_ir_parser_parse_string (ctx->parser, name, buffer, length, error); - success = error != NULL; - ctx->include_modules = g_list_concat (ctx->include_modules, modules); - g_free (buffer); - - return success; + return TRUE; } extern GLogLevelFlags logged_levels; @@ -2520,6 +2541,12 @@ start_element_handler (GMarkupParseContext *context, g_string_free (tags, TRUE); } + if (ctx->state == STATE_PASSTHROUGH) + { + ctx->unknown_depth += 1; + return; + } + switch (element_name[0]) { case 'a': @@ -2619,8 +2646,16 @@ start_element_handler (GMarkupParseContext *context, break; } - if (!parse_include (context, ctx, name, version, error)) - break; + if (!parse_include (context, ctx, name, version)) + { + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Failed to parse included gir %s-%s", + name, + version); + return; + } ctx->dependencies = g_list_prepend (ctx->dependencies, g_strdup_printf ("%s-%s", name, version)); @@ -2806,22 +2841,22 @@ start_element_handler (GMarkupParseContext *context, break; } - if (ctx->state != STATE_UNKNOWN) + if (ctx->state != STATE_PASSTHROUGH) { - state_switch (ctx, STATE_UNKNOWN); + g_markup_parse_context_get_position (context, &line_number, &char_number); + if (!g_str_has_prefix (element_name, "c:")) + g_printerr ("%s:%d:%d: warning: dropping to PASSTHROUGH\n", + ctx->file_path, line_number, char_number); + state_switch (ctx, STATE_PASSTHROUGH); ctx->unknown_depth = 1; } - else - { - ctx->unknown_depth += 1; - } out: if (*error) { g_markup_parse_context_get_position (context, &line_number, &char_number); - fprintf (stderr, "Error at line %d, character %d: %s\n", line_number, char_number, (*error)->message); + g_printerr ("%s:%d:%d: error: %s\n", ctx->file_path, line_number, char_number, (*error)->message); backtrace_stderr (); } } @@ -3194,7 +3229,7 @@ end_element_handler (GMarkupParseContext *context, } break; - case STATE_UNKNOWN: + case STATE_PASSTHROUGH: ctx->unknown_depth -= 1; if (ctx->unknown_depth == 0) state_switch (ctx, ctx->prev_state); @@ -3230,149 +3265,11 @@ cleanup (GMarkupParseContext *context, ctx->current_module = NULL; } -static GList * -post_filter_toplevel_varargs_functions (GList *list, - GList **varargs_callbacks_out) -{ - GList *iter; - GList *varargs_callbacks = *varargs_callbacks_out; - - iter = list; - while (iter) - { - GList *link = iter; - GIrNode *node = iter->data; - - iter = iter->next; - - if (node->type == G_IR_NODE_FUNCTION) - { - if (((GIrNodeFunction*)node)->is_varargs) - { - list = g_list_delete_link (list, link); - } - } - if (node->type == G_IR_NODE_CALLBACK) - { - if (((GIrNodeFunction*)node)->is_varargs) - { - varargs_callbacks = g_list_append (varargs_callbacks, - node); - list = g_list_delete_link (list, link); - } - } - } - - *varargs_callbacks_out = varargs_callbacks; - - return list; -} - -static GList * -post_filter_varargs_functions (GList *list, GList ** varargs_callbacks_out) -{ - GList *iter; - GList *varargs_callbacks; - - list = post_filter_toplevel_varargs_functions (list, varargs_callbacks_out); - - varargs_callbacks = *varargs_callbacks_out; - - iter = list; - while (iter) - { - GList *link = iter; - GIrNode *node = iter->data; - - iter = iter->next; - - if (node->type == G_IR_NODE_FUNCTION) - { - GList *param; - gboolean function_done = FALSE; - - for (param = ((GIrNodeFunction *)node)->parameters; - param; - param = param->next) - { - GIrNodeParam *node = (GIrNodeParam *)param->data; - - if (function_done) - break; - - if (node->type->is_interface) - { - GList *callback; - for (callback = varargs_callbacks; - callback; - callback = callback->next) - { - if (!strcmp (node->type->interface, - ((GIrNode *)varargs_callbacks->data)->name)) - { - list = g_list_delete_link (list, link); - function_done = TRUE; - break; - } - } - } - } - } - } - - *varargs_callbacks_out = varargs_callbacks; - - return list; -} - -static void -post_filter (GIrModule *module) -{ - GList *iter; - GList *varargs_callbacks = NULL; - - module->entries = post_filter_varargs_functions (module->entries, - &varargs_callbacks); - iter = module->entries; - while (iter) - { - GIrNode *node = iter->data; - - iter = iter->next; - - if (node->type == G_IR_NODE_OBJECT || - node->type == G_IR_NODE_INTERFACE) - { - GIrNodeInterface *iface = (GIrNodeInterface*)node; - iface->members = post_filter_varargs_functions (iface->members, - &varargs_callbacks); - } - else if (node->type == G_IR_NODE_BOXED) - { - GIrNodeBoxed *boxed = (GIrNodeBoxed*)node; - boxed->members = post_filter_varargs_functions (boxed->members, - &varargs_callbacks); - } - else if (node->type == G_IR_NODE_STRUCT) - { - GIrNodeStruct *iface = (GIrNodeStruct*)node; - iface->members = post_filter_varargs_functions (iface->members, - &varargs_callbacks); - } - else if (node->type == G_IR_NODE_UNION) - { - GIrNodeUnion *iface = (GIrNodeUnion*)node; - iface->members = post_filter_varargs_functions (iface->members, - &varargs_callbacks); - } - } - g_list_free (varargs_callbacks); -} - /** * g_ir_parser_parse_string: * @parser: a #GIrParser * @namespace: the namespace of the string + * @filename: (allow-none): Path to parsed file, or %NULL * @buffer: the data containing the XML * @length: length of the data * @error: return location for a #GError, or %NULL @@ -3386,6 +3283,7 @@ post_filter (GIrModule *module) GList * g_ir_parser_parse_string (GIrParser *parser, const gchar *namespace, + const gchar *filename, const gchar *buffer, gssize length, GError **error) @@ -3395,6 +3293,7 @@ g_ir_parser_parse_string (GIrParser *parser, ctx.parser = parser; ctx.state = STATE_START; + ctx.file_path = filename; ctx.namespace = namespace; ctx.include_modules = NULL; ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); @@ -3462,7 +3361,6 @@ g_ir_parser_parse_file (GIrParser *parser, gchar *buffer; gsize length; GList *modules; - GList *iter; const char *slash; char *dash; char *namespace; @@ -3493,12 +3391,7 @@ g_ir_parser_parse_file (GIrParser *parser, if (!g_file_get_contents (filename, &buffer, &length, error)) return NULL; - modules = g_ir_parser_parse_string (parser, namespace, buffer, length, error); - - for (iter = modules; iter; iter = iter->next) - { - post_filter ((GIrModule*)iter->data); - } + modules = g_ir_parser_parse_string (parser, namespace, filename, buffer, length, error); g_free (namespace); diff --git a/girparser.h b/girparser.h index ac0d216b2..6fca1b3da 100644 --- a/girparser.h +++ b/girparser.h @@ -34,6 +34,7 @@ void g_ir_parser_set_includes (GIrParser *parser, GList *g_ir_parser_parse_string (GIrParser *parser, const gchar *namespace, + const gchar *filename, const gchar *buffer, gssize length, GError **error); From 9a9825b0f93a7a21214c861773a599c6ed4813fd Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 22 Jun 2010 10:17:02 -0300 Subject: [PATCH 350/692] [giregisteredinfo] A Boxed is also a registered type --- giregisteredtypeinfo.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/giregisteredtypeinfo.h b/giregisteredtypeinfo.h index a7d19f5db..f3c20fdde 100644 --- a/giregisteredtypeinfo.h +++ b/giregisteredtypeinfo.h @@ -32,7 +32,8 @@ G_BEGIN_DECLS #define GI_IS_REGISTERED_TYPE_INFO(info) \ - ((g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ENUM) || \ + ((g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_BOXED) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ENUM) || \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FLAGS) || \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_INTERFACE) || \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_OBJECT) || \ From e169006ed663eaee25f86ee4c0ce5f2cf3d85650 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 22 Jun 2010 18:03:36 -0400 Subject: [PATCH 351/692] [girparser] Remove backtrace() It's not useful; we never got good info from it, and modern operating systems ship with crash catching systems. --- girparser.c | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/girparser.c b/girparser.c index 1badfd7e8..2713bb463 100644 --- a/girparser.c +++ b/girparser.c @@ -35,10 +35,6 @@ */ #define SUPPORTED_GIR_VERSION "1.1" -#if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS) -# include -#endif - struct _GIrParser { gchar **includes; @@ -282,29 +278,6 @@ locate_gir (GIrParser *parser, line_number, char_number, attribute, element); \ } while (0) -static void -backtrace_stderr (void) -{ -#if defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS) - void *array[50]; - int size, i; - char **strings; - - size = backtrace (array, 50); - strings = (char**) backtrace_symbols (array, size); - - fprintf (stderr, "--- BACKTRACE (%d frames) ---\n", size); - - for (i = 0; i < size; i++) - fprintf (stderr, "%s\n", strings[i]); - - fprintf (stderr, "--- END BACKTRACE ---\n"); - - free (strings); -#endif -} - - static const gchar * find_attribute (const gchar *name, const gchar **attribute_names, @@ -2857,7 +2830,6 @@ start_element_handler (GMarkupParseContext *context, g_markup_parse_context_get_position (context, &line_number, &char_number); g_printerr ("%s:%d:%d: error: %s\n", ctx->file_path, line_number, char_number, (*error)->message); - backtrace_stderr (); } } @@ -2896,7 +2868,6 @@ require_one_of_end_elements (GMarkupParseContext *context, "Unexpected end tag '%s' on line %d char %d; current state=%d", actual_name, line_number, char_number, ctx->state); - backtrace_stderr(); return FALSE; } From c57c9efe6f76ef7974695d75ecbc5a025ef322b2 Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Tue, 15 Jun 2010 10:50:42 -0400 Subject: [PATCH 352/692] Attribute bug-fixes Rectify an assumption that nodes are ordered according to offset - since this assumption was not true, attributes ended up being not ordered either and the bsearch() when looking up attributes failed mysteriously. Instead of making such assumptions, simply sort the list of nodes we want to extract attributes from. The total attribute size computation was wrong as we didn't properly descend into subnodes. This resulted in memory access violations when writing the typelib (because not enough data was allocated). Instead of having a separate function for this, just include the attribute size in the existing function. See https://bugzilla.gnome.org/show_bug.cgi?id=571548 Signed-off-by: David Zeuthen --- girmodule.c | 31 ++++++++++++++++++++----------- girnode.c | 14 ++++---------- girnode.h | 3 +-- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/girmodule.c b/girmodule.c index b380912b5..ae40d5f5b 100644 --- a/girmodule.c +++ b/girmodule.c @@ -192,6 +192,16 @@ write_attributes (GIrModule *module, return wdata.count; } +static gint +node_cmp_offset_func (gconstpointer a, + gconstpointer b) +{ + const GIrNode *na = a; + const GIrNode *nb = b; + return na->offset - nb->offset; +} + + GTypelib * g_ir_module_build_typelib (GIrModule *module, GList *modules) @@ -209,7 +219,7 @@ g_ir_module_build_typelib (GIrModule *module, guint32 size, offset, offset2, old_offset; GHashTable *strings; GHashTable *types; - GList *offset_ordered_nodes; + GList *nodes_with_attributes; char *dependencies; guchar *data; @@ -242,7 +252,7 @@ g_ir_module_build_typelib (GIrModule *module, _g_irnode_init_stats (); strings = g_hash_table_new (g_str_hash, g_str_equal); types = g_hash_table_new (g_str_hash, g_str_equal); - offset_ordered_nodes = NULL; + nodes_with_attributes = NULL; n_entries = g_list_length (module->entries); g_message ("%d entries (%d local), %d dependencies\n", n_entries, n_local_entries, @@ -258,7 +268,6 @@ g_ir_module_build_typelib (GIrModule *module, GIrNode *node = e->data; size += g_ir_node_get_full_size (node); - size += g_ir_node_get_attribute_size (node); /* Also reset the offset here */ node->offset = 0; @@ -350,10 +359,10 @@ g_ir_module_build_typelib (GIrModule *module, g_hash_table_destroy (types); /* Reset the cached offsets */ - for (link = offset_ordered_nodes; link; link = link->next) + for (link = nodes_with_attributes; link; link = link->next) ((GIrNode *) link->data)->offset = 0; - g_list_free (offset_ordered_nodes); + g_list_free (nodes_with_attributes); strings = NULL; g_free (data); @@ -387,12 +396,12 @@ g_ir_module_build_typelib (GIrModule *module, build.modules = modules; build.strings = strings; build.types = types; - build.offset_ordered_nodes = offset_ordered_nodes; + build.nodes_with_attributes = nodes_with_attributes; build.n_attributes = header->n_attributes; build.data = data; g_ir_node_build_typelib (node, NULL, &build, &offset, &offset2); - offset_ordered_nodes = build.offset_ordered_nodes; + nodes_with_attributes = build.nodes_with_attributes; header->n_attributes = build.n_attributes; if (offset2 > old_offset + g_ir_node_get_full_size (node)) @@ -402,7 +411,8 @@ g_ir_module_build_typelib (GIrModule *module, entry++; } - offset_ordered_nodes = g_list_reverse (offset_ordered_nodes); + /* GIBaseInfo expects the AttributeBlob array to be sorted on the field (offset) */ + nodes_with_attributes = g_list_sort (nodes_with_attributes, node_cmp_offset_func); g_message ("header: %d entries, %d attributes", header->n_entries, header->n_attributes); @@ -413,10 +423,9 @@ g_ir_module_build_typelib (GIrModule *module, header->attributes = offset; offset2 = offset + header->n_attributes * header->attribute_blob_size; - for (e = offset_ordered_nodes; e; e = e->next) + for (e = nodes_with_attributes; e; e = e->next) { GIrNode *node = e->data; - write_attributes (module, node, strings, data, &offset, &offset2); } @@ -429,7 +438,7 @@ g_ir_module_build_typelib (GIrModule *module, g_hash_table_destroy (strings); g_hash_table_destroy (types); - g_list_free (offset_ordered_nodes); + g_list_free (nodes_with_attributes); return typelib; } diff --git a/girnode.c b/girnode.c index 0f5223fa0..fbdcdf965 100644 --- a/girnode.c +++ b/girnode.c @@ -573,7 +573,7 @@ add_attribute_size (gpointer key, gpointer value, gpointer data) *size_p += ALIGN_VALUE (strlen (value_str) + 1, 4); } -/* returns the full size of the blob including variable-size parts */ +/* returns the full size of the blob including variable-size parts (including attributes) */ static guint32 g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node) @@ -878,6 +878,8 @@ g_ir_node_get_full_size_internal (GIrNode *parent, node->name ? "' " : "", node, g_ir_node_type_to_string (node->type), size); + g_hash_table_foreach (node->attributes, add_attribute_size, &size); + return size; } @@ -887,14 +889,6 @@ g_ir_node_get_full_size (GIrNode *node) return g_ir_node_get_full_size_internal (NULL, node); } -guint32 -g_ir_node_get_attribute_size (GIrNode *node) -{ - guint32 size = 0; - g_hash_table_foreach (node->attributes, add_attribute_size, &size); - return size; -} - int g_ir_node_cmp (GIrNode *node, GIrNode *other) @@ -1438,7 +1432,7 @@ g_ir_node_build_typelib (GIrNode *node, */ g_assert (node->offset == 0); node->offset = *offset; - build->offset_ordered_nodes = g_list_prepend (build->offset_ordered_nodes, node); + build->nodes_with_attributes = g_list_prepend (build->nodes_with_attributes, node); build->n_attributes += g_hash_table_size (node->attributes); diff --git a/girnode.h b/girnode.h index 038a53d78..bd9acd068 100644 --- a/girnode.h +++ b/girnode.h @@ -51,7 +51,7 @@ struct _GIrTypelibBuild { GList *modules; GHashTable *strings; GHashTable *types; - GList *offset_ordered_nodes; + GList *nodes_with_attributes; guint32 n_attributes; guchar *data; }; @@ -362,7 +362,6 @@ GIrNode * g_ir_node_new (GIrNodeTypeId type); void g_ir_node_free (GIrNode *node); guint32 g_ir_node_get_size (GIrNode *node); guint32 g_ir_node_get_full_size (GIrNode *node); -guint32 g_ir_node_get_attribute_size (GIrNode *node); void g_ir_node_build_typelib (GIrNode *node, GIrNode *parent, GIrTypelibBuild *build, From 3d0dc7d21487dbf8e29a4084072cfee6be6ba393 Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Tue, 15 Jun 2010 11:01:37 -0400 Subject: [PATCH 353/692] Allow attributes on parameters and return values Any annotation where the key has a dot in the name will go into the attribute list. For example * @arg: (foo.bar baz): some arg the parameter @arg will get the attribute with key foo.bar and value baz. This also works for. * Returns: (foo.bar2 baz2): the return value Also add tests for this new feature. See https://bugzilla.gnome.org/show_bug.cgi?id=571548 Signed-off-by: David Zeuthen --- gibaseinfo.c | 24 ++++++++++---- gicallableinfo.c | 76 ++++++++++++++++++++++++++++++++++++++++++++ gicallableinfo.h | 6 ++++ girnode.c | 16 ++++++++++ girparser.c | 9 +++++- girwriter.c | 21 +++++++++++- gitypelib-internal.h | 4 +++ 7 files changed, 148 insertions(+), 8 deletions(-) diff --git a/gibaseinfo.c b/gibaseinfo.c index c8444a5ea..81b936d85 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -475,7 +475,7 @@ g_base_info_get_attribute (GIBaseInfo *info, static int cmp_attribute (const void *av, - const void *bv) + const void *bv) { const AttributeBlob *a = av; const AttributeBlob *b = bv; @@ -488,13 +488,25 @@ cmp_attribute (const void *av, return 1; } -static AttributeBlob * -find_first_attribute (GIRealInfo *rinfo) +/* + * _attribute_blob_find_first: + * @GIBaseInfo: A #GIBaseInfo. + * @blob_offset: The offset for the blob to find the first attribute for. + * + * Searches for the first #AttributeBlob for @blob_offset and returns + * it if found. + * + * Returns: A pointer to #AttributeBlob or %NULL if not found. + */ +AttributeBlob * +_attribute_blob_find_first (GIBaseInfo *info, + guint32 blob_offset) { + GIRealInfo *rinfo = (GIRealInfo *) info; Header *header = (Header *)rinfo->typelib->data; AttributeBlob blob, *first, *res, *previous; - blob.offset = rinfo->offset; + blob.offset = blob_offset; first = (AttributeBlob *) &rinfo->typelib->data[header->attributes]; @@ -505,7 +517,7 @@ find_first_attribute (GIRealInfo *rinfo) return NULL; previous = res - 1; - while (previous >= first && previous->offset == rinfo->offset) + while (previous >= first && previous->offset == blob_offset) { res = previous; previous = res - 1; @@ -563,7 +575,7 @@ g_base_info_iterate_attributes (GIBaseInfo *info, if (iterator->data != NULL) next = (AttributeBlob *) iterator->data; else - next = find_first_attribute (rinfo); + next = _attribute_blob_find_first (info, rinfo->offset); if (next == NULL || next->offset != rinfo->offset || next >= after) return FALSE; diff --git a/gicallableinfo.c b/gicallableinfo.c index 6097cb483..6b79e62cc 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -19,6 +19,8 @@ * Boston, MA 02111-1307, USA. */ +#include + #include #include @@ -259,3 +261,77 @@ g_callable_info_load_arg (GICallableInfo *info, _g_info_init ((GIRealInfo*)arg, GI_INFO_TYPE_ARG, rinfo->repository, (GIBaseInfo*)info, rinfo->typelib, offset + header->signature_blob_size + n * header->arg_blob_size); } + +/** + * g_callable_info_get_return_attribute: + * @info: a #GICallableInfo + * @name: a freeform string naming an attribute + * + * Retrieve an arbitrary attribute associated with the return value. + * + * Returns: The value of the attribute, or %NULL if no such attribute exists + */ +const gchar * +g_callable_info_get_return_attribute (GICallableInfo *info, + const gchar *name) +{ + GIAttributeIter iter = { 0, }; + gchar *curname, *curvalue; + while (g_callable_info_iterate_return_attributes (info, &iter, &curname, &curvalue)) + { + if (g_strcmp0 (name, curname) == 0) + return (const gchar*) curvalue; + } + + return NULL; +} + +/** + * g_callable_info_iterate_return_attributes: + * @info: a #GICallableInfo + * @iterator: a #GIAttributeIter structure, must be initialized; see below + * @name: (out) (transfer none): Returned name, must not be freed + * @value: (out) (transfer none): Returned name, must not be freed + * + * Iterate over all attributes associated with the return value. The + * iterator structure is typically stack allocated, and must have its + * first member initialized to %NULL. + * + * Both the @name and @value should be treated as constants + * and must not be freed. + * + * See g_base_info_iterate_attributes() for an example of how to use a + * similar API. + * + * Returns: %TRUE if there are more attributes + */ +gboolean +g_callable_info_iterate_return_attributes (GICallableInfo *info, + GIAttributeIter *iterator, + char **name, + char **value) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + AttributeBlob *next, *after; + guint32 blob_offset; + + after = (AttributeBlob *) &rinfo->typelib->data[header->attributes + + header->n_attributes * header->attribute_blob_size]; + + blob_offset = signature_offset (info); + + if (iterator->data != NULL) + next = (AttributeBlob *) iterator->data; + else + next = _attribute_blob_find_first (info, blob_offset); + + if (next == NULL || next->offset != blob_offset || next >= after) + return FALSE; + + *name = (gchar*) g_typelib_get_string (rinfo->typelib, next->name); + *value = (gchar*) g_typelib_get_string (rinfo->typelib, next->value); + iterator->data = next + 1; + + return TRUE; +} diff --git a/gicallableinfo.h b/gicallableinfo.h index 479baa2ae..54d2cacb7 100644 --- a/gicallableinfo.h +++ b/gicallableinfo.h @@ -39,6 +39,12 @@ G_BEGIN_DECLS GITypeInfo * g_callable_info_get_return_type (GICallableInfo *info); void g_callable_info_load_return_type (GICallableInfo *info, GITypeInfo *type); +const gchar * g_callable_info_get_return_attribute (GICallableInfo *info, + const gchar *name); +gboolean g_callable_info_iterate_return_attributes (GICallableInfo *info, + GIAttributeIter *iterator, + char **name, + char **value); GITransfer g_callable_info_get_caller_owns (GICallableInfo *info); gboolean g_callable_info_may_return_null (GICallableInfo *info); gint g_callable_info_get_n_args (GICallableInfo *info); diff --git a/girnode.c b/girnode.c index fbdcdf965..576ac1006 100644 --- a/girnode.c +++ b/girnode.c @@ -1678,6 +1678,14 @@ g_ir_node_build_typelib (GIrNode *node, blob->symbol = write_string (function->symbol, strings, data, offset2); blob->signature = signature; + /* function->result is special since it doesn't appear in the serialized format but + * we do want the attributes for it to appear + */ + build->nodes_with_attributes = g_list_prepend (build->nodes_with_attributes, function->result); + build->n_attributes += g_hash_table_size (((GIrNode *) function->result)->attributes); + g_assert (((GIrNode *) function->result)->offset == 0); + ((GIrNode *) function->result)->offset = signature; + g_debug ("building function '%s'", function->symbol); g_ir_node_build_typelib ((GIrNode *)function->result->type, @@ -1770,6 +1778,14 @@ g_ir_node_build_typelib (GIrNode *node, blob->name = write_string (node->name, strings, data, offset2); blob->signature = signature; + /* signal->result is special since it doesn't appear in the serialized format but + * we do want the attributes for it to appear + */ + build->nodes_with_attributes = g_list_prepend (build->nodes_with_attributes, signal->result); + build->n_attributes += g_hash_table_size (((GIrNode *) signal->result)->attributes); + g_assert (((GIrNode *) signal->result)->offset == 0); + ((GIrNode *) signal->result)->offset = signature; + g_ir_node_build_typelib ((GIrNode *)signal->result->type, node, build, &signature, offset2); diff --git a/girparser.c b/girparser.c index 2713bb463..5efe7fded 100644 --- a/girparser.c +++ b/girparser.c @@ -1990,7 +1990,14 @@ start_attribute (GMarkupParseContext *context, curnode = CURRENT_NODE (ctx); - g_hash_table_insert (curnode->attributes, g_strdup (name), g_strdup (value)); + if (ctx->current_typed && ctx->current_typed->type == G_IR_NODE_PARAM) + { + g_hash_table_insert (ctx->current_typed->attributes, g_strdup (name), g_strdup (value)); + } + else + { + g_hash_table_insert (curnode->attributes, g_strdup (name), g_strdup (value)); + } return TRUE; } diff --git a/girwriter.c b/girwriter.c index b123a1345..19862b0da 100644 --- a/girwriter.c +++ b/girwriter.c @@ -358,7 +358,7 @@ write_type_info (const gchar *namespace, static void write_attributes (Xml *file, - GIBaseInfo *info) + GIBaseInfo *info) { GIAttributeIter iter = { 0, }; char *name, *value; @@ -371,6 +371,21 @@ write_attributes (Xml *file, } } +static void +write_return_value_attributes (Xml *file, + GICallableInfo *info) +{ + GIAttributeIter iter = { 0, }; + char *name, *value; + + while (g_callable_info_iterate_return_attributes (info, &iter, &name, &value)) + { + xml_start_element (file, "attribute"); + xml_printf (file, " name=\"%s\" value=\"%s\"", name, value); + xml_end_element (file, "attribute"); + } +} + static void write_constant_value (const gchar *namespace, GITypeInfo *info, @@ -467,6 +482,8 @@ write_callable_info (const gchar *namespace, if (g_callable_info_may_return_null (info)) xml_printf (file, " allow-none=\"1\""); + write_return_value_attributes (file, info); + write_type_info (namespace, type, file); xml_end_element (file, "return-value"); @@ -528,6 +545,8 @@ write_callable_info (const gchar *namespace, if (g_arg_info_get_destroy (arg) >= 0) xml_printf (file, " destroy=\"%d\"", g_arg_info_get_destroy (arg)); + write_attributes (file, (GIBaseInfo*) arg); + type = g_arg_info_get_type (arg); write_type_info (namespace, type, file); diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 90113ac2c..d4577acc7 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -1110,6 +1110,10 @@ gboolean g_typelib_validate (GTypelib *typelib, GError **error); +/* defined in gibaseinfo.c */ +AttributeBlob *_attribute_blob_find_first (GIBaseInfo *info, + guint32 blob_offset); + G_END_DECLS #endif /* __G_TYPELIB_H__ */ From 68b4fb43bbe24c479aef52cefb8d94a03085087f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 7 Jul 2010 18:18:37 -0400 Subject: [PATCH 354/692] Move doc to toplevel element, write for unknown containers Moving to allows us to better preserve whitespace. XML has no facility for whitespace-preserving attributes. Second, for arrays and lists, both types with unknown element_type can occur in the current scanner; it's least wrong if we write out an type. --- girparser.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/girparser.c b/girparser.c index 5efe7fded..678edcc35 100644 --- a/girparser.c +++ b/girparser.c @@ -76,6 +76,7 @@ typedef enum STATE_ALIAS, /* 30 */ STATE_TYPE, STATE_ATTRIBUTE, + STATE_DOC, STATE_PASSTHROUGH } ParseState; @@ -1957,6 +1958,22 @@ end_type (ParseContext *ctx) } } +static gboolean +start_doc (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + if (strcmp (element_name, "doc") != 0 || ctx->node_stack == NULL) + return FALSE; + + state_switch (ctx, STATE_DOC); + + return TRUE; +} + static gboolean start_attribute (GMarkupParseContext *context, const gchar *element_name, @@ -2570,6 +2587,9 @@ start_element_handler (GMarkupParseContext *context, attribute_names, attribute_values, ctx, error)) goto out; + else if (start_doc (context, element_name, attribute_names, + attribute_values, ctx, error)) + goto out; break; case 'e': @@ -3207,6 +3227,13 @@ end_element_handler (GMarkupParseContext *context, } break; + case STATE_DOC: + if (strcmp ("doc", element_name) == 0) + { + state_switch (ctx, ctx->prev_state); + } + break; + case STATE_PASSTHROUGH: ctx->unknown_depth -= 1; if (ctx->unknown_depth == 0) From b6d50e29517413f0a0e3e6cc2375973576cf8c87 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 12 Jun 2010 18:08:56 -0300 Subject: [PATCH 355/692] Add support for non-GObject fundamental objects This patch adds support for instantiable fundamental object types, which are not GObject based. This is mostly interesting for being able to support GstMiniObject's which are extensivly used in GStreamer. Includes a big test case to the Everything module (inspired by GstMiniObject) which should be used by language bindings who wishes to test this functionallity. This patch increases the size of the typelib and breaks compatibility with older typelibs. https://bugzilla.gnome.org/show_bug.cgi?id=568913 --- gdump.c | 55 ++++++++- giobjectinfo.c | 249 +++++++++++++++++++++++++++++++++++++++++ giobjectinfo.h | 52 +++++++++ giregisteredtypeinfo.h | 3 +- girnode.c | 21 ++++ girnode.h | 6 + girparser.c | 19 ++++ girwriter.c | 22 ++++ gitypelib-internal.h | 23 +++- gitypelib.c | 2 +- 10 files changed, 445 insertions(+), 7 deletions(-) diff --git a/gdump.c b/gdump.c index 5cb10b045..328f07521 100644 --- a/gdump.c +++ b/gdump.c @@ -270,6 +270,56 @@ dump_enum_type (GType type, const char *symbol, GOutputStream *out) goutput_write (out, " "); } +static void +dump_fundamental_type (GType type, const char *symbol, GOutputStream *out) +{ + guint n_interfaces; + guint i; + GType *interfaces; + GString *parent_str; + GType parent; + gboolean first = TRUE; + + + escaped_printf (out, " len > 0) + escaped_printf (out, " parents=\"%s\"", parent_str->str); + g_string_free (parent_str, TRUE); + + goutput_write (out, ">\n"); + + interfaces = g_type_interfaces (type, &n_interfaces); + for (i = 0; i < n_interfaces; i++) + { + GType itype = interfaces[i]; + escaped_printf (out, " \n", + g_type_name (itype)); + } + goutput_write (out, " \n"); +} + static void dump_type (GType type, const char *symbol, GOutputStream *out) { @@ -294,10 +344,7 @@ dump_type (GType type, const char *symbol, GOutputStream *out) /* GValue, etc. Just skip them. */ break; default: - /* Other fundamental types such as the once GStreamer and Clutter registers - * are not yet interesting from an introspection perspective and should be - * ignored - */ + dump_fundamental_type (type, symbol, out); break; } } diff --git a/giobjectinfo.c b/giobjectinfo.c index ace8d5d4b..bc2ddcd0f 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -96,6 +96,29 @@ g_object_info_get_abstract (GIObjectInfo *info) return blob->abstract != 0; } +/** + * g_object_info_get_fundamental: + * @info: a #GIObjectInfo + * + * Obtain if the object type is of a fundamental type which is not + * G_TYPE_OBJECT. This is mostly for supporting GstMiniObject. + * + * Returns: %TRUE if the object type is a fundamental type + */ +gboolean +g_object_info_get_fundamental (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), FALSE); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->fundamental != 0; +} + /** * g_object_info_get_type_name: * @info: a #GIObjectInfo @@ -636,3 +659,229 @@ g_object_info_get_class_struct (GIObjectInfo *info) return NULL; } +typedef const char* (*SymbolGetter) (GIObjectInfo *info); + +static void * +_get_func(GIObjectInfo *info, + SymbolGetter getter) +{ + const char* symbol; + GSList *parents = NULL, *l; + GIObjectInfo *parent_info; + + parent_info = info; + while (parent_info != NULL) { + parents = g_slist_prepend(parents, parent_info); + parent_info = g_object_info_get_parent(parent_info); + } + + for (l = parents; l; l = l->next) { + GIObjectInfoRefFunction func; + parent_info = l->data; + symbol = getter(parent_info); + if (symbol == NULL) + continue; + if (g_typelib_symbol (((GIRealInfo *)parent_info)->typelib, symbol, (void**) &func)) { + g_slist_free(parents); + return func; + } + } + + g_slist_free(parents); + return NULL; + +} + +/** + * g_object_info_get_ref_function: + * @info: a #GIObjectInfo + * + * Obtain the symbol name of the function that should be called to ref this + * object type. It's mainly used fundamental types. The type signature for + * the symbol is %GIObjectInfoRefFunction, to fetch the function pointer + * see g_object_info_get_ref_function(). + * + * Returns: the symbol or %NULL + */ +const char * +g_object_info_get_ref_function (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->ref_func) + return g_typelib_get_string (rinfo->typelib, blob->ref_func); + + return NULL; +} + +/** + * g_object_info_get_ref_function_pointer: + * @info: a #GIObjectInfo + * + * Obtain a pointer to a function which can be used to + * increase the reference count an instance of this object type. + * This takes derivation into account and will reversely traverse + * the base classes of this type, starting at the top type. + * + * Returns: the function pointer or %NULL + */ +GIObjectInfoRefFunction +g_object_info_get_ref_function_pointer (GIObjectInfo *info) +{ + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + return (GIObjectInfoRefFunction)_get_func(info, (SymbolGetter)g_object_info_get_ref_function); +} + +/** + * g_object_info_get_unref_function: + * @info: a #GIObjectInfo + * + * Obtain the symbol name of the function that should be called to unref this + * object type. It's mainly used fundamental types. The type signature for + * the symbol is %GIObjectInfoUnrefFunction, to fetch the function pointer + * see g_object_info_get_unref_function(). + * + * Returns: the symbol or %NULL + */ +const char * +g_object_info_get_unref_function (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->unref_func) + return g_typelib_get_string (rinfo->typelib, blob->unref_func); + + return NULL; +} + +/** + * g_object_info_get_unref_function_pointer: + * @info: a #GIObjectInfo + * + * Obtain a pointer to a function which can be used to + * decrease the reference count an instance of this object type. + * This takes derivation into account and will reversely traverse + * the base classes of this type, starting at the top type. + * + * Returns: the function pointer or %NULL + */ +GIObjectInfoUnrefFunction +g_object_info_get_unref_function_pointer (GIObjectInfo *info) +{ + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + return (GIObjectInfoUnrefFunction)_get_func(info, (SymbolGetter)g_object_info_get_unref_function); +} + +/** + * g_object_info_get_set_value_function: + * @info: a #GIObjectInfo + * + * Obtain the symbol name of the function that should be called to convert + * set a GValue giving an object instance pointer of this object type. + * I's mainly used fundamental types. The type signature for the symbol + * is %GIObjectInfoSetValueFunction, to fetch the function pointer + * see g_object_info_get_set_value_function(). + * + * Returns: the symbol or %NULL + */ +const char * +g_object_info_get_set_value_function (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->set_value_func) + return g_typelib_get_string (rinfo->typelib, blob->set_value_func); + + return NULL; +} + +/** + * g_object_info_get_set_value_function_pointer: + * @info: a #GIObjectInfo + * + * Obtain a pointer to a function which can be used to + * set a GValue given an instance of this object type. + * This takes derivation into account and will reversely traverse + * the base classes of this type, starting at the top type. + * + * Returns: the function pointer or %NULL + */ +GIObjectInfoSetValueFunction +g_object_info_get_set_value_function_pointer (GIObjectInfo *info) +{ + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + return (GIObjectInfoSetValueFunction)_get_func(info, (SymbolGetter)g_object_info_get_set_value_function); +} + +/** + * g_object_info_get_get_value_function: + * @info: a #GIObjectInfo + * + * Obtain the symbol name of the function that should be called to convert + * an object instance pointer of this object type to a GValue. + * I's mainly used fundamental types. The type signature for the symbol + * is %GIObjectInfoGetValueFunction, to fetch the function pointer + * see g_object_info_get_get_value_function(). + * + * Returns: the symbol or %NULL + */ +const char * +g_object_info_get_get_value_function (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->get_value_func) + return g_typelib_get_string (rinfo->typelib, blob->get_value_func); + + return NULL; +} + +/** + * g_object_info_get_get_value_function_pointer: + * @info: a #GIObjectInfo + * + * Obtain a pointer to a function which can be used to + * extract an instance of this object type out of a GValue. + * This takes derivation into account and will reversely traverse + * the base classes of this type, starting at the top type. + * + * Returns: the function pointer or %NULL + */ +GIObjectInfoGetValueFunction +g_object_info_get_get_value_function_pointer (GIObjectInfo *info) +{ + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); + + return (GIObjectInfoGetValueFunction)_get_func(info, (SymbolGetter)g_object_info_get_get_value_function); +} diff --git a/giobjectinfo.h b/giobjectinfo.h index 27ec71411..630def618 100644 --- a/giobjectinfo.h +++ b/giobjectinfo.h @@ -30,12 +30,52 @@ G_BEGIN_DECLS +/** + * GIObjectInfoRefFunction: + * @object: object instance pointer + * + * Increases the reference count of an object instance. + * + * Returns: the object instance + */ +typedef void * (*GIObjectInfoRefFunction) (void *object); + +/** + * GIObjectInfoUnrefFunction: + * @object: object instance pointer + * + * Decreases the reference count of an object instance. + * + */ +typedef void (*GIObjectInfoUnrefFunction) (void *object); + +/** + * GIObjectInfoSetValueFunction: + * @value: a #GValue + * @object: object instance pointer + * + * Update @value and attach the object instance pointer @object to it. + * + */ +typedef void (*GIObjectInfoSetValueFunction) (GValue *value, void *object); + +/** + * GIObjectInfoGetValueFunction: + * @value: a #GValue + * + * Extract an object instance out of @value + * + * Returns: the object instance + */ +typedef void * (*GIObjectInfoGetValueFunction) (const GValue *value); + #define GI_IS_OBJECT_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_OBJECT) const gchar * g_object_info_get_type_name (GIObjectInfo *info); const gchar * g_object_info_get_type_init (GIObjectInfo *info); gboolean g_object_info_get_abstract (GIObjectInfo *info); +gboolean g_object_info_get_fundamental (GIObjectInfo *info); GIObjectInfo * g_object_info_get_parent (GIObjectInfo *info); gint g_object_info_get_n_interfaces (GIObjectInfo *info); GIInterfaceInfo * g_object_info_get_interface (GIObjectInfo *info, @@ -64,6 +104,18 @@ GIConstantInfo * g_object_info_get_constant (GIObjectInfo *info, gint n); GIStructInfo * g_object_info_get_class_struct (GIObjectInfo *info); +const char * g_object_info_get_ref_function (GIObjectInfo *info); +GIObjectInfoRefFunction g_object_info_get_ref_function_pointer (GIObjectInfo *info); + +const char * g_object_info_get_unref_function (GIObjectInfo *info); +GIObjectInfoUnrefFunction g_object_info_get_unref_function_pointer (GIObjectInfo *info); + +const char * g_object_info_get_set_value_function (GIObjectInfo *info); +GIObjectInfoSetValueFunction g_object_info_get_set_value_function_pointer (GIObjectInfo *info); + +const char * g_object_info_get_get_value_function (GIObjectInfo *info); +GIObjectInfoGetValueFunction g_object_info_get_get_value_function_pointer (GIObjectInfo *info); + G_END_DECLS diff --git a/giregisteredtypeinfo.h b/giregisteredtypeinfo.h index f3c20fdde..76a1ee22d 100644 --- a/giregisteredtypeinfo.h +++ b/giregisteredtypeinfo.h @@ -38,7 +38,8 @@ G_BEGIN_DECLS (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_INTERFACE) || \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_OBJECT) || \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_STRUCT) || \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_UNION)) + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_UNION) || \ + (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_BOXED)) const gchar * g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info); const gchar * g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info); diff --git a/girnode.c b/girnode.c index 576ac1006..af24161d2 100644 --- a/girnode.c +++ b/girnode.c @@ -298,6 +298,10 @@ g_ir_node_free (GIrNode *node) g_free (node->name); g_free (iface->gtype_name); g_free (iface->gtype_init); + g_free (iface->ref_func); + g_free (iface->unref_func); + g_free (iface->set_value_func); + g_free (iface->get_value_func); g_free (iface->glib_type_struct); @@ -692,6 +696,14 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4); if (iface->gtype_init) size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4); + if (iface->ref_func) + size += ALIGN_VALUE (strlen (iface->ref_func) + 1, 4); + if (iface->unref_func) + size += ALIGN_VALUE (strlen (iface->unref_func) + 1, 4); + if (iface->set_value_func) + size += ALIGN_VALUE (strlen (iface->set_value_func) + 1, 4); + if (iface->get_value_func) + size += ALIGN_VALUE (strlen (iface->get_value_func) + 1, 4); size += 2 * (n + (n % 2)); for (l = iface->members; l; l = l->next) @@ -2094,11 +2106,20 @@ g_ir_node_build_typelib (GIrNode *node, blob->blob_type = BLOB_TYPE_OBJECT; blob->abstract = object->abstract; + blob->fundamental = object->fundamental; 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->ref_func) + blob->ref_func = write_string (object->ref_func, strings, data, offset2); + if (object->unref_func) + blob->unref_func = write_string (object->unref_func, strings, data, offset2); + if (object->set_value_func) + blob->set_value_func = write_string (object->set_value_func, strings, data, offset2); + if (object->get_value_func) + blob->get_value_func = write_string (object->get_value_func, strings, data, offset2); if (object->parent) blob->parent = find_entry (module, modules, object->parent); else diff --git a/girnode.h b/girnode.h index bd9acd068..dcd8fa494 100644 --- a/girnode.h +++ b/girnode.h @@ -244,10 +244,16 @@ struct _GIrNodeInterface gboolean abstract; gboolean deprecated; + gboolean fundamental; gchar *gtype_name; gchar *gtype_init; + gchar *ref_func; + gchar *unref_func; + gchar *set_value_func; + gchar *get_value_func; + gchar *parent; gchar *glib_type_struct; diff --git a/girparser.c b/girparser.c index 678edcc35..7796bea28 100644 --- a/girparser.c +++ b/girparser.c @@ -1640,6 +1640,11 @@ start_class (GMarkupParseContext *context, const gchar *typeinit; const gchar *deprecated; const gchar *abstract; + const gchar *fundamental; + const gchar *ref_func; + const gchar *unref_func; + const gchar *set_value_func; + const gchar *get_value_func; GIrNodeInterface *iface; if (!(strcmp (element_name, "class") == 0 && @@ -1656,6 +1661,11 @@ start_class (GMarkupParseContext *context, typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); abstract = find_attribute ("abstract", attribute_names, attribute_values); + fundamental = find_attribute ("glib:fundamental", attribute_names, attribute_values); + ref_func = find_attribute ("glib:ref-func", attribute_names, attribute_values); + unref_func = find_attribute ("glib:unref-func", attribute_names, attribute_values); + set_value_func = find_attribute ("glib:set-value-func", attribute_names, attribute_values); + get_value_func = find_attribute ("glib:get-value-func", attribute_names, attribute_values); if (name == NULL) { @@ -1686,6 +1696,15 @@ start_class (GMarkupParseContext *context, iface->abstract = abstract && strcmp (abstract, "1") == 0; + if (ref_func) + iface->ref_func = g_strdup (ref_func); + if (unref_func) + iface->unref_func = g_strdup (unref_func); + if (set_value_func) + iface->set_value_func = g_strdup (set_value_func); + if (get_value_func) + iface->get_value_func = g_strdup (get_value_func); + push_node (ctx, (GIrNode *) iface); ctx->current_module->entries = g_list_append (ctx->current_module->entries, iface); diff --git a/girwriter.c b/girwriter.c index 19862b0da..56d61b239 100644 --- a/girwriter.c +++ b/girwriter.c @@ -999,8 +999,10 @@ write_object_info (const gchar *namespace, const gchar *name; const gchar *type_name; const gchar *type_init; + const gchar *func; gboolean deprecated; gboolean is_abstract; + gboolean is_fundamental; GIObjectInfo *pnode; GIStructInfo *class_struct; gint i; @@ -1008,6 +1010,7 @@ write_object_info (const gchar *namespace, name = g_base_info_get_name ((GIBaseInfo *)info); deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); is_abstract = g_object_info_get_abstract (info); + is_fundamental = g_object_info_get_fundamental (info); type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); @@ -1033,6 +1036,25 @@ write_object_info (const gchar *namespace, xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init); + if (is_fundamental) + xml_printf (file, " glib:fundamental=\"1\""); + + func = g_object_info_get_unref_function (info); + if (func) + xml_printf (file, " glib:unref-function=\"%s\"", func); + + func = g_object_info_get_ref_function (info); + if (func) + xml_printf (file, " glib:ref-function=\"%s\"", func); + + func = g_object_info_get_set_value_function (info); + if (func) + xml_printf (file, " glib:set-value-function=\"%s\"", func); + + func = g_object_info_get_get_value_function (info); + if (func) + xml_printf (file, " glib:get-value-function=\"%s\"", func); + if (deprecated) xml_printf (file, " deprecated=\"1\""); diff --git a/gitypelib-internal.h b/gitypelib-internal.h index d4577acc7..981f7b480 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -72,6 +72,11 @@ G_BEGIN_DECLS /* TYPELIB HISTORY ----- + +Version 1.1 +- Add ref/unref/set-value/get-value functions to Object, to be able + to support instantiatable fundamental types which are not GObject based. + Version 1.0 - Rename class_struct to gtype_struct, add to interfaces @@ -918,6 +923,8 @@ typedef struct { /** * ObjectBlob: * @blob_type: #BLOB_TYPE_OBJECT + * @fundamental: this object is not a GObject derived type, instead it's + * an additional fundamental type. * @gtype_name: String name of the associated #GType * @gtype_init: String naming the symbol which gets the runtime #GType * @parent: The directory index of the parent type. This is only set for @@ -938,12 +945,21 @@ typedef struct { * @signals: Describes the signals. * @vfuncs: Describes the virtual functions. * @constants: Describes the constants. + * @ref_func: String pointing to a function which can be called to increase + * the reference count for an instance of this object type. + * @unref_func: String pointing to a function which can be called to decrease + * the reference count for an instance of this object type. + * @set_value_func: String pointing to a function which can be called to + * convert a pointer of this object to a GValue + * @get_value_func: String pointing to a function which can be called to + * convert extract a pointer to this object from a GValue */ typedef struct { guint16 blob_type; /* 7 */ guint16 deprecated : 1; guint16 abstract : 1; - guint16 reserved :14; + guint16 fundamental : 1; + guint16 reserved :13; guint32 name; guint32 gtype_name; @@ -961,6 +977,11 @@ typedef struct { guint16 n_constants; guint16 reserved2; + guint32 ref_func; + guint32 unref_func; + guint32 set_value_func; + guint32 get_value_func; + guint32 reserved3; guint32 reserved4; diff --git a/gitypelib.c b/gitypelib.c index 6aa3077c4..74aa7edd8 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -183,7 +183,7 @@ g_typelib_check_sanity (void) CHECK_SIZE (PropertyBlob, 16); CHECK_SIZE (SignalBlob, 16); CHECK_SIZE (VFuncBlob, 20); - CHECK_SIZE (ObjectBlob, 44); + CHECK_SIZE (ObjectBlob, 60); CHECK_SIZE (InterfaceBlob, 40); CHECK_SIZE (ConstantBlob, 24); CHECK_SIZE (AttributeBlob, 12); From 4994c3d4b8274dcbfd7bafaec6a9e4f78f6f2e3a Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Fri, 9 Jul 2010 10:20:57 -0300 Subject: [PATCH 356/692] Remove trailing whitespace --- girparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index 7796bea28..488d77b9f 100644 --- a/girparser.c +++ b/girparser.c @@ -1987,7 +1987,7 @@ start_doc (GMarkupParseContext *context, { if (strcmp (element_name, "doc") != 0 || ctx->node_stack == NULL) return FALSE; - + state_switch (ctx, STATE_DOC); return TRUE; From cf2b0074adec5bcba2d71113e0de4b4cbebdeea0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 8 Jul 2010 14:20:40 -0400 Subject: [PATCH 357/692] Bump shared library version, typelib version https://bugzilla.gnome.org/show_bug.cgi?id=623774 --- Makefile.am | 2 +- girmodule.c | 2 +- gitypelib.c | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index f76e6c3ef..e0f2b1bab 100644 --- a/Makefile.am +++ b/Makefile.am @@ -55,7 +55,7 @@ libgirepository_1_0_la_SOURCES = \ libgirepository_1_0_la_CPPFLAGS = $(GIREPO_CFLAGS) libgirepository_1_0_la_LIBADD = $(GIREPO_LIBS) -libgirepository_1_0_la_LDFLAGS = -no-undefined +libgirepository_1_0_la_LDFLAGS = -no-undefined -version-number 1:0:0 libgirepository_parser_la_SOURCES = \ girmodule.c \ diff --git a/girmodule.c b/girmodule.c index ae40d5f5b..1c62319f4 100644 --- a/girmodule.c +++ b/girmodule.c @@ -290,7 +290,7 @@ g_ir_module_build_typelib (GIrModule *module, /* fill in header */ header = (Header *)data; memcpy (header, G_IR_MAGIC, 16); - header->major_version = 2; + header->major_version = 3; header->minor_version = 0; header->reserved = 0; header->n_entries = n_entries; diff --git a/gitypelib.c b/gitypelib.c index 74aa7edd8..06a38d241 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -288,12 +288,13 @@ validate_header (ValidateContext *ctx, } - if (header->major_version != 2 || header->minor_version != 0) + if (header->major_version != 3 || header->minor_version != 0) { g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_HEADER, - "Version mismatch"); + "Version mismatch; expected 3, found %d", + header->major_version); return FALSE; } From 3a310fd2427e5ce0f060926ec09a6889c7d71728 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 7 Jul 2010 14:07:17 -0400 Subject: [PATCH 358/692] Don't include machine-dependent integral types in the typelib Previously we had both e.g. GI_TYPE_TAG_LONG and GI_TYPE_TAG_INT64, but in fact the typelib is already machine-specific, so it makes sense to just encode this as a fixed type. The .gir remains abstract. We also remove size_t from the typelib; one would never want to treat it differently than an integer. time_t is removed as well; while bindings like gjs had special handling to turn it into e.g. a JS Date object, I don't think we should encourage people to use these POSIX types in their API. Use GTimeVal or the like instead. Because the typelib is now really machine-specific, we need to remove the -expected.tgirs from git. (We could potentially add a check which wasn't just a literal diff later) https://bugzilla.gnome.org/show_bug.cgi?id=623774 --- giconstantinfo.c | 21 --------------- gifieldinfo.c | 60 ----------------------------------------- girepository.c | 18 ------------- girffi.c | 29 -------------------- girnode.c | 27 ------------------- girparser.c | 69 +++++++++++++++++++++++++++++++++++++++--------- girwriter.c | 18 ------------- gitypelib.c | 11 ++------ gitypes.h | 50 +++++++++++++++-------------------- 9 files changed, 79 insertions(+), 224 deletions(-) diff --git a/giconstantinfo.c b/giconstantinfo.c index 4a3b838d7..58b223fba 100644 --- a/giconstantinfo.c +++ b/giconstantinfo.c @@ -129,27 +129,6 @@ g_constant_info_get_value (GIConstantInfo *info, case GI_TYPE_TAG_DOUBLE: value->v_double = *(gdouble*)&rinfo->typelib->data[blob->offset]; break; - case GI_TYPE_TAG_TIME_T: - value->v_long = *(long*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_SHORT: - value->v_short = *(gshort*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_USHORT: - value->v_ushort = *(gushort*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_INT: - value->v_int = *(gint*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_UINT: - value->v_uint = *(guint*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_LONG: - value->v_long = *(glong*)&rinfo->typelib->data[blob->offset]; - break; - case GI_TYPE_TAG_ULONG: - value->v_ulong = *(gulong*)&rinfo->typelib->data[blob->offset]; - break; } } } diff --git a/gifieldinfo.c b/gifieldinfo.c index 14e371f87..9862a723e 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -215,15 +215,11 @@ g_field_info_get_field (GIFieldInfo *field_info, break; case GI_TYPE_TAG_INT16: case GI_TYPE_TAG_UINT16: - case GI_TYPE_TAG_SHORT: - case GI_TYPE_TAG_USHORT: value->v_uint16 = G_STRUCT_MEMBER (guint16, mem, offset); result = TRUE; break; case GI_TYPE_TAG_INT32: case GI_TYPE_TAG_UINT32: - case GI_TYPE_TAG_INT: - case GI_TYPE_TAG_UINT: value->v_uint32 = G_STRUCT_MEMBER (guint32, mem, offset); result = TRUE; break; @@ -232,13 +228,6 @@ g_field_info_get_field (GIFieldInfo *field_info, value->v_uint64 = G_STRUCT_MEMBER (guint64, mem, offset); result = TRUE; break; - case GI_TYPE_TAG_LONG: - case GI_TYPE_TAG_ULONG: - value->v_ulong = G_STRUCT_MEMBER (gulong, mem, offset); - result = TRUE; - break; - case GI_TYPE_TAG_SSIZE: - case GI_TYPE_TAG_SIZE: case GI_TYPE_TAG_GTYPE: value->v_size = G_STRUCT_MEMBER (gsize, mem, offset); result = TRUE; @@ -251,16 +240,6 @@ g_field_info_get_field (GIFieldInfo *field_info, value->v_double = G_STRUCT_MEMBER (gdouble, mem, offset); result = TRUE; break; - case GI_TYPE_TAG_TIME_T: -#if SIZEOF_TIME_T == 4 - value->v_int32 = G_STRUCT_MEMBER (time_t, mem, offset); -#elif SIZEOF_TIME_T == 8 - value->v_int64 = G_STRUCT_MEMBER (time_t, mem, offset); -#else -# error "Unexpected size for time_t: not 4 or 8" -#endif - result = TRUE; - break; case GI_TYPE_TAG_UTF8: case GI_TYPE_TAG_FILENAME: case GI_TYPE_TAG_ARRAY: @@ -306,15 +285,11 @@ g_field_info_get_field (GIFieldInfo *field_info, break; case GI_TYPE_TAG_INT16: case GI_TYPE_TAG_UINT16: - case GI_TYPE_TAG_SHORT: - case GI_TYPE_TAG_USHORT: value->v_int = (gint)G_STRUCT_MEMBER (guint16, mem, offset); result = TRUE; break; case GI_TYPE_TAG_INT32: case GI_TYPE_TAG_UINT32: - case GI_TYPE_TAG_INT: - case GI_TYPE_TAG_UINT: value->v_int = (gint)G_STRUCT_MEMBER (guint32, mem, offset); result = TRUE; break; @@ -323,11 +298,6 @@ g_field_info_get_field (GIFieldInfo *field_info, value->v_int = (gint)G_STRUCT_MEMBER (guint64, mem, offset); result = TRUE; break; - case GI_TYPE_TAG_LONG: - case GI_TYPE_TAG_ULONG: - value->v_int = (gint)G_STRUCT_MEMBER (gulong, mem, offset); - result = TRUE; - break; default: g_warning("Field %s: Unexpected enum storage type %s", g_base_info_get_name ((GIBaseInfo *)field_info), @@ -424,15 +394,11 @@ g_field_info_set_field (GIFieldInfo *field_info, break; case GI_TYPE_TAG_INT16: case GI_TYPE_TAG_UINT16: - case GI_TYPE_TAG_SHORT: - case GI_TYPE_TAG_USHORT: G_STRUCT_MEMBER (guint16, mem, offset) = value->v_uint16; result = TRUE; break; case GI_TYPE_TAG_INT32: case GI_TYPE_TAG_UINT32: - case GI_TYPE_TAG_INT: - case GI_TYPE_TAG_UINT: G_STRUCT_MEMBER (guint32, mem, offset) = value->v_uint32; result = TRUE; break; @@ -441,13 +407,6 @@ g_field_info_set_field (GIFieldInfo *field_info, G_STRUCT_MEMBER (guint64, mem, offset) = value->v_uint64; result = TRUE; break; - case GI_TYPE_TAG_LONG: - case GI_TYPE_TAG_ULONG: - G_STRUCT_MEMBER (gulong, mem, offset)= value->v_ulong; - result = TRUE; - break; - case GI_TYPE_TAG_SSIZE: - case GI_TYPE_TAG_SIZE: case GI_TYPE_TAG_GTYPE: G_STRUCT_MEMBER (gsize, mem, offset) = value->v_size; result = TRUE; @@ -460,16 +419,6 @@ g_field_info_set_field (GIFieldInfo *field_info, G_STRUCT_MEMBER (gdouble, mem, offset)= value->v_double; result = TRUE; break; - case GI_TYPE_TAG_TIME_T: -#if SIZEOF_TIME_T == 4 - G_STRUCT_MEMBER (time_t, mem, offset) = value->v_int32; -#elif SIZEOF_TIME_T == 8 - G_STRUCT_MEMBER (time_t, mem, offset) = value->v_int64; -#else -# error "Unexpected size for time_t: not 4 or 8" -#endif - result = TRUE; - break; case GI_TYPE_TAG_UTF8: case GI_TYPE_TAG_FILENAME: case GI_TYPE_TAG_ARRAY: @@ -510,15 +459,11 @@ g_field_info_set_field (GIFieldInfo *field_info, break; case GI_TYPE_TAG_INT16: case GI_TYPE_TAG_UINT16: - case GI_TYPE_TAG_SHORT: - case GI_TYPE_TAG_USHORT: G_STRUCT_MEMBER (guint16, mem, offset) = (guint16)value->v_int; result = TRUE; break; case GI_TYPE_TAG_INT32: case GI_TYPE_TAG_UINT32: - case GI_TYPE_TAG_INT: - case GI_TYPE_TAG_UINT: G_STRUCT_MEMBER (guint32, mem, offset) = (guint32)value->v_int; result = TRUE; break; @@ -527,11 +472,6 @@ g_field_info_set_field (GIFieldInfo *field_info, G_STRUCT_MEMBER (guint64, mem, offset) = (guint64)value->v_int; result = TRUE; break; - case GI_TYPE_TAG_LONG: - case GI_TYPE_TAG_ULONG: - G_STRUCT_MEMBER (gulong, mem, offset) = (gulong)value->v_int; - result = TRUE; - break; default: g_warning("Field %s: Unexpected enum storage type %s", g_base_info_get_name ((GIBaseInfo *)field_info), diff --git a/girepository.c b/girepository.c index 66a604eb4..ba6756eac 100644 --- a/girepository.c +++ b/girepository.c @@ -1319,28 +1319,10 @@ g_type_tag_to_string (GITypeTag type) return "int64"; case GI_TYPE_TAG_UINT64: return "uint64"; - case GI_TYPE_TAG_SHORT: - return "short"; - case GI_TYPE_TAG_USHORT: - return "ushort"; - case GI_TYPE_TAG_INT: - return "int"; - case GI_TYPE_TAG_UINT: - return "uint"; - case GI_TYPE_TAG_LONG: - return "long"; - case GI_TYPE_TAG_ULONG: - return "ulong"; - case GI_TYPE_TAG_SSIZE: - return "ssize"; - case GI_TYPE_TAG_SIZE: - return "size"; case GI_TYPE_TAG_FLOAT: return "float"; case GI_TYPE_TAG_DOUBLE: return "double"; - case GI_TYPE_TAG_TIME_T: - return "time_t"; case GI_TYPE_TAG_GTYPE: return "GType"; case GI_TYPE_TAG_UTF8: diff --git a/girffi.c b/girffi.c index 559af258c..23b076bca 100644 --- a/girffi.c +++ b/girffi.c @@ -54,25 +54,6 @@ _gi_type_tag_get_ffi_type (GITypeTag tag, return &ffi_type_sint64; case GI_TYPE_TAG_UINT64: return &ffi_type_uint64; - case GI_TYPE_TAG_SHORT: - return &ffi_type_sshort; - case GI_TYPE_TAG_USHORT: - return &ffi_type_ushort; - case GI_TYPE_TAG_INT: - return &ffi_type_sint; - case GI_TYPE_TAG_UINT: - return &ffi_type_uint; - case GI_TYPE_TAG_SSIZE: -#if GLIB_SIZEOF_SIZE_T == 4 - return &ffi_type_sint32; -#elif GLIB_SIZEOF_SIZE_T == 8 - return &ffi_type_sint64; -#else -# error "Unexpected size for size_t: not 4 or 8" -#endif - case GI_TYPE_TAG_LONG: - return &ffi_type_slong; - case GI_TYPE_TAG_SIZE: case GI_TYPE_TAG_GTYPE: #if GLIB_SIZEOF_SIZE_T == 4 return &ffi_type_uint32; @@ -81,16 +62,6 @@ _gi_type_tag_get_ffi_type (GITypeTag tag, #else # error "Unexpected size for size_t: not 4 or 8" #endif - case GI_TYPE_TAG_TIME_T: -#if SIZEOF_TIME_T == 4 - return &ffi_type_sint32; -#elif SIZEOF_TIME_T == 8 - return &ffi_type_sint64; -#else -# error "Unexpected size for time_t: not 4 or 8" -#endif - case GI_TYPE_TAG_ULONG: - return &ffi_type_ulong; case GI_TYPE_TAG_FLOAT: return &ffi_type_float; case GI_TYPE_TAG_DOUBLE: diff --git a/girnode.c b/girnode.c index af24161d2..17b739ea9 100644 --- a/girnode.c +++ b/girnode.c @@ -2319,33 +2319,6 @@ g_ir_node_build_typelib (GIrNode *node, blob->size = 8; DO_ALIGNED_COPY(&data[blob->offset], parse_uint_value (constant->value), guint64); break; - case GI_TYPE_TAG_SHORT: - blob->size = sizeof (gshort); - *(gshort*)&data[blob->offset] = (gshort) parse_int_value (constant->value); - break; - case GI_TYPE_TAG_USHORT: - blob->size = sizeof (gushort); - *(gushort*)&data[blob->offset] = (gushort) parse_uint_value (constant->value); - break; - case GI_TYPE_TAG_INT: - blob->size = sizeof (gint); - *(gint*)&data[blob->offset] = (gint) parse_int_value (constant->value); - break; - case GI_TYPE_TAG_UINT: - blob->size = sizeof (guint); - *(gint*)&data[blob->offset] = (guint) parse_uint_value (constant->value); - break; - case GI_TYPE_TAG_SSIZE: /* FIXME */ - case GI_TYPE_TAG_LONG: - blob->size = sizeof (glong); - DO_ALIGNED_COPY(&data[blob->offset], parse_int_value (constant->value), glong); - break; - case GI_TYPE_TAG_SIZE: /* FIXME */ - case GI_TYPE_TAG_TIME_T: - case GI_TYPE_TAG_ULONG: - blob->size = sizeof (gulong); - DO_ALIGNED_COPY(&data[blob->offset], parse_uint_value (constant->value), gulong); - break; case GI_TYPE_TAG_FLOAT: blob->size = sizeof (gfloat); DO_ALIGNED_COPY(&data[blob->offset], parse_float_value (constant->value), gfloat); diff --git a/girparser.c b/girparser.c index 488d77b9f..8af0396d9 100644 --- a/girparser.c +++ b/girparser.c @@ -326,19 +326,38 @@ push_node (ParseContext *ctx, GIrNode *node) static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib, gboolean in_gobject); +typedef struct { + const gchar *str; + guint size; + guint is_signed : 1; +} IntegerAliasInfo; + +static IntegerAliasInfo integer_aliases[] = { + { "char", SIZEOF_CHAR, 0 }, + { "short", SIZEOF_SHORT, 1 }, + { "ushort", SIZEOF_SHORT, 0 }, + { "int", SIZEOF_INT, 1 }, + { "uint", SIZEOF_INT, 0 }, + { "long", SIZEOF_LONG, 1 }, + { "ulong", SIZEOF_LONG, 0 }, + { "gsize", GLIB_SIZEOF_SIZE_T, 0 }, + { "gssize", GLIB_SIZEOF_SIZE_T, 1 }, +}; + typedef struct { const gchar *str; gint tag; gboolean pointer; } BasicTypeInfo; +#define BASIC_TYPE_FIXED_OFFSET 3 + static BasicTypeInfo basic_types[] = { { "none", GI_TYPE_TAG_VOID, 0 }, { "any", GI_TYPE_TAG_VOID, 1 }, { "bool", GI_TYPE_TAG_BOOLEAN, 0 }, - { "char", GI_TYPE_TAG_INT8, 0 }, - { "int8", GI_TYPE_TAG_INT8, 0 }, + { "int8", GI_TYPE_TAG_INT8, 0 }, /* Start of BASIC_TYPE_FIXED_OFFSET */ { "uint8", GI_TYPE_TAG_UINT8, 0 }, { "int16", GI_TYPE_TAG_INT16, 0 }, { "uint16", GI_TYPE_TAG_UINT16, 0 }, @@ -346,19 +365,8 @@ static BasicTypeInfo basic_types[] = { { "uint32", GI_TYPE_TAG_UINT32, 0 }, { "int64", GI_TYPE_TAG_INT64, 0 }, { "uint64", GI_TYPE_TAG_UINT64, 0 }, - { "short", GI_TYPE_TAG_SHORT, 0 }, - { "ushort", GI_TYPE_TAG_USHORT, 0 }, - { "int", GI_TYPE_TAG_INT, 0 }, - { "uint", GI_TYPE_TAG_UINT, 0 }, - { "long", GI_TYPE_TAG_LONG, 0 }, - { "ulong", GI_TYPE_TAG_ULONG, 0 }, - { "ssize_t", GI_TYPE_TAG_SSIZE, 0 }, - { "ssize", GI_TYPE_TAG_SSIZE, 0 }, - { "size_t", GI_TYPE_TAG_SIZE, 0 }, - { "size", GI_TYPE_TAG_SIZE, 0 }, { "float", GI_TYPE_TAG_FLOAT, 0 }, { "double", GI_TYPE_TAG_DOUBLE, 0 }, - { "time_t", GI_TYPE_TAG_TIME_T, 0 }, { "GType", GI_TYPE_TAG_GTYPE, 0 }, { "utf8", GI_TYPE_TAG_UTF8, 1 }, { "filename", GI_TYPE_TAG_FILENAME,1 }, @@ -375,6 +383,41 @@ parse_basic (const char *str) if (g_str_has_prefix (str, basic_types[i].str)) return &(basic_types[i]); } + for (i = 0; i < G_N_ELEMENTS (integer_aliases); i++) + { + if (g_str_has_prefix (str, integer_aliases[i].str)) + { + switch (integer_aliases[i].size) + { + case sizeof(guint8): + if (integer_aliases[i].is_signed) + return &basic_types[BASIC_TYPE_FIXED_OFFSET]; + else + return &basic_types[BASIC_TYPE_FIXED_OFFSET+1]; + break; + case sizeof(guint16): + if (integer_aliases[i].is_signed) + return &basic_types[BASIC_TYPE_FIXED_OFFSET+2]; + else + return &basic_types[BASIC_TYPE_FIXED_OFFSET+3]; + break; + case sizeof(guint32): + if (integer_aliases[i].is_signed) + return &basic_types[BASIC_TYPE_FIXED_OFFSET+4]; + else + return &basic_types[BASIC_TYPE_FIXED_OFFSET+5]; + break; + case sizeof(guint64): + if (integer_aliases[i].is_signed) + return &basic_types[BASIC_TYPE_FIXED_OFFSET+6]; + else + return &basic_types[BASIC_TYPE_FIXED_OFFSET+7]; + break; + default: + g_assert_not_reached (); + } + } + } return NULL; } diff --git a/girwriter.c b/girwriter.c index 56d61b239..bf7ea9dca 100644 --- a/girwriter.c +++ b/girwriter.c @@ -757,24 +757,6 @@ write_constant_value (const gchar *namespace, case GI_TYPE_TAG_UINT64: xml_printf (file, "%" G_GUINT64_FORMAT, value->v_uint64); break; - case GI_TYPE_TAG_INT: - xml_printf (file, "%d", value->v_int); - break; - case GI_TYPE_TAG_UINT: - xml_printf (file, "%d", value->v_uint); - break; - case GI_TYPE_TAG_LONG: - xml_printf (file, "%ld", value->v_long); - break; - case GI_TYPE_TAG_ULONG: - xml_printf (file, "%ld", value->v_ulong); - break; - case GI_TYPE_TAG_SSIZE: - xml_printf (file, "%zd", value->v_ssize); - break; - case GI_TYPE_TAG_SIZE: - xml_printf (file, "%zd", value->v_size); - break; case GI_TYPE_TAG_FLOAT: xml_printf (file, "%f", value->v_float); break; diff --git a/gitypelib.c b/gitypelib.c index 06a38d241..0741bcb18 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -909,17 +909,8 @@ validate_constant_blob (GTypelib *typelib, 4, /* UINT32 */ 8, /* INT64 */ 8, /* UINT64 */ - sizeof (gshort), - sizeof (gushort), - sizeof (gint), - sizeof (guint), - sizeof (glong), - sizeof (gulong), - sizeof (gssize), - sizeof (gsize), sizeof (gfloat), sizeof (gdouble), - sizeof (time_t), 0, /* GTYPE */ 0, /* UTF8 */ 0, /* FILENAME */ @@ -933,6 +924,8 @@ validate_constant_blob (GTypelib *typelib, ConstantBlob *blob; SimpleTypeBlob *type; + g_assert (G_N_ELEMENTS (value_size) == GI_TYPE_TAG_ERROR + 1); + if (typelib->len < offset + sizeof (ConstantBlob)) { g_set_error (error, diff --git a/gitypes.h b/gitypes.h index 5ef64ca16..eb1c1021c 100644 --- a/gitypes.h +++ b/gitypes.h @@ -319,17 +319,8 @@ typedef enum { * @GI_TYPE_TAG_UINT32: 32-bit unsigned integer * @GI_TYPE_TAG_INT64: 64-bit signed integer * @GI_TYPE_TAG_UINT64: 64-bit unsigned integer - * @GI_TYPE_TAG_SHORT: signed short - * @GI_TYPE_TAG_USHORT: unsigned hosrt - * @GI_TYPE_TAG_INT: signed integer - * @GI_TYPE_TAG_UINT: unsigned integer - * @GI_TYPE_TAG_LONG: signed long - * @GI_TYPE_TAG_ULONG: unsigned long - * @GI_TYPE_TAG_SSIZE: ssize_t - * @GI_TYPE_TAG_SIZE: size_t * @GI_TYPE_TAG_FLOAT: float * @GI_TYPE_TAG_DOUBLE: double floating point - * @GI_TYPE_TAG_TIME_T: time_t * @GI_TYPE_TAG_GTYPE: a #GType * @GI_TYPE_TAG_UTF8: a UTF-8 encoded string * @GI_TYPE_TAG_FILENAME: a filename, encoded in the same encoding @@ -355,31 +346,32 @@ typedef enum { GI_TYPE_TAG_UINT32 = 7, GI_TYPE_TAG_INT64 = 8, GI_TYPE_TAG_UINT64 = 9, - GI_TYPE_TAG_SHORT = 10, - GI_TYPE_TAG_USHORT = 11, - GI_TYPE_TAG_INT = 12, - GI_TYPE_TAG_UINT = 13, - GI_TYPE_TAG_LONG = 14, - GI_TYPE_TAG_ULONG = 15, - GI_TYPE_TAG_SSIZE = 16, - GI_TYPE_TAG_SIZE = 17, - GI_TYPE_TAG_FLOAT = 18, - GI_TYPE_TAG_DOUBLE = 19, - GI_TYPE_TAG_TIME_T = 20, - GI_TYPE_TAG_GTYPE = 21, - GI_TYPE_TAG_UTF8 = 22, - GI_TYPE_TAG_FILENAME = 23, + GI_TYPE_TAG_FLOAT = 10, + GI_TYPE_TAG_DOUBLE = 11, + GI_TYPE_TAG_GTYPE = 12, + GI_TYPE_TAG_UTF8 = 13, + GI_TYPE_TAG_FILENAME = 14, /* Non-basic types */ - GI_TYPE_TAG_ARRAY = 24, - GI_TYPE_TAG_INTERFACE = 25, - GI_TYPE_TAG_GLIST = 26, - GI_TYPE_TAG_GSLIST = 27, - GI_TYPE_TAG_GHASH = 28, - GI_TYPE_TAG_ERROR = 29 + GI_TYPE_TAG_ARRAY = 15, + GI_TYPE_TAG_INTERFACE = 16, + GI_TYPE_TAG_GLIST = 17, + GI_TYPE_TAG_GSLIST = 18, + GI_TYPE_TAG_GHASH = 19, + GI_TYPE_TAG_ERROR = 20 /* Note - there is only room currently for 32 tags. * See docs/typelib-format.txt SimpleTypeBlob definition */ } GITypeTag; +#define GI_TYPE_TAG_N_TYPES (GI_TYPE_TAG_ERROR+1) + +/* These were removed and no longer appear in the typelib; + * instead, the machine-specific versions like INT32 are + * always used. + */ +#define GI_TYPE_TAG_SHORT GI_TYPE_TAG_SHORT_WAS_REMOVED +#define GI_TYPE_TAG_INT GI_TYPE_TAG_INT_WAS_REMOVED +#define GI_TYPE_TAG_LONG GI_TYPE_TAG_LONG_WAS_REMOVED + /** * GIArrayType: * @GI_ARRAY_TYPE_C: a C array, char[] for instance From 1b8bf7a4dc55f3c6066c17330ec065de9c37095d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 14 Jul 2010 11:59:11 -0400 Subject: [PATCH 359/692] [girepository] Actually verify header of loaded typelibs in g_irepository_require Take a GError * for typelib loading code, validate the header. This fixes bizarre errors from gjs where g_irepository_require would happily load old typelibs. --- girepository.c | 4 ++- girmodule.c | 8 +++++- gitypelib.c | 71 +++++++++++++++++++++++++++++++++++++------------- gitypelib.h | 13 +++++---- 4 files changed, 71 insertions(+), 25 deletions(-) diff --git a/girepository.c b/girepository.c index ba6756eac..ef3d6d224 100644 --- a/girepository.c +++ b/girepository.c @@ -1221,7 +1221,9 @@ g_irepository_require (GIRepository *repository, goto out; } - typelib = g_typelib_new_from_mapped_file (mfile); + typelib = g_typelib_new_from_mapped_file (mfile, error); + if (!typelib) + goto out; header = (Header *) typelib->data; typelib_namespace = g_typelib_get_string (typelib, header->namespace); typelib_version = g_typelib_get_string (typelib, header->nsversion); diff --git a/girmodule.c b/girmodule.c index 1c62319f4..066d51616 100644 --- a/girmodule.c +++ b/girmodule.c @@ -206,6 +206,7 @@ GTypelib * g_ir_module_build_typelib (GIrModule *module, GList *modules) { + GError *error = NULL; GTypelib *typelib; gsize length; guint i; @@ -434,7 +435,12 @@ g_ir_module_build_typelib (GIrModule *module, data = g_realloc (data, offset2); header = (Header*) data; length = header->size = offset2; - typelib = g_typelib_new_from_memory (data, length); + typelib = g_typelib_new_from_memory (data, length, &error); + if (!typelib) + { + g_error ("error building typelib: %s", + error->message); + } g_hash_table_destroy (strings); g_hash_table_destroy (types); diff --git a/gitypelib.c b/gitypelib.c index 0741bcb18..5469e8b29 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -260,30 +260,30 @@ validate_name (GTypelib *typelib, return TRUE; } +/* Fast path sanity check, operates on a memory blob */ static gboolean -validate_header (ValidateContext *ctx, - GError **error) +validate_header_basic (const guint8 *memory, + gsize len, + GError **error) { - GTypelib *typelib = ctx->typelib; - Header *header; + Header *header = (Header *)memory; - if (typelib->len < sizeof (Header)) + if (len < sizeof (Header)) { g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID, - "The buffer is too short"); + "The specified typelib length %" G_GSIZE_FORMAT " is too short", + len); return FALSE; } - header = (Header *)typelib->data; - if (strncmp (header->magic, G_IR_MAGIC, 16) != 0) { g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_HEADER, - "Magic string not found"); + "Invalid magic header"); return FALSE; } @@ -293,7 +293,7 @@ validate_header (ValidateContext *ctx, g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_HEADER, - "Version mismatch; expected 3, found %d", + "Typelib version mismatch; expected 3, found %d", header->major_version); return FALSE; @@ -308,12 +308,13 @@ validate_header (ValidateContext *ctx, return FALSE; } - if (header->size != typelib->len) + if (header->size != len) { g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_HEADER, - "Typelib size mismatch"); + "Typelib size %" G_GSIZE_FORMAT " does not match %" G_GSIZE_FORMAT, + header->size, len); return FALSE; } @@ -378,9 +379,24 @@ validate_header (ValidateContext *ctx, return FALSE; } - if (!validate_name (typelib, "namespace", typelib->data, header->namespace, error)) + return TRUE; +} + +static gboolean +validate_header (ValidateContext *ctx, + GError **error) +{ + GTypelib *typelib = ctx->typelib; + + if (!validate_header_basic (typelib->data, typelib->len, error)) return FALSE; + { + Header *header = (Header*)typelib->data; + if (!validate_name (typelib, "namespace", typelib->data, header->namespace, error)) + return FALSE; + } + return TRUE; } @@ -2056,6 +2072,7 @@ _g_typelib_ensure_open (GTypelib *typelib) * g_typelib_new_from_memory: * @memory: address of memory chunk containing the typelib * @len: length of memory chunk containing the typelib + * @error: a #GError * * Creates a new #GTypelib from a memory location. The memory block * pointed to by @typelib will be automatically g_free()d when the @@ -2064,10 +2081,15 @@ _g_typelib_ensure_open (GTypelib *typelib) * Return value: the new #GTypelib **/ GTypelib * -g_typelib_new_from_memory (guchar *memory, gsize len) +g_typelib_new_from_memory (guint8 *memory, + gsize len, + GError **error) { GTypelib *meta; + if (!validate_header_basic (memory, len, error)) + return NULL; + meta = g_slice_new0 (GTypelib); meta->data = memory; meta->len = len; @@ -2081,16 +2103,22 @@ g_typelib_new_from_memory (guchar *memory, gsize len) * g_typelib_new_from_const_memory: * @memory: address of memory chunk containing the typelib * @len: length of memory chunk containing the typelib + * @error: A #GError * * Creates a new #GTypelib from a memory location. * * Return value: the new #GTypelib **/ GTypelib * -g_typelib_new_from_const_memory (const guchar *memory, gsize len) +g_typelib_new_from_const_memory (const guchar *memory, + gsize len, + GError **error) { GTypelib *meta; + if (!validate_header_basic (memory, len, error)) + return NULL; + meta = g_slice_new0 (GTypelib); meta->data = (guchar *) memory; meta->len = len; @@ -2103,21 +2131,28 @@ g_typelib_new_from_const_memory (const guchar *memory, gsize len) /** * g_typelib_new_from_mapped_file: * @mfile: a #GMappedFile, that will be free'd when the repository is destroyed + * @error: a #GError * * Creates a new #GTypelib from a #GMappedFile. * * Return value: the new #GTypelib **/ GTypelib * -g_typelib_new_from_mapped_file (GMappedFile *mfile) +g_typelib_new_from_mapped_file (GMappedFile *mfile, + GError **error) { GTypelib *meta; + guint8 *data = (guint8 *) g_mapped_file_get_contents (mfile); + gsize len = g_mapped_file_get_length (mfile); + + if (!validate_header_basic (data, len, error)) + return NULL; meta = g_slice_new0 (GTypelib); meta->mfile = mfile; meta->owns_memory = FALSE; - meta->data = (guchar *) g_mapped_file_get_contents (mfile); - meta->len = g_mapped_file_get_length (mfile); + meta->data = data; + meta->len = len; return meta; } diff --git a/gitypelib.h b/gitypelib.h index 5d5eda5fe..0a61008ac 100644 --- a/gitypelib.h +++ b/gitypelib.h @@ -34,11 +34,14 @@ G_BEGIN_DECLS typedef struct _GTypelib GTypelib; -GTypelib * g_typelib_new_from_memory (guchar *memory, - gsize len); -GTypelib * g_typelib_new_from_const_memory (const guchar *memory, - gsize len); -GTypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile); +GTypelib * g_typelib_new_from_memory (guint8 *memory, + gsize len, + GError **error); +GTypelib * g_typelib_new_from_const_memory (const guint8 *memory, + gsize len, + GError **error); +GTypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile, + GError **error); void g_typelib_free (GTypelib *typelib); gboolean g_typelib_symbol (GTypelib *typelib, From 5b5ab282a6718b6dce46405a7dbb1a08a953485a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Thu, 15 Jul 2010 23:40:28 +0200 Subject: [PATCH 360/692] [girepository] Fix ordering in override_search_path Entries in the GI_TYPELIB_PATH environment variable are added to the global search path in reverse order - instead, add entries in the same order in which they are specified. --- girepository.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/girepository.c b/girepository.c index ef3d6d224..df09d822b 100644 --- a/girepository.c +++ b/girepository.c @@ -131,6 +131,9 @@ init_globals (void) g_free (custom_dirs); } + if (override_search_path != NULL) + override_search_path = g_slist_reverse (override_search_path); + libdir = GOBJECT_INTROSPECTION_LIBDIR; typelib_dir = g_build_filename (libdir, "girepository-1.0", NULL); From c8fb0f97a867e73c8125647fbbc7d741a4928a2d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 19 Jul 2010 17:48:17 -0400 Subject: [PATCH 361/692] Fix two compilation warnings --- gitypelib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitypelib.c b/gitypelib.c index 5469e8b29..ef87c0e61 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -314,7 +314,7 @@ validate_header_basic (const guint8 *memory, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_HEADER, "Typelib size %" G_GSIZE_FORMAT " does not match %" G_GSIZE_FORMAT, - header->size, len); + (gsize) header->size, len); return FALSE; } From c0b26bf0a0442793b2731c8aae30b771be1af779 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 22 Jul 2010 13:46:33 -0400 Subject: [PATCH 362/692] [girepository] Include path to file in typelib load failure error This makes version conflicts more obvious. --- girepository.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/girepository.c b/girepository.c index df09d822b..f379cf68a 100644 --- a/girepository.c +++ b/girepository.c @@ -1224,9 +1224,19 @@ g_irepository_require (GIRepository *repository, goto out; } - typelib = g_typelib_new_from_mapped_file (mfile, error); - if (!typelib) - goto out; + { + GError *temp_error = NULL; + typelib = g_typelib_new_from_mapped_file (mfile, &temp_error); + if (!typelib) + { + g_set_error (error, G_IREPOSITORY_ERROR, + G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND, + "Failed to load typelib file '%s' for namespace '%s': %s", + path, namespace, temp_error->message); + g_clear_error (&temp_error); + goto out; + } + } header = (Header *) typelib->data; typelib_namespace = g_typelib_get_string (typelib, header->namespace); typelib_version = g_typelib_get_string (typelib, header->nsversion); From 958b70d8b07c3c2c3eb7ebd8e67d47227f790313 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 27 Jul 2010 07:06:54 -0400 Subject: [PATCH 363/692] Add g_irepository_enumerate This will be used for pygobject to enumerate namespaces. --- girepository.c | 71 ++++++++++++++++++++++++++++++++++++++++---------- girepository.h | 2 ++ 2 files changed, 59 insertions(+), 14 deletions(-) diff --git a/girepository.c b/girepository.c index f379cf68a..6aae24575 100644 --- a/girepository.c +++ b/girepository.c @@ -1049,23 +1049,18 @@ free_candidate (struct NamespaceVersionCandidadate *candidate) g_slice_free (struct NamespaceVersionCandidadate, candidate); } -static GMappedFile * -find_namespace_latest (const gchar *namespace, - gchar **version_ret, - gchar **path_ret) +static GSList * +enumerate_namespace_versions (const gchar *namespace) { + GSList *candidates = NULL; + GHashTable *found_versions = g_hash_table_new (g_str_hash, g_str_equal); + char *namespace_dash; + char *namespace_typelib; GSList *tmp_path; GSList *ldir; GError *error = NULL; - char *namespace_dash; - char *namespace_typelib; - GSList *candidates = NULL; - GMappedFile *result = NULL; int index; - *version_ret = NULL; - *path_ret = NULL; - namespace_dash = g_strdup_printf ("%s-", namespace); namespace_typelib = g_strdup_printf ("%s.typelib", namespace); @@ -1105,6 +1100,10 @@ find_namespace_latest (const gchar *namespace, else continue; + if (g_hash_table_lookup (found_versions, version) != NULL) + continue; + g_hash_table_insert (found_versions, version, version); + path = g_build_filename (dirname, entry, NULL); mfile = g_mapped_file_new (path, FALSE, &error); if (mfile == NULL) @@ -1124,6 +1123,27 @@ find_namespace_latest (const gchar *namespace, g_dir_close (dir); index++; } + + g_slist_free (tmp_path); + g_free (namespace_dash); + g_free (namespace_typelib); + g_hash_table_destroy (found_versions); + + return candidates; +} + +static GMappedFile * +find_namespace_latest (const gchar *namespace, + gchar **version_ret, + gchar **path_ret) +{ + GSList *candidates; + GMappedFile *result = NULL; + + *version_ret = NULL; + *path_ret = NULL; + + candidates = enumerate_namespace_versions (namespace); if (candidates != NULL) { @@ -1141,12 +1161,35 @@ find_namespace_latest (const gchar *namespace, g_slist_foreach (candidates, (GFunc) free_candidate, NULL); g_slist_free (candidates); } - g_free (namespace_dash); - g_free (namespace_typelib); - g_slist_free (tmp_path); return result; } +/** + * g_irepository_enumerate: + * @repository: (allow-none): Repository + * @namespace_: GI namespace, e.g. "Gtk" + * + * Returns: (element-type utf8) (transfer full): An array of versions available for + * this namespace. + */ +GList * +g_irepository_enumerate (GIRepository *repository, + const gchar *namespace_) +{ + GList *ret = NULL; + GSList *candidates, *link; + + candidates = enumerate_namespace_versions (namespace_); + for (link = candidates; link; link = link->next) + { + struct NamespaceVersionCandidadate *candidate = link->data; + ret = g_list_append (ret, g_strdup (candidate->version)); + free_candidate (candidate); + } + g_slist_free (candidates); + return ret; +} + /** * g_irepository_require: * @repository: (allow-none): Repository, may be %NULL for the default diff --git a/girepository.h b/girepository.h index 4b605d237..b3937950c 100644 --- a/girepository.h +++ b/girepository.h @@ -101,6 +101,8 @@ gboolean g_irepository_is_registered (GIRepository *repository, GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, const gchar *namespace_, const gchar *name); +GList * g_irepository_enumerate (GIRepository *repository, + const gchar *namespace_); GTypelib * g_irepository_require (GIRepository *repository, const gchar *namespace_, const gchar *version, From da698167a05a6a73dc5c1a0e6235357d91dbe91e Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Wed, 28 Jul 2010 12:24:10 +0200 Subject: [PATCH 364/692] Add g_info_type_to_string (GIInfoType type) --- girepository.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++ gitypeinfo.h | 1 + 2 files changed, 57 insertions(+) diff --git a/girepository.c b/girepository.c index 6aae24575..bc2c0873e 100644 --- a/girepository.c +++ b/girepository.c @@ -1403,3 +1403,59 @@ g_type_tag_to_string (GITypeTag type) return "unknown"; } } + +/** + * g_info_type_to_string: + * @type: info type + * + * Returns: (transfer none): Description for this info type + */ +const gchar* +g_info_type_to_string (GIInfoType type) +{ + switch (type) + { + case GI_INFO_TYPE_INVALID: + return "invalid"; + case GI_INFO_TYPE_FUNCTION: + return "function"; + case GI_INFO_TYPE_CALLBACK: + return "callback"; + case GI_INFO_TYPE_STRUCT: + return "struct"; + case GI_INFO_TYPE_BOXED: + return "boxed"; + case GI_INFO_TYPE_ENUM: + return "enum"; + case GI_INFO_TYPE_FLAGS: + return "flags"; + case GI_INFO_TYPE_OBJECT: + return "object"; + case GI_INFO_TYPE_INTERFACE: + return "interface"; + case GI_INFO_TYPE_CONSTANT: + return "constant"; + case GI_INFO_TYPE_ERROR_DOMAIN: + return "error domain"; + case GI_INFO_TYPE_UNION: + return "union"; + case GI_INFO_TYPE_VALUE: + return "value"; + case GI_INFO_TYPE_SIGNAL: + return "signal"; + case GI_INFO_TYPE_VFUNC: + return "vfunc"; + case GI_INFO_TYPE_PROPERTY: + return "property"; + case GI_INFO_TYPE_FIELD: + return "field"; + case GI_INFO_TYPE_ARG: + return "arg"; + case GI_INFO_TYPE_TYPE: + return "type"; + case GI_INFO_TYPE_UNRESOLVED: + return "unresolved"; + default: + return "unknown"; + } +} diff --git a/gitypeinfo.h b/gitypeinfo.h index 4d33d31ec..39890a7d9 100644 --- a/gitypeinfo.h +++ b/gitypeinfo.h @@ -36,6 +36,7 @@ G_BEGIN_DECLS #define G_TYPE_TAG_IS_BASIC(tag) (tag < GI_TYPE_TAG_ARRAY) const gchar* g_type_tag_to_string (GITypeTag type); +const gchar* g_info_type_to_string (GIInfoType type); gboolean g_type_info_is_pointer (GITypeInfo *info); GITypeTag g_type_info_get_tag (GITypeInfo *info); From ab9085eda341e112fb97c04b6ccbdf618946ab5a Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Wed, 28 Jul 2010 08:52:05 -0300 Subject: [PATCH 365/692] [GIRepository] Rename g_irepository_enumerate Rename it to g_irepository_enumerate_versions --- girepository.c | 17 +++++++++-------- girepository.h | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/girepository.c b/girepository.c index bc2c0873e..46f95dedd 100644 --- a/girepository.c +++ b/girepository.c @@ -1050,7 +1050,7 @@ free_candidate (struct NamespaceVersionCandidadate *candidate) } static GSList * -enumerate_namespace_versions (const gchar *namespace) +enumerate_namespace_versions (const gchar *namespace) { GSList *candidates = NULL; GHashTable *found_versions = g_hash_table_new (g_str_hash, g_str_equal); @@ -1123,7 +1123,7 @@ enumerate_namespace_versions (const gchar *namespace) g_dir_close (dir); index++; } - + g_slist_free (tmp_path); g_free (namespace_dash); g_free (namespace_typelib); @@ -1165,20 +1165,21 @@ find_namespace_latest (const gchar *namespace, } /** - * g_irepository_enumerate: - * @repository: (allow-none): Repository + * g_irepository_enumerate_versions: + * @repository: (allow-none): the repository * @namespace_: GI namespace, e.g. "Gtk" * - * Returns: (element-type utf8) (transfer full): An array of versions available for - * this namespace. + * Obtain a list of versions for @namespace_ in this @repository. + * + * Returns: (element-type utf8) (transfer full): the array of versions. */ GList * -g_irepository_enumerate (GIRepository *repository, +g_irepository_enumerate_versions (GIRepository *repository, const gchar *namespace_) { GList *ret = NULL; GSList *candidates, *link; - + candidates = enumerate_namespace_versions (namespace_); for (link = candidates; link; link = link->next) { diff --git a/girepository.h b/girepository.h index b3937950c..181744070 100644 --- a/girepository.h +++ b/girepository.h @@ -101,8 +101,8 @@ gboolean g_irepository_is_registered (GIRepository *repository, GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, const gchar *namespace_, const gchar *name); -GList * g_irepository_enumerate (GIRepository *repository, - const gchar *namespace_); +GList * g_irepository_enumerate_versions (GIRepository *repository, + const gchar *namespace_); GTypelib * g_irepository_require (GIRepository *repository, const gchar *namespace_, const gchar *version, From c93fbff870ec5423fcf3e19e561a165b54aeb981 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Wed, 28 Jul 2010 08:52:45 -0300 Subject: [PATCH 366/692] [girepository] Update documentation --- girepository.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/girepository.c b/girepository.c index 46f95dedd..02f86beae 100644 --- a/girepository.c +++ b/girepository.c @@ -1353,6 +1353,14 @@ g_irepository_error_quark (void) return quark; } +/** + * g_type_tag_to_string: + * @type: the type_tag + * + * Obtain a string representation of @type + * + * Returns: the string + */ const gchar* g_type_tag_to_string (GITypeTag type) { @@ -1407,9 +1415,11 @@ g_type_tag_to_string (GITypeTag type) /** * g_info_type_to_string: - * @type: info type + * @type: the info type * - * Returns: (transfer none): Description for this info type + * Obtain a string representation of @type + * + * Returns: the string */ const gchar* g_info_type_to_string (GIInfoType type) From 899718c93c6524278c3abe4e23425cf000f805d4 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Wed, 28 Jul 2010 09:01:33 -0300 Subject: [PATCH 367/692] [girepository-private] Add ffi declarations Add declarations for the ffi closure api we're using, this silents GCC warnings on systems with broken ffi headers. --- girepository-private.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/girepository-private.h b/girepository-private.h index 8382f408f..e2810d26e 100644 --- a/girepository-private.h +++ b/girepository-private.h @@ -110,4 +110,13 @@ GIVFuncInfo * _g_base_info_find_vfunc (GIRealInfo *rinfo, ffi_type * _gi_type_tag_get_ffi_type (GITypeTag type_tag, gboolean is_pointer); +extern ffi_status ffi_prep_closure_loc (ffi_closure *, + ffi_cif *, + void (*fun)(ffi_cif *, void *, void **, void *), + void *user_data, + void *codeloc); +extern void *ffi_closure_alloc (size_t size, void **code); +extern void ffi_closure_free (void *); + + #endif /* __GIREPOSITORY_PRIVATE_H__ */ From 9771d87b4df5643ec9ccd490ab02e831d7ee609f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 28 Jul 2010 16:35:47 +0200 Subject: [PATCH 368/692] Add BLOB_TYPE_FLAGS to BLOB_IS_REGISTERED_TYPE --- gitypelib-internal.h | 1 + 1 file changed, 1 insertion(+) diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 981f7b480..d1461fa1f 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -181,6 +181,7 @@ typedef enum { ((blob)->blob_type == BLOB_TYPE_STRUCT || \ (blob)->blob_type == BLOB_TYPE_UNION || \ (blob)->blob_type == BLOB_TYPE_ENUM || \ + (blob)->blob_type == BLOB_TYPE_FLAGS || \ (blob)->blob_type == BLOB_TYPE_OBJECT || \ (blob)->blob_type == BLOB_TYPE_INTERFACE) From e3b7e76b86b187d3d389b8854e3f7ae39c678113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steve=20Fr=C3=A9cinaux?= Date: Fri, 30 Jul 2010 20:38:34 +0200 Subject: [PATCH 369/692] Add new API g_typelib_require_private() This is equivalent to g_typelib_require() but intended for use with private typelibs, which get loaded from the provided directory. https://bugzilla.gnome.org/show_bug.cgi?id=625672 --- girepository.c | 123 +++++++++++++++++++++++++++++++++++-------------- girepository.h | 6 +++ 2 files changed, 94 insertions(+), 35 deletions(-) diff --git a/girepository.c b/girepository.c index 02f86beae..7c2e2b509 100644 --- a/girepository.c +++ b/girepository.c @@ -929,9 +929,9 @@ g_irepository_get_typelib_path (GIRepository *repository, static GMappedFile * find_namespace_version (const gchar *namespace, const gchar *version, + GSList *search_path, gchar **path_ret) { - GSList *tmp_path; GSList *ldir; GError *error = NULL; GMappedFile *mfile = NULL; @@ -939,8 +939,7 @@ find_namespace_version (const gchar *namespace, fname = g_strdup_printf ("%s-%s.typelib", namespace, version); - tmp_path = build_search_path_with_overrides (); - for (ldir = tmp_path; ldir; ldir = ldir->next) + for (ldir = search_path; ldir; ldir = ldir->next) { char *path = g_build_filename (ldir->data, fname, NULL); @@ -955,7 +954,6 @@ find_namespace_version (const gchar *namespace, break; } g_free (fname); - g_slist_free (tmp_path); return mfile; } @@ -1050,13 +1048,13 @@ free_candidate (struct NamespaceVersionCandidadate *candidate) } static GSList * -enumerate_namespace_versions (const gchar *namespace) +enumerate_namespace_versions (const gchar *namespace, + GSList *search_path) { GSList *candidates = NULL; GHashTable *found_versions = g_hash_table_new (g_str_hash, g_str_equal); char *namespace_dash; char *namespace_typelib; - GSList *tmp_path; GSList *ldir; GError *error = NULL; int index; @@ -1065,8 +1063,7 @@ enumerate_namespace_versions (const gchar *namespace) namespace_typelib = g_strdup_printf ("%s.typelib", namespace); index = 0; - tmp_path = build_search_path_with_overrides (); - for (ldir = tmp_path; ldir; ldir = ldir->next) + for (ldir = search_path; ldir; ldir = ldir->next) { GDir *dir; const char *dirname; @@ -1124,7 +1121,6 @@ enumerate_namespace_versions (const gchar *namespace) index++; } - g_slist_free (tmp_path); g_free (namespace_dash); g_free (namespace_typelib); g_hash_table_destroy (found_versions); @@ -1134,6 +1130,7 @@ enumerate_namespace_versions (const gchar *namespace) static GMappedFile * find_namespace_latest (const gchar *namespace, + GSList *search_path, gchar **version_ret, gchar **path_ret) { @@ -1143,7 +1140,7 @@ find_namespace_latest (const gchar *namespace, *version_ret = NULL; *path_ret = NULL; - candidates = enumerate_namespace_versions (namespace); + candidates = enumerate_namespace_versions (namespace, search_path); if (candidates != NULL) { @@ -1178,9 +1175,13 @@ g_irepository_enumerate_versions (GIRepository *repository, const gchar *namespace_) { GList *ret = NULL; + GSList *search_path; GSList *candidates, *link; - candidates = enumerate_namespace_versions (namespace_); + search_path = build_search_path_with_overrides (); + candidates = enumerate_namespace_versions (namespace_, search_path); + g_slist_free (search_path); + for (link = candidates; link; link = link->next) { struct NamespaceVersionCandidadate *candidate = link->data; @@ -1191,28 +1192,13 @@ g_irepository_enumerate_versions (GIRepository *repository, return ret; } -/** - * g_irepository_require: - * @repository: (allow-none): Repository, may be %NULL for the default - * @namespace_: GI namespace to use, e.g. "Gtk" - * @version: (allow-none): Version of namespace, may be %NULL for latest - * @flags: Set of %GIRepositoryLoadFlags, may be 0 - * @error: a #GError. - * - * Force the namespace @namespace_ to be loaded if it isn't already. - * If @namespace_ is not loaded, this function will search for a - * ".typelib" file using the repository search path. In addition, a - * version @version of namespace may be specified. If @version is - * not specified, the latest will be used. - * - * Returns: a pointer to the #GTypelib if successful, %NULL otherwise - */ -GTypelib * -g_irepository_require (GIRepository *repository, - const gchar *namespace, - const gchar *version, - GIRepositoryLoadFlags flags, - GError **error) +static GTypelib * +require_internal (GIRepository *repository, + const gchar *namespace, + const gchar *version, + GIRepositoryLoadFlags flags, + GSList *search_path, + GError **error) { GMappedFile *mfile; GTypelib *ret = NULL; @@ -1245,12 +1231,14 @@ g_irepository_require (GIRepository *repository, if (version != NULL) { - mfile = find_namespace_version (namespace, version, &path); + mfile = find_namespace_version (namespace, version, + search_path, &path); tmp_version = g_strdup (version); } else { - mfile = find_namespace_latest (namespace, &tmp_version, &path); + mfile = find_namespace_latest (namespace, search_path, + &tmp_version, &path); } if (mfile == NULL) @@ -1317,6 +1305,71 @@ g_irepository_require (GIRepository *repository, return ret; } +/** + * g_irepository_require: + * @repository: (allow-none): Repository, may be %NULL for the default + * @namespace_: GI namespace to use, e.g. "Gtk" + * @version: (allow-none): Version of namespace, may be %NULL for latest + * @flags: Set of %GIRepositoryLoadFlags, may be 0 + * @error: a #GError. + * + * Force the namespace @namespace_ to be loaded if it isn't already. + * If @namespace_ is not loaded, this function will search for a + * ".typelib" file using the repository search path. In addition, a + * version @version of namespace may be specified. If @version is + * not specified, the latest will be used. + * + * Returns: a pointer to the #GTypelib if successful, %NULL otherwise + */ +GTypelib * +g_irepository_require (GIRepository *repository, + const gchar *namespace, + const gchar *version, + GIRepositoryLoadFlags flags, + GError **error) +{ + GSList *search_path; + GTypelib *typelib; + + search_path = build_search_path_with_overrides (); + typelib = require_internal (repository, namespace, version, flags, + search_path, error); + g_slist_free (search_path); + + return typelib; +} + +/** + * g_irepository_require_private: + * @repository: (allow-none): Repository, may be %NULL for the default + * @typelib_dir: Private directory where to find the requested typelib + * @namespace_: GI namespace to use, e.g. "Gtk" + * @version: (allow-none): Version of namespace, may be %NULL for latest + * @flags: Set of %GIRepositoryLoadFlags, may be 0 + * @error: a #GError. + * + * Force the namespace @namespace_ to be loaded if it isn't already. + * If @namespace_ is not loaded, this function will search for a + * ".typelib" file within the private directory only. In addition, a + * version @version of namespace should be specified. If @version is + * not specified, the latest will be used. + * + * Returns: a pointer to the #GTypelib if successful, %NULL otherwise + */ +GTypelib * +g_irepository_require_private (GIRepository *repository, + const gchar *typelib_dir, + const gchar *namespace, + const gchar *version, + GIRepositoryLoadFlags flags, + GError **error) +{ + GSList search_path = { (gpointer) typelib_dir, NULL }; + + return require_internal (repository, namespace, version, flags, + &search_path, error); +} + static gboolean g_irepository_introspect_cb (const char *option_name, const char *value, diff --git a/girepository.h b/girepository.h index 181744070..5c6a1c0f1 100644 --- a/girepository.h +++ b/girepository.h @@ -108,6 +108,12 @@ GTypelib * g_irepository_require (GIRepository *repository, const gchar *version, GIRepositoryLoadFlags flags, GError **error); +GTypelib * g_irepository_require_private (GIRepository *repository, + const gchar *typelib_dir, + const gchar *namespace, + const gchar *version, + GIRepositoryLoadFlags flags, + GError **error); gchar ** g_irepository_get_dependencies (GIRepository *repository, const gchar *namespace_); gchar ** g_irepository_get_loaded_namespaces (GIRepository *repository); From 439753a5b3e997e3a76694052c7badf62060951b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steve=20Fr=C3=A9cinaux?= Date: Tue, 3 Aug 2010 23:39:58 +0200 Subject: [PATCH 370/692] Do not leak typelibs with wrong header info. Previously the typelibs that were loaded but whose header information weren't right were just leaked. https://bugzilla.gnome.org/show_bug.cgi?id=625672 --- girepository.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/girepository.c b/girepository.c index 7c2e2b509..50bcfbdca 100644 --- a/girepository.c +++ b/girepository.c @@ -1280,6 +1280,7 @@ require_internal (GIRepository *repository, "Typelib file %s for namespace '%s' contains " "namespace '%s' which doesn't match the file name", path, namespace, typelib_namespace); + g_typelib_free (typelib); goto out; } if (version != NULL && strcmp (typelib_version, version) != 0) @@ -1289,6 +1290,7 @@ require_internal (GIRepository *repository, "Typelib file %s for namespace '%s' contains " "version '%s' which doesn't match the expected version '%s'", path, namespace, typelib_version, version); + g_typelib_free (typelib); goto out; } From f552f46f88064e3d10084cdadc476254e9bcaf32 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 21 Jul 2010 18:55:24 -0400 Subject: [PATCH 371/692] [girparser] Cleanly pass through c:include --- girparser.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/girparser.c b/girparser.c index 8af0396d9..11576e913 100644 --- a/girparser.c +++ b/girparser.c @@ -47,6 +47,7 @@ typedef enum STATE_END, STATE_REPOSITORY, STATE_INCLUDE, + STATE_C_INCLUDE, STATE_PACKAGE, STATE_NAMESPACE, /* 5 */ STATE_ENUM, @@ -2734,6 +2735,11 @@ start_element_handler (GMarkupParseContext *context, attribute_names, attribute_values, ctx, error)) goto out; + else if (strcmp (element_name, "c:include") == 0) + { + state_switch (ctx, STATE_C_INCLUDE); + goto out; + } break; case 'm': @@ -3033,6 +3039,13 @@ end_element_handler (GMarkupParseContext *context, } break; + case STATE_C_INCLUDE: + if (require_end_element (context, ctx, "c:include", element_name, error)) + { + state_switch (ctx, STATE_REPOSITORY); + } + break; + case STATE_PACKAGE: if (require_end_element (context, ctx, "package", element_name, error)) { From 9b1bb64e830832ca78772399fffdb02c02a16bd9 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 31 Jul 2010 06:22:52 -0400 Subject: [PATCH 372/692] [girepository] Fix up error printing We didn't show the right error message if we failed to find the symbol; fix this by removing error printing from the middle of the dumper, and add it correctly to the toplevel dump entry point. --- gdump.c | 12 ++++++++++-- girepository.c | 11 +++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/gdump.c b/gdump.c index 328f07521..3dc21728f 100644 --- a/gdump.c +++ b/gdump.c @@ -68,6 +68,7 @@ static GType invoke_get_type (GModule *self, const char *symbol, GError **error) { GetTypeFunc sym; + GType ret; if (!g_module_symbol (self, symbol, (void**)&sym)) { @@ -78,7 +79,15 @@ invoke_get_type (GModule *self, const char *symbol, GError **error) return G_TYPE_INVALID; } - return sym (); + ret = sym (); + if (ret == G_TYPE_INVALID) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Function '%s' returned G_TYPE_INVALID", symbol); + } + return ret; } static void @@ -429,7 +438,6 @@ g_irepository_dump (const char *arg, GError **error) if (type == G_TYPE_INVALID) { - g_printerr ("Invalid GType: '%s'\n", line); caught_error = TRUE; g_free (line); break; diff --git a/girepository.c b/girepository.c index 50bcfbdca..17d076d5b 100644 --- a/girepository.c +++ b/girepository.c @@ -1378,8 +1378,15 @@ g_irepository_introspect_cb (const char *option_name, gpointer data, GError **error) { - gboolean ret = g_irepository_dump (value, error); - exit (ret ? 0 : 1); + GError *tmp_error = NULL; + gboolean ret = g_irepository_dump (value, &tmp_error); + if (!ret) + { + g_error ("Failed to extract GType data: %s", + tmp_error->message); + exit (1); + } + exit (0); } static const GOptionEntry introspection_args[] = { From 62f1b65cc8bf07ceffd0b32d40bf29fdf27f9aee Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 26 Jul 2010 16:26:46 -0400 Subject: [PATCH 373/692] [gircompiler] Clean up parsing We never actually include multiple modules in the compiler, so just nuke that. Also rather than passing around GIrModule consistently pass around a GIrTypelibBuild structure which has various things. This lets us maintain a stack there which we can walk for better error messages. Also, fix up the node lookup in giroffsets.c; previously it didn't really handle includes correctly. We really need to switch to always using Foo.Bar (i.e. GIName) names internally... --- girmodule.c | 36 ++++++++--- girmodule.h | 17 ++++-- girnode.c | 165 ++++++++++++++++++++++++--------------------------- girnode.h | 28 +++------ giroffsets.c | 96 +++++++++++++++--------------- girparser.c | 97 ++++++++++++++++++------------ girparser.h | 20 ++++--- 7 files changed, 243 insertions(+), 216 deletions(-) diff --git a/girmodule.c b/girmodule.c index 066d51616..70b1d2a81 100644 --- a/girmodule.c +++ b/girmodule.c @@ -78,7 +78,7 @@ g_ir_module_free (GIrModule *module) /** * g_ir_module_fatal: - * @module: Current module + * @build: Current build * @line: Origin line number, or 0 if unknown * @msg: printf-format string * @args: Remaining arguments @@ -86,12 +86,14 @@ g_ir_module_free (GIrModule *module) * Report a fatal error, then exit. */ void -g_ir_module_fatal (GIrModule *module, +g_ir_module_fatal (GIrTypelibBuild *build, guint line, const char *msg, ...) { + GString *context; char *formatted; + GList *link; va_list args; @@ -99,10 +101,27 @@ g_ir_module_fatal (GIrModule *module, formatted = g_strdup_vprintf (msg, args); - if (line) - g_printerr ("%s-%s.gir:%d: error: %s\n", module->name, module->version, line, formatted); - else - g_printerr ("%s-%s.gir: error: %s\n", module->name, module->version, formatted); + context = g_string_new (""); + if (line > 0) + g_string_append_printf (context, "%d: ", line); + if (build->stack) + g_string_append (context, "In "); + for (link = g_list_last (build->stack); link; link = link->prev) + { + GIrNode *node = link->data; + const char *name = node->name; + if (name) + g_string_append (context, name); + if (link->prev) + g_string_append (context, "."); + } + if (build->stack) + g_string_append (context, ": "); + + g_printerr ("%s-%s.gir:%serror: %s\n", build->module->name, + build->module->version, + context->str, formatted); + g_string_free (context, TRUE); exit (1); @@ -203,8 +222,7 @@ node_cmp_offset_func (gconstpointer a, GTypelib * -g_ir_module_build_typelib (GIrModule *module, - GList *modules) +g_ir_module_build_typelib (GIrModule *module) { GError *error = NULL; GTypelib *typelib; @@ -393,8 +411,8 @@ g_ir_module_build_typelib (GIrModule *module, entry->offset = offset; entry->name = write_string (node->name, strings, data, &offset2); + memset (&build, 0, sizeof (build)); build.module = module; - build.modules = modules; build.strings = strings; build.types = types; build.nodes_with_attributes = nodes_with_attributes; diff --git a/girmodule.h b/girmodule.h index bd3fbf29d..e8d7ad1e8 100644 --- a/girmodule.h +++ b/girmodule.h @@ -26,9 +26,19 @@ G_BEGIN_DECLS - +typedef struct _GIrTypelibBuild GIrTypelibBuild; typedef struct _GIrModule GIrModule; +struct _GIrTypelibBuild { + GIrModule *module; + GHashTable *strings; + GHashTable *types; + GList *nodes_with_attributes; + guint32 n_attributes; + guchar *data; + GList *stack; +}; + struct _GIrModule { gchar *name; @@ -58,10 +68,9 @@ void g_ir_module_free (GIrModule *module); void g_ir_module_add_include_module (GIrModule *module, GIrModule *include_module); -GTypelib * g_ir_module_build_typelib (GIrModule *module, - GList *modules); +GTypelib * g_ir_module_build_typelib (GIrModule *module); -void g_ir_module_fatal (GIrModule *module, guint line, const char *msg, ...) G_GNUC_PRINTF (3, 4) G_GNUC_NORETURN; +void g_ir_module_fatal (GIrTypelibBuild *build, guint line, const char *msg, ...) G_GNUC_PRINTF (3, 4) G_GNUC_NORETURN; void _g_irnode_init_stats (void); void _g_irnode_dump_stats (void); diff --git a/girnode.c b/girnode.c index 17b739ea9..b35c745ee 100644 --- a/girnode.c +++ b/girnode.c @@ -113,7 +113,8 @@ g_ir_node_type_to_string (GIrNodeTypeId type) } GIrNode * -g_ir_node_new (GIrNodeTypeId type) +g_ir_node_new (GIrNodeTypeId type, + GIrModule *module) { GIrNode *node = NULL; @@ -192,6 +193,7 @@ g_ir_node_new (GIrNodeTypeId type) } node->type = type; + node->module = module; node->offset = 0; node->attributes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); @@ -1040,12 +1042,12 @@ parse_boolean_value (const gchar *str) } static GIrNode * -find_entry_node (GIrModule *module, - GList *modules, +find_entry_node (GIrTypelibBuild *build, const gchar *name, guint16 *idx) { + GIrModule *module = build->module; GList *l; gint i; gchar **names; @@ -1086,7 +1088,7 @@ find_entry_node (GIrModule *module, if (n_names > 1) { - GIrNode *node = g_ir_node_new (G_IR_NODE_XREF); + GIrNode *node = g_ir_node_new (G_IR_NODE_XREF, module); ((GIrNodeXRef *)node)->namespace = g_strdup (names[0]); node->name = g_strdup (names[1]); @@ -1103,8 +1105,9 @@ find_entry_node (GIrModule *module, goto out; } - g_ir_module_fatal (module, 0, "Type reference '%s' not found", name); - + + g_ir_module_fatal (build, -1, "type reference '%s' not found", + name); out: g_strfreev (names); @@ -1113,101 +1116,77 @@ find_entry_node (GIrModule *module, } static guint16 -find_entry (GIrModule *module, - GList *modules, +find_entry (GIrTypelibBuild *build, const gchar *name) { guint16 idx = 0; - find_entry_node (module, modules, name, &idx); + find_entry_node (build, name, &idx); return idx; } -static GIrNode * -find_name_in_module (GIrModule *module, - const gchar *name) +static GIrModule * +find_namespace (GIrModule *module, + const char *name) { + GIrModule *target; GList *l; + + if (strcmp (module->name, name) == 0) + return module; - for (l = module->entries; l; l = l->next) + for (l = module->include_modules; l; l = l->next) { - GIrNode *node = (GIrNode *)l->data; + GIrModule *submodule = l->data; - if (strcmp (node->name, name) == 0) - return node; + if (strcmp (submodule->name, name) == 0) + return submodule; + + target = find_namespace (submodule, name); + if (target) + return target; } - return NULL; } -gboolean -g_ir_find_node (GIrModule *module, - GList *modules, - const char *name, - GIrNode **node_out, - GIrModule **module_out) +GIrNode * +g_ir_find_node (GIrTypelibBuild *build, + GIrModule *src_module, + const char *name) { + GList *l; + GIrNode *return_node = NULL; char **names = g_strsplit (name, ".", 0); gint n_names = g_strv_length (names); - GIrNode *node = NULL; - GList *l; - - if (n_names == 0) - { - g_warning ("Name can't be empty"); - goto out; - } - - if (n_names > 2) - { - g_warning ("Too many name parts in '%s'", name); - goto out; - } + const char *target_name; + GIrModule *target_module; if (n_names == 1) { - *module_out = module; - node = find_name_in_module (module, names[0]); - } - else if (strcmp (names[0], module->name) == 0) - { - *module_out = module; - node = find_name_in_module (module, names[1]); + target_module = src_module; + target_name = name; } else { - for (l = module->include_modules; l; l = l->next) + target_module = find_namespace (build->module, names[0]); + target_name = names[1]; + } + + for (l = target_module->entries; l; l = l->next) + { + GIrNode *node = (GIrNode *)l->data; + + if (strcmp (node->name, target_name) == 0) { - GIrModule *m = l->data; - - if (strcmp (names[0], m->name) == 0) - { - *module_out = m; - node = find_name_in_module (m, names[1]); - goto out; - } - } - - for (l = modules; l; l = l->next) - { - GIrModule *m = l->data; - - if (strcmp (names[0], m->name) == 0) - { - *module_out = m; - node = find_name_in_module (m, names[1]); - goto out; - } + return_node = node; + break; } } - out: g_strfreev (names); - *node_out = node; - - return node != NULL; + return return_node; } static int @@ -1235,8 +1214,7 @@ get_index_of_member_type (GIrNodeInterface *node, } static void -serialize_type (GIrModule *module, - GList *modules, +serialize_type (GIrTypelibBuild *build, GIrNodeType *node, GString *str) { @@ -1275,7 +1253,7 @@ serialize_type (GIrModule *module, } else if (node->tag == GI_TYPE_TAG_ARRAY) { - serialize_type (module, modules, node->parameter_type1, str); + serialize_type (build, node->parameter_type1, str); g_string_append (str, "["); if (node->has_length) @@ -1294,7 +1272,7 @@ serialize_type (GIrModule *module, GIrNode *iface; gchar *name; - iface = find_entry_node (module, modules, node->interface, NULL); + iface = find_entry_node (build, node->interface, NULL); if (iface) { if (iface->type == G_IR_NODE_XREF) @@ -1316,7 +1294,7 @@ serialize_type (GIrModule *module, if (node->parameter_type1) { g_string_append (str, "<"); - serialize_type (module, modules, node->parameter_type1, str); + serialize_type (build, node->parameter_type1, str); g_string_append (str, ">"); } } @@ -1326,7 +1304,7 @@ serialize_type (GIrModule *module, if (node->parameter_type1) { g_string_append (str, "<"); - serialize_type (module, modules, node->parameter_type1, str); + serialize_type (build, node->parameter_type1, str); g_string_append (str, ">"); } } @@ -1336,9 +1314,9 @@ serialize_type (GIrModule *module, if (node->parameter_type1) { g_string_append (str, "<"); - serialize_type (module, modules, node->parameter_type1, str); + serialize_type (build, node->parameter_type1, str); g_string_append (str, ","); - serialize_type (module, modules, node->parameter_type2, str); + serialize_type (build, node->parameter_type2, str); g_string_append (str, ">"); } } @@ -1421,8 +1399,7 @@ g_ir_node_build_typelib (GIrNode *node, guint32 *offset, guint32 *offset2) { - GIrModule *module = build->module; - GList *modules = build->modules; + gboolean appended_stack; GHashTable *strings = build->strings; GHashTable *types = build->types; guchar *data = build->data; @@ -1437,7 +1414,14 @@ g_ir_node_build_typelib (GIrNode *node, node->name ? " " : "", g_ir_node_type_to_string (node->type)); - g_ir_node_compute_offsets (node, module, modules); + if (build->stack) + appended_stack = node != (GIrNode*)build->stack->data; + else + appended_stack = TRUE; + if (appended_stack) + build->stack = g_list_prepend (build->stack, node); + + g_ir_node_compute_offsets (build, node); /* We should only be building each node once. If we do a typelib expansion, we also * reset the offset in girmodule.c. @@ -1474,7 +1458,7 @@ g_ir_node_build_typelib (GIrNode *node, gpointer value; str = g_string_new (0); - serialize_type (module, modules, type, str); + serialize_type (build, type, str); s = g_string_free (str, FALSE); types_count += 1; @@ -1529,7 +1513,7 @@ g_ir_node_build_typelib (GIrNode *node, iface->reserved = 0; iface->tag = type->tag; iface->reserved2 = 0; - iface->interface = find_entry (module, modules, type->interface); + iface->interface = find_entry (build, type->interface); } break; @@ -1592,7 +1576,7 @@ g_ir_node_build_typelib (GIrNode *node, *offset2 = ALIGN_VALUE (*offset2 + G_STRUCT_OFFSET (ErrorTypeBlob, domains) + 2 * blob->n_domains, 4); for (i = 0; i < blob->n_domains; i++) - blob->domains[i] = find_entry (module, modules, type->errors[i]); + blob->domains[i] = find_entry (build, type->errors[i]); } break; @@ -2121,11 +2105,11 @@ g_ir_node_build_typelib (GIrNode *node, if (object->get_value_func) blob->get_value_func = write_string (object->get_value_func, strings, data, offset2); if (object->parent) - blob->parent = find_entry (module, modules, object->parent); + blob->parent = find_entry (build, object->parent); else blob->parent = 0; if (object->glib_type_struct) - blob->gtype_struct = find_entry (module, modules, object->glib_type_struct); + blob->gtype_struct = find_entry (build, object->glib_type_struct); else blob->gtype_struct = 0; @@ -2141,7 +2125,7 @@ g_ir_node_build_typelib (GIrNode *node, for (l = object->interfaces; l; l = l->next) { blob->n_interfaces++; - *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data); + *(guint16*)&data[*offset] = find_entry (build, (gchar *)l->data); *offset += 2; } @@ -2190,7 +2174,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->gtype_name = write_string (iface->gtype_name, strings, data, offset2); blob->gtype_init = write_string (iface->gtype_init, strings, data, offset2); if (iface->glib_type_struct) - blob->gtype_struct = find_entry (module, modules, iface->glib_type_struct); + blob->gtype_struct = find_entry (build, iface->glib_type_struct); else blob->gtype_struct = 0; blob->n_prerequisites = 0; @@ -2204,7 +2188,7 @@ g_ir_node_build_typelib (GIrNode *node, for (l = iface->prerequisites; l; l = l->next) { blob->n_prerequisites++; - *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data); + *(guint16*)&data[*offset] = find_entry (build, (gchar *)l->data); *offset += 2; } @@ -2261,7 +2245,7 @@ g_ir_node_build_typelib (GIrNode *node, 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->error_codes = find_entry (build, domain->codes); blob->reserved2 = 0; } break; @@ -2352,6 +2336,9 @@ g_ir_node_build_typelib (GIrNode *node, if (*offset2 - old_offset2 + *offset - old_offset > g_ir_node_get_full_size (node)) g_error ("exceeding space reservation; offset: %d (prev %d) offset2: %d (prev %d) nodesize: %d", *offset, old_offset, *offset2, old_offset2, g_ir_node_get_full_size (node)); + + if (appended_stack) + build->stack = g_list_delete_link (build->stack, build->stack); } /* if str is already in the pool, return previous location, otherwise write str diff --git a/girnode.h b/girnode.h index dcd8fa494..edb94008f 100644 --- a/girnode.h +++ b/girnode.h @@ -27,7 +27,6 @@ G_BEGIN_DECLS -typedef struct _GIrTypelibBuild GIrTypelibBuild; typedef struct _GIrNode GIrNode; typedef struct _GIrNodeFunction GIrNodeFunction; typedef struct _GIrNodeParam GIrNodeParam; @@ -46,16 +45,6 @@ typedef struct _GIrNodeErrorDomain GIrNodeErrorDomain; typedef struct _GIrNodeXRef GIrNodeXRef; typedef struct _GIrNodeUnion GIrNodeUnion; -struct _GIrTypelibBuild { - GIrModule *module; - GList *modules; - GHashTable *strings; - GHashTable *types; - GList *nodes_with_attributes; - guint32 n_attributes; - guchar *data; -}; - typedef enum { G_IR_NODE_INVALID = 0, @@ -84,6 +73,7 @@ struct _GIrNode { GIrNodeTypeId type; gchar *name; + GIrModule *module; guint32 offset; /* Assigned as we build the typelib */ @@ -364,7 +354,8 @@ struct _GIrNodeErrorDomain }; -GIrNode * g_ir_node_new (GIrNodeTypeId type); +GIrNode * g_ir_node_new (GIrNodeTypeId type, + GIrModule *module); void g_ir_node_free (GIrNode *node); guint32 g_ir_node_get_size (GIrNode *node); guint32 g_ir_node_get_full_size (GIrNode *node); @@ -386,17 +377,14 @@ guint32 write_string (const gchar *str, const gchar * g_ir_node_param_direction_string (GIrNodeParam * node); const gchar * g_ir_node_type_to_string (GIrNodeTypeId type); -gboolean g_ir_find_node (GIrModule *module, - GList *modules, - const char *name, - GIrNode **node_out, - GIrModule **module_out); +GIrNode *g_ir_find_node (GIrTypelibBuild *build, + GIrModule *module, + const char *name); /* In giroffsets.c */ -void g_ir_node_compute_offsets (GIrNode *node, - GIrModule *module, - GList *modules); +void g_ir_node_compute_offsets (GIrTypelibBuild *build, + GIrNode *node); G_END_DECLS diff --git a/giroffsets.c b/giroffsets.c index 5d481da15..bcac716c3 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -20,6 +20,7 @@ #include "girepository-private.h" #include "girnode.h" +#include /* The C standard specifies that an enumeration can be any char or any signed * or unsigned integer type capable of resresenting all the values of the @@ -144,26 +145,24 @@ get_enum_size_alignment (GIrNodeEnum *enum_node, } static gboolean -get_interface_size_alignment (GIrNodeType *type, - GIrModule *module, - GList *modules, +get_interface_size_alignment (GIrTypelibBuild *build, + GIrNodeType *type, gint *size, gint *alignment, const char *who) { GIrNode *iface; - GIrModule *iface_module; - if (!g_ir_find_node (module, modules, type->interface, &iface, &iface_module)) + iface = g_ir_find_node (build, ((GIrNode*)type)->module, type->interface); + if (!iface) { - g_ir_module_fatal (module, 0, "Can't resolve type '%s' for %s", type->interface, who); + g_ir_module_fatal (build, 0, "Can't resolve type '%s' for %s", type->interface, who); *size = -1; *alignment = -1; return FALSE; } - g_ir_node_compute_offsets (iface, iface_module, - iface_module == module ? modules : NULL); + g_ir_node_compute_offsets (build, iface); switch (iface->type) { @@ -223,9 +222,8 @@ get_interface_size_alignment (GIrNodeType *type, } static gboolean -get_type_size_alignment (GIrNodeType *type, - GIrModule *module, - GList *modules, +get_type_size_alignment (GIrTypelibBuild *build, + GIrNodeType *type, gint *size, gint *alignment, const char *who) @@ -241,7 +239,7 @@ get_type_size_alignment (GIrNodeType *type, gint elt_size, elt_alignment; if (!type->has_size - || !get_type_size_alignment(type->parameter_type1, module, modules, + || !get_type_size_alignment(build, type->parameter_type1, &elt_size, &elt_alignment, who)) { *size = -1; @@ -258,7 +256,7 @@ get_type_size_alignment (GIrNodeType *type, { if (type->tag == GI_TYPE_TAG_INTERFACE) { - return get_interface_size_alignment (type, module, modules, size, alignment, who); + return get_interface_size_alignment (build, type, size, alignment, who); } else { @@ -291,13 +289,13 @@ get_type_size_alignment (GIrNodeType *type, } static gboolean -get_field_size_alignment (GIrNodeField *field, +get_field_size_alignment (GIrTypelibBuild *build, + GIrNodeField *field, GIrNode *parent_node, - GIrModule *module, - GList *modules, gint *size, gint *alignment) { + GIrModule *module = build->module; gchar *who; gboolean success; @@ -310,7 +308,7 @@ get_field_size_alignment (GIrNodeField *field, success = TRUE; } else - success = get_type_size_alignment (field->type, module, modules, size, alignment, who); + success = get_type_size_alignment (build, field->type, size, alignment, who); g_free (who); return success; @@ -319,10 +317,9 @@ get_field_size_alignment (GIrNodeField *field, #define ALIGN(n, align) (((n) + (align) - 1) & ~((align) - 1)) static gboolean -compute_struct_field_offsets (GIrNode *node, +compute_struct_field_offsets (GIrTypelibBuild *build, + GIrNode *node, GList *members, - GIrModule *module, - GList *modules, gint *size_out, gint *alignment_out) { @@ -346,8 +343,7 @@ compute_struct_field_offsets (GIrNode *node, int member_size; int member_alignment; - if (get_field_size_alignment (field, node, - module, modules, + if (get_field_size_alignment (build, field, node, &member_size, &member_alignment)) { size = ALIGN (size, member_alignment); @@ -388,10 +384,9 @@ compute_struct_field_offsets (GIrNode *node, } static gboolean -compute_union_field_offsets (GIrNode *node, +compute_union_field_offsets (GIrTypelibBuild *build, + GIrNode *node, GList *members, - GIrModule *module, - GList *modules, gint *size_out, gint *alignment_out) { @@ -415,8 +410,7 @@ compute_union_field_offsets (GIrNode *node, int member_size; int member_alignment; - if (get_field_size_alignment (field, node, - module, modules, + if (get_field_size_alignment (build,field, node, &member_size, &member_alignment)) { size = MAX (size, member_size); @@ -446,10 +440,11 @@ compute_union_field_offsets (GIrNode *node, } static gboolean -check_needs_computation (GIrNode *node, - GIrModule *module, +check_needs_computation (GIrTypelibBuild *build, + GIrNode *node, gint alignment) { + GIrModule *module = build->module; /* * 0: Not yet computed * >0: Previously succeeded @@ -467,30 +462,36 @@ check_needs_computation (GIrNode *node, /** * g_ir_node_compute_offsets: + * @build: Current typelib build * @node: a #GIrNode - * @module: Current module being processed - * @modules: all currently loaded modules * * If a node is a a structure or union, makes sure that the field * offsets have been computed, and also computes the overall size and * alignment for the type. */ void -g_ir_node_compute_offsets (GIrNode *node, - GIrModule *module, - GList *modules) +g_ir_node_compute_offsets (GIrTypelibBuild *build, + GIrNode *node) { + gboolean appended_stack; + + if (build->stack) + appended_stack = node != (GIrNode*)build->stack->data; + else + appended_stack = TRUE; + if (appended_stack) + build->stack = g_list_prepend (build->stack, node); + switch (node->type) { case G_IR_NODE_BOXED: { GIrNodeBoxed *boxed = (GIrNodeBoxed *)node; - if (!check_needs_computation (node, module, boxed->alignment)) + if (!check_needs_computation (build, node, boxed->alignment)) return; - compute_struct_field_offsets (node, boxed->members, - module, modules, + compute_struct_field_offsets (build, node, boxed->members, &boxed->size, &boxed->alignment); break; } @@ -498,11 +499,10 @@ g_ir_node_compute_offsets (GIrNode *node, { GIrNodeStruct *struct_ = (GIrNodeStruct *)node; - if (!check_needs_computation (node, module, struct_->alignment)) + if (!check_needs_computation (build, node, struct_->alignment)) return; - compute_struct_field_offsets (node, struct_->members, - module, modules, + compute_struct_field_offsets (build, node, struct_->members, &struct_->size, &struct_->alignment); break; } @@ -511,11 +511,10 @@ g_ir_node_compute_offsets (GIrNode *node, { GIrNodeInterface *iface = (GIrNodeInterface *)node; - if (!check_needs_computation (node, module, iface->alignment)) + if (!check_needs_computation (build, node, iface->alignment)) return; - compute_struct_field_offsets (node, iface->members, - module, modules, + compute_struct_field_offsets (build, node, iface->members, &iface->size, &iface->alignment); break; } @@ -523,11 +522,10 @@ g_ir_node_compute_offsets (GIrNode *node, { GIrNodeUnion *union_ = (GIrNodeUnion *)node; - if (!check_needs_computation (node, module, union_->alignment)) + if (!check_needs_computation (build, node, union_->alignment)) return; - compute_union_field_offsets (node, union_->members, - module, modules, + compute_union_field_offsets (build, (GIrNode*)union_, union_->members, &union_->size, &union_->alignment); break; } @@ -544,7 +542,9 @@ g_ir_node_compute_offsets (GIrNode *node, break; } default: - /* Nothing to do */ - return; + break; } + + if (appended_stack) + build->stack = g_list_delete_link (build->stack, build->stack); } diff --git a/girparser.c b/girparser.c index 11576e913..ae1e625d0 100644 --- a/girparser.c +++ b/girparser.c @@ -324,7 +324,8 @@ push_node (ParseContext *ctx, GIrNode *node) ctx->node_stack = g_slist_prepend (ctx->node_stack, node); } -static GIrNodeType * parse_type_internal (const gchar *str, gchar **next, gboolean in_glib, +static GIrNodeType * parse_type_internal (GIrModule *module, + const gchar *str, gchar **next, gboolean in_glib, gboolean in_gobject); typedef struct { @@ -423,14 +424,15 @@ parse_basic (const char *str) } static GIrNodeType * -parse_type_internal (const gchar *str, char **next, gboolean in_glib, +parse_type_internal (GIrModule *module, + const gchar *str, char **next, gboolean in_glib, gboolean in_gobject) { const BasicTypeInfo *basic; GIrNodeType *type; char *temporary_type = NULL; - type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE); + type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE, module); type->unparsed = g_strdup (str); @@ -644,7 +646,7 @@ parse_type (ParseContext *ctx, const gchar *type) if (basic == NULL) type = resolve_aliases (ctx, type); - node = parse_type_internal (type, NULL, in_glib, in_gobject); + node = parse_type_internal (ctx->current_module, type, NULL, in_glib, in_gobject); if (node) g_debug ("Parsed type: %s => %d", type, node->tag); else @@ -721,7 +723,8 @@ start_glib_boxed (GMarkupParseContext *context, return FALSE; } - boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED); + boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED, + ctx->current_module); ((GIrNode *)boxed)->name = g_strdup (name); boxed->gtype_name = g_strdup (typename); @@ -804,7 +807,8 @@ start_function (GMarkupParseContext *context, return FALSE; } - function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION); + function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION, + ctx->current_module); ((GIrNode *)function)->name = g_strdup (name); function->symbol = g_strdup (symbol); @@ -1005,7 +1009,8 @@ start_parameter (GMarkupParseContext *context, if (name == NULL) name = "unknown"; - param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM); + param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM, + ctx->current_module); ctx->current_typed = (GIrNode*) param; ctx->current_typed->name = g_strdup (name); @@ -1141,7 +1146,8 @@ start_field (GMarkupParseContext *context, return FALSE; } - field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD); + field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD, + ctx->current_module); ctx->current_typed = (GIrNode*) field; ((GIrNode *)field)->name = g_strdup (name); /* Fields are assumed to be read-only. @@ -1203,7 +1209,8 @@ start_field (GMarkupParseContext *context, { GIrNodeConstant *constant; - constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT); + constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT, + ctx->current_module); ((GIrNode *)constant)->name = g_strdup (name); constant->value = g_strdup (branch); constant->type = union_->discriminator_type; @@ -1298,9 +1305,11 @@ start_enum (GMarkupParseContext *context, } if (strcmp (element_name, "enumeration") == 0) - enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM); + enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM, + ctx->current_module); else - enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS); + enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS, + ctx->current_module); ((GIrNode *)enum_)->name = g_strdup (name); enum_->gtype_name = g_strdup (typename); enum_->gtype_init = g_strdup (typeinit); @@ -1363,7 +1372,8 @@ start_property (GMarkupParseContext *context, return FALSE; } - property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY); + property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY, + ctx->current_module); ctx->current_typed = (GIrNode*) property; ((GIrNode *)property)->name = g_strdup (name); @@ -1445,7 +1455,8 @@ start_member (GMarkupParseContext *context, return FALSE; } - value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE); + value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE, + ctx->current_module); ((GIrNode *)value_)->name = g_strdup (name); @@ -1518,7 +1529,8 @@ start_constant (GMarkupParseContext *context, return FALSE; } - constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT); + constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT, + ctx->current_module); ((GIrNode *)constant)->name = g_strdup (name); constant->value = g_strdup (value); @@ -1590,7 +1602,8 @@ start_errordomain (GMarkupParseContext *context, return FALSE; } - domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN); + domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN, + ctx->current_module); ((GIrNode *)domain)->name = g_strdup (name); domain->getquark = g_strdup (getquark); @@ -1652,7 +1665,8 @@ start_interface (GMarkupParseContext *context, return FALSE; } - iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE); + iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE, + ctx->current_module); ((GIrNode *)iface)->name = g_strdup (name); iface->gtype_name = g_strdup (typename); iface->gtype_init = g_strdup (typeinit); @@ -1727,7 +1741,8 @@ start_class (GMarkupParseContext *context, return FALSE; } - iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT); + iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT, + ctx->current_module); ((GIrNode *)iface)->name = g_strdup (name); iface->gtype_name = g_strdup (typename); iface->gtype_init = g_strdup (typeinit); @@ -1820,7 +1835,8 @@ start_type (GMarkupParseContext *context, const char *len; const char *size; - typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE); + typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE, + ctx->current_module); typenode->tag = GI_TYPE_TAG_ARRAY; typenode->is_pointer = TRUE; @@ -1870,7 +1886,10 @@ start_type (GMarkupParseContext *context, name = find_attribute ("name", attribute_names, attribute_values); if (name == NULL) - MISSING_ATTRIBUTE (context, error, element_name, "name"); + { + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; + } pointer_depth = 0; ctype = find_attribute ("c:type", attribute_names, attribute_values); @@ -2097,7 +2116,8 @@ start_return_value (GMarkupParseContext *context, ctx->state == STATE_FUNCTION)) return FALSE; - param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM); + param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM, + ctx->current_module); param->in = FALSE; param->out = FALSE; param->retval = TRUE; @@ -2206,7 +2226,8 @@ start_glib_signal (GMarkupParseContext *context, MISSING_ATTRIBUTE (context, error, element_name, "name"); return FALSE; } - signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL); + signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL, + ctx->current_module); ((GIrNode *)signal)->name = g_strdup (name); @@ -2287,7 +2308,8 @@ start_vfunc (GMarkupParseContext *context, return FALSE; } - vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC); + vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC, + ctx->current_module); ((GIrNode *)vfunc)->name = g_strdup (name); @@ -2383,7 +2405,8 @@ start_struct (GMarkupParseContext *context, return FALSE; } - struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT); + struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT, + ctx->current_module); ((GIrNode *)struct_)->name = g_strdup (name ? name : ""); if (deprecated) @@ -2443,7 +2466,8 @@ start_union (GMarkupParseContext *context, return FALSE; } - union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION); + union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION, + ctx->current_module); ((GIrNode *)union_)->name = g_strdup (name ? name : ""); union_->gtype_name = g_strdup (typename); @@ -2505,7 +2529,7 @@ parse_include (GMarkupParseContext *context, gchar *buffer; gsize length; gchar *girpath, *girname; - GList *modules; + GIrModule *module; GList *l; for (l = ctx->parser->parsed_modules; l; l = l->next) @@ -2541,7 +2565,7 @@ parse_include (GMarkupParseContext *context, } g_free (girname); - g_debug ("Parsing include %s", girpath); + g_debug ("Parsing include %s\n", girpath); if (!g_file_get_contents (girpath, &buffer, &length, &error)) { @@ -2551,7 +2575,7 @@ parse_include (GMarkupParseContext *context, return FALSE; } - modules = g_ir_parser_parse_string (ctx->parser, name, girpath, buffer, length, &error); + module = g_ir_parser_parse_string (ctx->parser, name, girpath, buffer, length, &error); g_free (buffer); if (error != NULL) { @@ -2564,8 +2588,8 @@ parse_include (GMarkupParseContext *context, } g_free (girpath); - ctx->include_modules = g_list_concat (ctx->include_modules, - modules); + ctx->include_modules = g_list_append (ctx->include_modules, + module); return TRUE; } @@ -3357,10 +3381,9 @@ cleanup (GMarkupParseContext *context, * Parse a string that holds a complete GIR XML file, and return a list of a * a #GirModule for each <namespace/> element within the file. * - * Returns: (transfer container): a newly allocated list of #GIrModule. The modules themselves - * are owned by the #GIrParser and will be freed along with the parser. + * Returns: (transfer none): a new #GirModule */ -GList * +GIrModule * g_ir_parser_parse_string (GIrParser *parser, const gchar *namespace, const gchar *filename, @@ -3418,7 +3441,7 @@ g_ir_parser_parse_string (GIrParser *parser, g_markup_parse_context_free (context); - return ctx.modules; + return ctx.modules->data; } /** @@ -3433,14 +3456,14 @@ g_ir_parser_parse_string (GIrParser *parser, * Returns: (transfer container): a newly allocated list of #GIrModule. The modules themselves * are owned by the #GIrParser and will be freed along with the parser. */ -GList * +GIrModule * g_ir_parser_parse_file (GIrParser *parser, const gchar *filename, GError **error) { gchar *buffer; gsize length; - GList *modules; + GIrModule *module; const char *slash; char *dash; char *namespace; @@ -3471,13 +3494,13 @@ g_ir_parser_parse_file (GIrParser *parser, if (!g_file_get_contents (filename, &buffer, &length, error)) return NULL; - modules = g_ir_parser_parse_string (parser, namespace, filename, buffer, length, error); + module = g_ir_parser_parse_string (parser, namespace, filename, buffer, length, error); g_free (namespace); g_free (buffer); - return modules; + return module; } diff --git a/girparser.h b/girparser.h index 6fca1b3da..076c9818b 100644 --- a/girparser.h +++ b/girparser.h @@ -25,6 +25,8 @@ G_BEGIN_DECLS +#include "girmodule.h" + typedef struct _GIrParser GIrParser; GIrParser *g_ir_parser_new (void); @@ -32,15 +34,15 @@ void g_ir_parser_free (GIrParser *parser); void g_ir_parser_set_includes (GIrParser *parser, const gchar *const *includes); -GList *g_ir_parser_parse_string (GIrParser *parser, - const gchar *namespace, - const gchar *filename, - const gchar *buffer, - gssize length, - GError **error); -GList *g_ir_parser_parse_file (GIrParser *parser, - const gchar *filename, - GError **error); +GIrModule *g_ir_parser_parse_string (GIrParser *parser, + const gchar *namespace, + const gchar *filename, + const gchar *buffer, + gssize length, + GError **error); +GIrModule *g_ir_parser_parse_file (GIrParser *parser, + const gchar *filename, + GError **error); G_END_DECLS From 2b07f1ed31bcc6a404d75bad7eb88e698d3eeead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steve=20Fr=C3=A9cinaux?= Date: Mon, 16 Aug 2010 22:39:19 +0200 Subject: [PATCH 374/692] Include the loaded version in g_irepository_enumerate_versions() Logically speaking, the already loaded version of a namespace is part of the currently available versions, and can be forgotten if we only consider the versions available in GI_TYPELIB_PATH, as it could have been loaded using g_irepository_require_private(). As a side effect, it meant that bindings relying on enumerate_version() (like pygobject) were not able to require private versions through their classical requirement scheme. This patch fixes it by adding the loaded version to the unsorted list of available versions returned by g_irepository_enumerate_versions() This patch also uses g_list_prepend() instead of g_list_append() in that function. https://bugzilla.gnome.org/show_bug.cgi?id=625983 --- girepository.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/girepository.c b/girepository.c index 17d076d5b..96a23e6fe 100644 --- a/girepository.c +++ b/girepository.c @@ -1166,7 +1166,8 @@ find_namespace_latest (const gchar *namespace, * @repository: (allow-none): the repository * @namespace_: GI namespace, e.g. "Gtk" * - * Obtain a list of versions for @namespace_ in this @repository. + * Obtain an unordered list of versions (either currently loaded or + * available) for @namespace_ in this @repository. * * Returns: (element-type utf8) (transfer full): the array of versions. */ @@ -1177,6 +1178,7 @@ g_irepository_enumerate_versions (GIRepository *repository, GList *ret = NULL; GSList *search_path; GSList *candidates, *link; + const gchar *loaded_version; search_path = build_search_path_with_overrides (); candidates = enumerate_namespace_versions (namespace_, search_path); @@ -1185,10 +1187,19 @@ g_irepository_enumerate_versions (GIRepository *repository, for (link = candidates; link; link = link->next) { struct NamespaceVersionCandidadate *candidate = link->data; - ret = g_list_append (ret, g_strdup (candidate->version)); + ret = g_list_prepend (ret, g_strdup (candidate->version)); free_candidate (candidate); } g_slist_free (candidates); + + /* The currently loaded version of a namespace is also part of the + * available versions, as it could have been loaded using + * require_private(). + */ + loaded_version = g_irepository_get_version (NULL, namespace_); + if (loaded_version && !g_list_find_custom (ret, loaded_version, g_str_equal)) + ret = g_list_prepend (ret, g_strdup (loaded_version)); + return ret; } From 318843cead68edf07381046da72ff52c1fc8e31b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steve=20Fr=C3=A9cinaux?= Date: Wed, 18 Aug 2010 22:26:48 +0200 Subject: [PATCH 375/692] Fix warning when using g_irepository_enumerate_version() The reason for the warning was that g_irepository_get_version() expects the typelib to be already loaded, but enumerate_version() can be called on typelibs that are not. --- girepository.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/girepository.c b/girepository.c index 96a23e6fe..288055ce2 100644 --- a/girepository.c +++ b/girepository.c @@ -1196,9 +1196,12 @@ g_irepository_enumerate_versions (GIRepository *repository, * available versions, as it could have been loaded using * require_private(). */ - loaded_version = g_irepository_get_version (NULL, namespace_); - if (loaded_version && !g_list_find_custom (ret, loaded_version, g_str_equal)) - ret = g_list_prepend (ret, g_strdup (loaded_version)); + if (g_irepository_is_registered (repository, namespace_, NULL)) + { + loaded_version = g_irepository_get_version (repository, namespace_); + if (loaded_version && !g_list_find_custom (ret, loaded_version, g_str_equal)) + ret = g_list_prepend (ret, g_strdup (loaded_version)); + } return ret; } From d853f196c10f8aff6fa53bb398e2acb0233085f6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 3 Aug 2010 13:01:35 -0400 Subject: [PATCH 376/692] Move alias target to This makes type parsing more uniform. Delete the typedef for GSList in foo.h - that's not supported anymore, or at least for now. --- girparser.c | 99 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 72 insertions(+), 27 deletions(-) diff --git a/girparser.c b/girparser.c index ae1e625d0..17ed6b541 100644 --- a/girparser.c +++ b/girparser.c @@ -101,6 +101,7 @@ struct _ParseContext const char *c_prefix; GIrModule *current_module; GSList *node_stack; + char *current_alias; GIrNode *current_typed; GList *type_stack; GList *type_parameters; @@ -127,6 +128,8 @@ static void text_handler (GMarkupParseContext *context, static void cleanup (GMarkupParseContext *context, GError *error, gpointer user_data); +static void state_switch (ParseContext *ctx, ParseState newstate); + static GMarkupParser markup_parser = { @@ -144,6 +147,13 @@ start_alias (GMarkupParseContext *context, const gchar **attribute_values, ParseContext *ctx, GError **error); +static gboolean +start_type (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error); static const gchar *find_attribute (const gchar *name, const gchar **attribute_names, @@ -197,6 +207,11 @@ firstpass_start_element_handler (GMarkupParseContext *context, start_alias (context, element_name, attribute_names, attribute_values, ctx, error); } + else if (ctx->state == STATE_ALIAS && strcmp (element_name, "type") == 0) + { + start_type (context, element_name, attribute_names, attribute_values, + ctx, error); + } else if (strcmp (element_name, "record") == 0) { const gchar *name; @@ -221,6 +236,15 @@ firstpass_end_element_handler (GMarkupParseContext *context, gpointer user_data, GError **error) { + ParseContext *ctx = user_data; + if (strcmp (element_name, "alias") == 0) + { + state_switch (ctx, STATE_NAMESPACE); + g_free (ctx->current_alias); + ctx->current_alias = NULL; + } + else if (strcmp (element_name, "type") == 0 && ctx->state == STATE_TYPE) + state_switch (ctx, ctx->prev_state); } static GMarkupParser firstpass_parser = @@ -1237,9 +1261,6 @@ start_alias (GMarkupParseContext *context, GError **error) { const gchar *name; - const gchar *target; - char *key; - char *value; name = find_attribute ("name", attribute_names, attribute_values); if (name == NULL) @@ -1248,26 +1269,8 @@ start_alias (GMarkupParseContext *context, return FALSE; } - target = find_attribute ("target", attribute_names, attribute_values); - if (name == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "target"); - return FALSE; - } - - value = g_strdup (target); - key = g_strdup_printf ("%s.%s", ctx->namespace, name); - if (!strchr (target, '.')) - { - const BasicTypeInfo *basic = parse_basic (target); - if (!basic) - { - g_free (value); - /* For non-basic types, re-qualify the interface */ - value = g_strdup_printf ("%s.%s", ctx->namespace, target); - } - } - g_hash_table_replace (ctx->aliases, key, value); + ctx->current_alias = g_strdup (name); + state_switch (ctx, STATE_ALIAS); return TRUE; } @@ -1781,6 +1784,7 @@ start_type (GMarkupParseContext *context, { const gchar *name; const gchar *ctype; + gboolean in_alias = FALSE; gboolean is_array; gboolean is_varargs; GIrNodeType *typenode; @@ -1808,15 +1812,55 @@ start_type (GMarkupParseContext *context, ctx->state == STATE_BOXED_FIELD || ctx->state == STATE_NAMESPACE_CONSTANT || ctx->state == STATE_CLASS_CONSTANT || - ctx->state == STATE_INTERFACE_CONSTANT + ctx->state == STATE_INTERFACE_CONSTANT || + ctx->state == STATE_ALIAS ) { + if (ctx->state == STATE_ALIAS) + in_alias = TRUE; state_switch (ctx, STATE_TYPE); ctx->type_depth = 1; ctx->type_stack = NULL; ctx->type_parameters = NULL; } + name = find_attribute ("name", attribute_names, attribute_values); + + if (in_alias && ctx->current_alias) + { + char *key; + char *value; + + if (name == NULL) + { + MISSING_ATTRIBUTE (context, error, element_name, "name"); + return FALSE; + } + + key = g_strdup_printf ("%s.%s", ctx->namespace, ctx->current_alias); + if (!strchr (name, '.')) + { + const BasicTypeInfo *basic = parse_basic (name); + if (!basic) + { + /* For non-basic types, re-qualify the interface */ + value = g_strdup_printf ("%s.%s", ctx->namespace, name); + } + else + { + value = g_strdup (name); + } + } + else + value = g_strdup (name); + + g_hash_table_replace (ctx->aliases, key, value); + + return TRUE; + } + else if (!ctx->current_module || in_alias) + return TRUE; + if (!ctx->current_typed) { g_set_error (error, @@ -1842,7 +1886,6 @@ start_type (GMarkupParseContext *context, typenode->is_pointer = TRUE; typenode->is_array = TRUE; - name = find_attribute ("name", attribute_names, attribute_values); if (name && strcmp (name, "GLib.Array") == 0) { typenode->array_type = GI_ARRAY_TYPE_ARRAY; } else if (name && strcmp (name, "GLib.ByteArray") == 0) { @@ -1883,7 +1926,6 @@ start_type (GMarkupParseContext *context, else { int pointer_depth; - name = find_attribute ("name", attribute_names, attribute_values); if (name == NULL) { @@ -2933,7 +2975,7 @@ start_element_handler (GMarkupParseContext *context, break; } - if (ctx->state != STATE_PASSTHROUGH) + if (*error == NULL && ctx->state != STATE_PASSTHROUGH) { g_markup_parse_context_get_position (context, &line_number, &char_number); if (!g_str_has_prefix (element_name, "c:")) @@ -3088,6 +3130,8 @@ end_element_handler (GMarkupParseContext *context, case STATE_ALIAS: if (require_end_element (context, ctx, "alias", element_name, error)) { + g_free (ctx->current_alias); + ctx->current_alias = NULL; state_switch (ctx, STATE_NAMESPACE); } break; @@ -3415,6 +3459,7 @@ g_ir_parser_parse_string (GIrParser *parser, g_markup_parse_context_free (context); + ctx.state = STATE_START; context = g_markup_parse_context_new (&markup_parser, 0, &ctx, NULL); if (!g_markup_parse_context_parse (context, buffer, length, error)) goto out; From f5ec6f66981b432f1e77c8e1ed17c997978b3067 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 21 Jul 2010 21:06:17 -0400 Subject: [PATCH 377/692] Use GLib types consistently Rather than have the scanner/parser handle both e.g. "glong" and "long", simply use the GLib types everywhere. This commit adds TYPE_LONG_LONG and TYPE_LONG_DOUBLE to the scanner types; however, rather than add them to the typelib, they're just marked as not-introspectable. --- girepository.c | 22 ++++++++++---------- girnode.c | 28 +------------------------ girparser.c | 56 +++++++++++++++++++++++++------------------------- 3 files changed, 40 insertions(+), 66 deletions(-) diff --git a/girepository.c b/girepository.c index 288055ce2..689957469 100644 --- a/girepository.c +++ b/girepository.c @@ -1445,27 +1445,27 @@ g_type_tag_to_string (GITypeTag type) case GI_TYPE_TAG_VOID: return "void"; case GI_TYPE_TAG_BOOLEAN: - return "boolean"; + return "gboolean"; case GI_TYPE_TAG_INT8: - return "int8"; + return "gint8"; case GI_TYPE_TAG_UINT8: - return "uint8"; + return "guint8"; case GI_TYPE_TAG_INT16: - return "int16"; + return "gint16"; case GI_TYPE_TAG_UINT16: - return "uint16"; + return "guint16"; case GI_TYPE_TAG_INT32: - return "int32"; + return "gint32"; case GI_TYPE_TAG_UINT32: - return "uint32"; + return "guint32"; case GI_TYPE_TAG_INT64: - return "int64"; + return "gint64"; case GI_TYPE_TAG_UINT64: - return "uint64"; + return "guint64"; case GI_TYPE_TAG_FLOAT: - return "float"; + return "gfloat"; case GI_TYPE_TAG_DOUBLE: - return "double"; + return "gdouble"; case GI_TYPE_TAG_GTYPE: return "GType"; case GI_TYPE_TAG_UTF8: diff --git a/girnode.c b/girnode.c index b35c745ee..2f6a27090 100644 --- a/girnode.c +++ b/girnode.c @@ -1219,36 +1219,10 @@ serialize_type (GIrTypelibBuild *build, GString *str) { gint i; - const gchar* basic[] = { - "void", - "boolean", - "int8", - "uint8", - "int16", - "uint16", - "int32", - "uint32", - "int64", - "uint64", - "short", - "ushort", - "int", - "uint", - "long", - "ulong", - "ssize", - "size", - "float", - "double", - "time_t", - "GType", - "utf8", - "filename", - }; if (node->tag < GI_TYPE_TAG_ARRAY) { - g_string_append_printf (str, "%s%s", basic[node->tag], + g_string_append_printf (str, "%s%s", g_type_tag_to_string (node->tag), node->is_pointer ? "*" : ""); } else if (node->tag == GI_TYPE_TAG_ARRAY) diff --git a/girparser.c b/girparser.c index 17ed6b541..570e64886 100644 --- a/girparser.c +++ b/girparser.c @@ -359,13 +359,13 @@ typedef struct { } IntegerAliasInfo; static IntegerAliasInfo integer_aliases[] = { - { "char", SIZEOF_CHAR, 0 }, - { "short", SIZEOF_SHORT, 1 }, - { "ushort", SIZEOF_SHORT, 0 }, - { "int", SIZEOF_INT, 1 }, - { "uint", SIZEOF_INT, 0 }, - { "long", SIZEOF_LONG, 1 }, - { "ulong", SIZEOF_LONG, 0 }, + { "gchar", SIZEOF_CHAR, 0 }, + { "gshort", SIZEOF_SHORT, 1 }, + { "gushort", SIZEOF_SHORT, 0 }, + { "gint", SIZEOF_INT, 1 }, + { "guint", SIZEOF_INT, 0 }, + { "glong", SIZEOF_LONG, 1 }, + { "gulong", SIZEOF_LONG, 0 }, { "gsize", GLIB_SIZEOF_SIZE_T, 0 }, { "gssize", GLIB_SIZEOF_SIZE_T, 1 }, }; @@ -379,30 +379,30 @@ typedef struct { #define BASIC_TYPE_FIXED_OFFSET 3 static BasicTypeInfo basic_types[] = { - { "none", GI_TYPE_TAG_VOID, 0 }, - { "any", GI_TYPE_TAG_VOID, 1 }, + { "none", GI_TYPE_TAG_VOID, 0 }, + { "gpointer", GI_TYPE_TAG_VOID, 1 }, - { "bool", GI_TYPE_TAG_BOOLEAN, 0 }, - { "int8", GI_TYPE_TAG_INT8, 0 }, /* Start of BASIC_TYPE_FIXED_OFFSET */ - { "uint8", GI_TYPE_TAG_UINT8, 0 }, - { "int16", GI_TYPE_TAG_INT16, 0 }, - { "uint16", GI_TYPE_TAG_UINT16, 0 }, - { "int32", GI_TYPE_TAG_INT32, 0 }, - { "uint32", GI_TYPE_TAG_UINT32, 0 }, - { "int64", GI_TYPE_TAG_INT64, 0 }, - { "uint64", GI_TYPE_TAG_UINT64, 0 }, - { "float", GI_TYPE_TAG_FLOAT, 0 }, - { "double", GI_TYPE_TAG_DOUBLE, 0 }, - { "GType", GI_TYPE_TAG_GTYPE, 0 }, - { "utf8", GI_TYPE_TAG_UTF8, 1 }, - { "filename", GI_TYPE_TAG_FILENAME,1 }, + { "gboolean", GI_TYPE_TAG_BOOLEAN, 0 }, + { "gint8", GI_TYPE_TAG_INT8, 0 }, /* Start of BASIC_TYPE_FIXED_OFFSET */ + { "guint8", GI_TYPE_TAG_UINT8, 0 }, + { "gint16", GI_TYPE_TAG_INT16, 0 }, + { "guint16", GI_TYPE_TAG_UINT16, 0 }, + { "gint32", GI_TYPE_TAG_INT32, 0 }, + { "guint32", GI_TYPE_TAG_UINT32, 0 }, + { "gint64", GI_TYPE_TAG_INT64, 0 }, + { "guint64", GI_TYPE_TAG_UINT64, 0 }, + { "gfloat", GI_TYPE_TAG_FLOAT, 0 }, + { "gdouble", GI_TYPE_TAG_DOUBLE, 0 }, + { "GType", GI_TYPE_TAG_GTYPE, 0 }, + { "utf8", GI_TYPE_TAG_UTF8, 1 }, + { "filename", GI_TYPE_TAG_FILENAME,1 }, }; static const BasicTypeInfo * parse_basic (const char *str) { - gint i; - gint n_basic = G_N_ELEMENTS (basic_types); + guint i; + guint n_basic = G_N_ELEMENTS (basic_types); for (i = 0; i < n_basic; i++) { @@ -1981,14 +1981,14 @@ end_type_top (ParseContext *ctx) typenode->tag == GI_TYPE_TAG_GSLIST) { if (typenode->parameter_type1 == NULL) - typenode->parameter_type1 = parse_type (ctx, "any"); + typenode->parameter_type1 = parse_type (ctx, "gpointer"); } else if (typenode->tag == GI_TYPE_TAG_GHASH) { if (typenode->parameter_type1 == NULL) { - typenode->parameter_type1 = parse_type (ctx, "any"); - typenode->parameter_type2 = parse_type (ctx, "any"); + typenode->parameter_type1 = parse_type (ctx, "gpointer"); + typenode->parameter_type2 = parse_type (ctx, "gpointer"); } } From 35cb08a25e0d57b784894b0f14c4210445700385 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 27 Jul 2010 06:16:37 -0400 Subject: [PATCH 378/692] Major rewrite One of the first big changes in this rewrite is changing the Type object to have separate target_fundamental and target_giname properties, rather than just being strings. Previously in the scanner, it was awful because we used heuristics around strings. The ast.py is refactored so that not everything is a Node - that was a rather useless abstraction. Now, only things which can have a GIName are Node. E.g. Type and Field are no longer Node. More things were merged from glibast.py into ast.py, since it isn't a very useful split. transformer.py gains more intelligence and will e.g. turn GLib.List into a List() object earlier. The namespace processing is a lot cleaner now; since we parse the included .girs, we know the C prefix for each namespace, and have functions to parse both C type names (GtkFooBar) and symbols gtk_foo_bar into their symbols cleanly. Type resolution is much, much saner because we know Type(target_giname=Gtk.Foo) maps to the namespace Gtk. glibtransformer.py now just handles the XML processing from the dump, and a few miscellaneous things. The major heavy lifting now lives in primarytransformer.py, which is a combination of most of annotationparser.py and half of glibtransformer.py. annotationparser.py now literally just parses annotations; it's no longer in the business of e.g. guessing transfer too. finaltransformer.py is a new file which does post-analysis for "introspectability" mainly. girparser.c is fixed for some introspectable=0 processing. --- girmodule.c | 2 +- girparser.c | 109 ++++++++++++++++++++++++++++++++++------------------ gitypelib.c | 4 +- 3 files changed, 74 insertions(+), 41 deletions(-) diff --git a/girmodule.c b/girmodule.c index 70b1d2a81..ebee26c5d 100644 --- a/girmodule.c +++ b/girmodule.c @@ -309,7 +309,7 @@ g_ir_module_build_typelib (GIrModule *module) /* fill in header */ header = (Header *)data; memcpy (header, G_IR_MAGIC, 16); - header->major_version = 3; + header->major_version = 4; header->minor_version = 0; header->reserved = 0; header->n_entries = n_entries; diff --git a/girparser.c b/girparser.c index 570e64886..bdb878111 100644 --- a/girparser.c +++ b/girparser.c @@ -33,7 +33,7 @@ /* This is a "major" version in the sense that it's only bumped * for incompatible changes. */ -#define SUPPORTED_GIR_VERSION "1.1" +#define SUPPORTED_GIR_VERSION "1.2" struct _GIrParser { @@ -48,33 +48,33 @@ typedef enum STATE_REPOSITORY, STATE_INCLUDE, STATE_C_INCLUDE, - STATE_PACKAGE, - STATE_NAMESPACE, /* 5 */ + STATE_PACKAGE, /* 5 */ + STATE_NAMESPACE, STATE_ENUM, STATE_BITFIELD, STATE_FUNCTION, - STATE_FUNCTION_RETURN, - STATE_FUNCTION_PARAMETERS, /* 10 */ + STATE_FUNCTION_RETURN, /* 10 */ + STATE_FUNCTION_PARAMETERS, STATE_FUNCTION_PARAMETER, STATE_CLASS, STATE_CLASS_FIELD, - STATE_CLASS_PROPERTY, - STATE_INTERFACE, /* 15 */ + STATE_CLASS_PROPERTY, /* 15 */ + STATE_INTERFACE, STATE_INTERFACE_PROPERTY, STATE_INTERFACE_FIELD, STATE_IMPLEMENTS, - STATE_PREREQUISITE, - STATE_BOXED, /* 20 */ + STATE_PREREQUISITE, /* 20 */ + STATE_BOXED, STATE_BOXED_FIELD, STATE_STRUCT, STATE_STRUCT_FIELD, - STATE_ERRORDOMAIN, - STATE_UNION, /* 25 */ + STATE_ERRORDOMAIN, /* 25 */ + STATE_UNION, STATE_UNION_FIELD, STATE_NAMESPACE_CONSTANT, STATE_CLASS_CONSTANT, - STATE_INTERFACE_CONSTANT, - STATE_ALIAS, /* 30 */ + STATE_INTERFACE_CONSTANT, /* 30 */ + STATE_ALIAS, STATE_TYPE, STATE_ATTRIBUTE, STATE_DOC, @@ -779,6 +779,7 @@ start_function (GMarkupParseContext *context, const gchar *throws; GIrNodeFunction *function; gboolean found = FALSE; + gboolean in_embedded_type; switch (ctx->state) { @@ -787,15 +788,14 @@ start_function (GMarkupParseContext *context, strcmp (element_name, "callback") == 0); break; case STATE_CLASS: - found = strcmp (element_name, "function") == 0; - /* fallthrough */ case STATE_BOXED: case STATE_STRUCT: case STATE_UNION: - found = (found || strcmp (element_name, "constructor") == 0); + found = strcmp (element_name, "constructor") == 0; /* fallthrough */ case STATE_INTERFACE: found = (found || + strcmp (element_name, "function") == 0 || strcmp (element_name, "method") == 0 || strcmp (element_name, "callback") == 0); break; @@ -809,12 +809,13 @@ start_function (GMarkupParseContext *context, if (!found) return FALSE; - if (ctx->state == STATE_STRUCT_FIELD) - ctx->in_embedded_type = TRUE; + in_embedded_type = ctx->state == STATE_STRUCT_FIELD; if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION)) return TRUE; + ctx->in_embedded_type = in_embedded_type; + name = find_attribute ("name", attribute_names, attribute_values); symbol = find_attribute ("c:identifier", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); @@ -964,15 +965,16 @@ parse_property_transfer (GIrNodeProperty *property, } } -static void -parse_param_transfer (GIrNodeParam *param, const gchar *transfer, const gchar *name) +static gboolean +parse_param_transfer (GIrNodeParam *param, const gchar *transfer, const gchar *name, + GError **error) { if (transfer == NULL) { - if (!name) - g_warning ("required attribute 'transfer-ownership' missing"); - else - g_warning ("required attribute 'transfer-ownership' for function '%s'", name); + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "required attribute 'transfer-ownership' missing"); + return FALSE; } else if (strcmp (transfer, "none") == 0) { @@ -991,8 +993,12 @@ parse_param_transfer (GIrNodeParam *param, const gchar *transfer, const gchar *n } else { - g_warning ("Unknown transfer-ownership value: %s", transfer); + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "invalid value for 'transfer-ownership': %s", transfer); + return FALSE; } + return TRUE; } static gboolean @@ -1078,7 +1084,8 @@ start_parameter (GMarkupParseContext *context, else param->allow_none = FALSE; - parse_param_transfer (param, transfer, name); + if (!parse_param_transfer (param, transfer, name, error)) + return FALSE; if (scope && strcmp (scope, "call") == 0) param->scope = GI_SCOPE_TYPE_CALL; @@ -1142,14 +1149,25 @@ start_field (GMarkupParseContext *context, const gchar *bits; const gchar *branch; GIrNodeField *field; + ParseState target_state; + gboolean introspectable; switch (ctx->state) { case STATE_CLASS: + target_state = STATE_CLASS_FIELD; + break; case STATE_BOXED: + target_state = STATE_BOXED_FIELD; + break; case STATE_STRUCT: + target_state = STATE_STRUCT_FIELD; + break; case STATE_UNION: + target_state = STATE_UNION_FIELD; + break; case STATE_INTERFACE: + target_state = STATE_INTERFACE_FIELD; break; default: return FALSE; @@ -1158,6 +1176,13 @@ start_field (GMarkupParseContext *context, if (strcmp (element_name, "field") != 0) return FALSE; + g_assert (ctx->state != STATE_PASSTHROUGH); + + /* We handle introspectability specially here; we replace with just gpointer + * for the type. + */ + introspectable = introspectable_prelude (context, attribute_names, attribute_values, ctx, target_state); + name = find_attribute ("name", attribute_names, attribute_values); readable = find_attribute ("readable", attribute_names, attribute_values); writable = find_attribute ("writable", attribute_names, attribute_values); @@ -1172,7 +1197,15 @@ start_field (GMarkupParseContext *context, field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD, ctx->current_module); - ctx->current_typed = (GIrNode*) field; + if (introspectable) + { + ctx->current_typed = (GIrNode*) field; + } + else + { + field->type = parse_type (ctx, "gpointer"); + } + ((GIrNode *)field)->name = g_strdup (name); /* Fields are assumed to be read-only. * (see also girwriter.py and generate.c) @@ -1193,7 +1226,6 @@ start_field (GMarkupParseContext *context, iface = (GIrNodeInterface *)CURRENT_NODE (ctx); iface->members = g_list_append (iface->members, field); - state_switch (ctx, STATE_CLASS_FIELD); } break; case G_IR_NODE_INTERFACE: @@ -1202,7 +1234,6 @@ start_field (GMarkupParseContext *context, iface = (GIrNodeInterface *)CURRENT_NODE (ctx); iface->members = g_list_append (iface->members, field); - state_switch (ctx, STATE_INTERFACE_FIELD); } break; case G_IR_NODE_BOXED: @@ -1211,7 +1242,6 @@ start_field (GMarkupParseContext *context, boxed = (GIrNodeBoxed *)CURRENT_NODE (ctx); boxed->members = g_list_append (boxed->members, field); - state_switch (ctx, STATE_BOXED_FIELD); } break; case G_IR_NODE_STRUCT: @@ -1220,7 +1250,6 @@ start_field (GMarkupParseContext *context, struct_ = (GIrNodeStruct *)CURRENT_NODE (ctx); struct_->members = g_list_append (struct_->members, field); - state_switch (ctx, STATE_STRUCT_FIELD); } break; case G_IR_NODE_UNION: @@ -1242,7 +1271,6 @@ start_field (GMarkupParseContext *context, union_->discriminators = g_list_append (union_->discriminators, constant); } - state_switch (ctx, STATE_UNION_FIELD); } break; default: @@ -2169,7 +2197,8 @@ start_return_value (GMarkupParseContext *context, state_switch (ctx, STATE_FUNCTION_RETURN); transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); - parse_param_transfer (param, transfer, NULL); + if (!parse_param_transfer (param, transfer, NULL, error)) + return FALSE; switch (CURRENT_NODE (ctx)->type) { @@ -2979,8 +3008,9 @@ start_element_handler (GMarkupParseContext *context, { g_markup_parse_context_get_position (context, &line_number, &char_number); if (!g_str_has_prefix (element_name, "c:")) - g_printerr ("%s:%d:%d: warning: dropping to PASSTHROUGH\n", - ctx->file_path, line_number, char_number); + g_printerr ("%s:%d:%d: warning: element %s from state %d is unknown, ignoring\n", + ctx->file_path, line_number, char_number, element_name, + ctx->state); state_switch (ctx, STATE_PASSTHROUGH); ctx->unknown_depth = 1; } @@ -3026,9 +3056,9 @@ require_one_of_end_elements (GMarkupParseContext *context, g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, - "Unexpected end tag '%s' on line %d char %d; current state=%d", + "Unexpected end tag '%s' on line %d char %d; current state=%d (prev=%d)", actual_name, - line_number, char_number, ctx->state); + line_number, char_number, ctx->state, ctx->prev_state); return FALSE; } @@ -3379,6 +3409,7 @@ end_element_handler (GMarkupParseContext *context, case STATE_PASSTHROUGH: ctx->unknown_depth -= 1; + g_assert (ctx->unknown_depth >= 0); if (ctx->unknown_depth == 0) state_switch (ctx, ctx->prev_state); break; @@ -3486,7 +3517,9 @@ g_ir_parser_parse_string (GIrParser *parser, g_markup_parse_context_free (context); - return ctx.modules->data; + if (ctx.modules) + return ctx.modules->data; + return NULL; } /** diff --git a/gitypelib.c b/gitypelib.c index ef87c0e61..f47a743d3 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -288,12 +288,12 @@ validate_header_basic (const guint8 *memory, } - if (header->major_version != 3 || header->minor_version != 0) + if (header->major_version != 4 || header->minor_version != 0) { g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_HEADER, - "Typelib version mismatch; expected 3, found %d", + "Typelib version mismatch; expected 4, found %d", header->major_version); return FALSE; From 0449abe8987cb6a0f81f0e31a3dc0dcef6562bbd Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 25 Aug 2010 13:14:57 -0400 Subject: [PATCH 379/692] scanner: Avoid internal invalid Type instances from parents We were adding a trailing ',' in the parent string, clean that up; and don't attempt to create a Type from the empty string. --- gdump.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/gdump.c b/gdump.c index 3dc21728f..84ac3c718 100644 --- a/gdump.c +++ b/gdump.c @@ -168,17 +168,17 @@ dump_object_type (GType type, const char *symbol, GOutputStream *out) GType parent; gboolean first = TRUE; - parent = type; + parent = g_type_parent (type); parent_str = g_string_new (""); - do + while (parent != G_TYPE_OBJECT && parent != G_TYPE_INVALID) { - parent = g_type_parent (parent); if (first) first = FALSE; else g_string_append_c (parent_str, ','); g_string_append (parent_str, g_type_name (parent)); - } while (parent != G_TYPE_OBJECT && parent != G_TYPE_INVALID); + parent = g_type_parent (parent); + } escaped_printf (out, " parents=\"%s\"", parent_str->str); @@ -299,11 +299,10 @@ dump_fundamental_type (GType type, const char *symbol, GOutputStream *out) if (G_TYPE_IS_INSTANTIATABLE (type)) escaped_printf (out, " instantiatable=\"1\""); - parent = type; + parent = g_type_parent (type); parent_str = g_string_new (""); - do + while (parent != G_TYPE_INVALID) { - parent = g_type_parent (parent); if (first) first = FALSE; else @@ -311,7 +310,8 @@ dump_fundamental_type (GType type, const char *symbol, GOutputStream *out) if (!g_type_name (parent)) break; g_string_append (parent_str, g_type_name (parent)); - } while (parent != G_TYPE_INVALID); + parent = g_type_parent (parent); + } if (parent_str->len > 0) escaped_printf (out, " parents=\"%s\"", parent_str->str); From 180e1b61ebe84add93fe307d76d655ca6895c291 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 31 Aug 2010 17:26:17 -0300 Subject: [PATCH 380/692] [girepository] Add a couple of missing transfer --- girepository.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/girepository.c b/girepository.c index 689957469..d22560661 100644 --- a/girepository.c +++ b/girepository.c @@ -382,7 +382,7 @@ register_internal (GIRepository *repository, * Note: The namespace must have already been loaded using a function * such as #g_irepository_require before calling this function. * - * Returns: Zero-terminated string array of versioned dependencies + * Returns: (transfer full): Zero-terminated string array of versioned dependencies */ char ** g_irepository_get_dependencies (GIRepository *repository, @@ -625,7 +625,7 @@ find_interface (gpointer key, * given namespace @namespace_. The namespace must have * already been loaded before calling this function. * - * Returns: #GIBaseInfo containing metadata + * Returns: (transfer full): #GIBaseInfo containing metadata */ GIBaseInfo * g_irepository_get_info (GIRepository *repository, @@ -666,7 +666,7 @@ g_irepository_get_info (GIRepository *repository, * arbitrary GType - thus, this function will operate most reliably * when you know the GType to originate from be from a loaded namespace. * - * Returns: #GIBaseInfo representing metadata about @type, or %NULL + * Returns: (transfer full): #GIBaseInfo representing metadata about @type, or %NULL */ GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository, @@ -719,7 +719,7 @@ g_irepository_find_by_gtype (GIRepository *repository, * #g_irepository_require once to load the namespace, or otherwise * ensure the namespace has already been loaded. * - * Returns: #GIBaseInfo representing metadata about @name, or %NULL + * Returns: (transfer full): #GIBaseInfo representing metadata about @name, or %NULL */ GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, @@ -759,7 +759,7 @@ collect_namespaces (gpointer key, } /** - * g_irepository_get_namespaces: + * g_irepository_get_loaded_namespaces: * @repository: A #GIRepository, may be %NULL for the default * * Return the list of currently loaded namespaces. @@ -1335,7 +1335,7 @@ require_internal (GIRepository *repository, * version @version of namespace may be specified. If @version is * not specified, the latest will be used. * - * Returns: a pointer to the #GTypelib if successful, %NULL otherwise + * Returns: (transfer full): a pointer to the #GTypelib if successful, %NULL otherwise */ GTypelib * g_irepository_require (GIRepository *repository, @@ -1370,7 +1370,7 @@ g_irepository_require (GIRepository *repository, * version @version of namespace should be specified. If @version is * not specified, the latest will be used. * - * Returns: a pointer to the #GTypelib if successful, %NULL otherwise + * Returns: (transfer full): a pointer to the #GTypelib if successful, %NULL otherwise */ GTypelib * g_irepository_require_private (GIRepository *repository, @@ -1410,6 +1410,15 @@ static const GOptionEntry introspection_args[] = { { NULL } }; +/** + * g_irepository_get_option_group: + * + * Obtain the option group for girepository, it's used + * by the dumper and for programs that wants to provide + * introspection information + * + * Returns: (transfer full): the option group + */ GOptionGroup * g_irepository_get_option_group (void) { From 9c80c84dc7dce0e191aac8de829420e9874dafb5 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 31 Aug 2010 17:33:06 -0300 Subject: [PATCH 381/692] [GIRepository] Rename GArgument to GIArgument Keep a typedef for backwards compatibility, until the major bindings has moved over. --- giconstantinfo.c | 2 +- giconstantinfo.h | 2 +- gifieldinfo.c | 8 ++++---- gifieldinfo.h | 4 ++-- gifunctioninfo.c | 10 +++++----- gifunctioninfo.h | 6 +++--- girwriter.c | 8 ++++---- gitypes.h | 7 ++++++- 8 files changed, 26 insertions(+), 21 deletions(-) diff --git a/giconstantinfo.c b/giconstantinfo.c index 58b223fba..ea7d41605 100644 --- a/giconstantinfo.c +++ b/giconstantinfo.c @@ -77,7 +77,7 @@ g_constant_info_get_type (GIConstantInfo *info) */ gint g_constant_info_get_value (GIConstantInfo *info, - GArgument *value) + GIArgument *value) { GIRealInfo *rinfo = (GIRealInfo *)info; ConstantBlob *blob; diff --git a/giconstantinfo.h b/giconstantinfo.h index eea0f66d0..a2679bd24 100644 --- a/giconstantinfo.h +++ b/giconstantinfo.h @@ -35,7 +35,7 @@ G_BEGIN_DECLS GITypeInfo * g_constant_info_get_type (GIConstantInfo *info); gint g_constant_info_get_value(GIConstantInfo *info, - GArgument *value); + GIArgument *value); G_END_DECLS diff --git a/gifieldinfo.c b/gifieldinfo.c index 9862a723e..4acc8e3a0 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -164,7 +164,7 @@ g_field_info_get_type (GIFieldInfo *info) * g_field_info_get_field: * @field_info: a #GIFieldInfo * @mem: pointer to a block of memory representing a C structure or union - * @value: a #GArgument into which to store the value retrieved + * @value: a #GIArgument into which to store the value retrieved * * Reads a field identified by a #GFieldInfo from a C structure or * union. This only handles fields of simple C types. It will fail @@ -176,7 +176,7 @@ g_field_info_get_type (GIFieldInfo *info) gboolean g_field_info_get_field (GIFieldInfo *field_info, gpointer mem, - GArgument *value) + GIArgument *value) { int offset; GITypeInfo *type_info; @@ -346,7 +346,7 @@ g_field_info_get_field (GIFieldInfo *field_info, * g_field_info_set_field: * @field_info: a #GIFieldInfo * @mem: pointer to a block of memory representing a C structure or union - * @value: a #GArgument holding the value to store + * @value: a #GIArgument holding the value to store * * Writes a field identified by a #GFieldInfo to a C structure or * union. This only handles fields of simple C types. It will fail @@ -360,7 +360,7 @@ g_field_info_get_field (GIFieldInfo *field_info, gboolean g_field_info_set_field (GIFieldInfo *field_info, gpointer mem, - const GArgument *value) + const GIArgument *value) { int offset; GITypeInfo *type_info; diff --git a/gifieldinfo.h b/gifieldinfo.h index 53ff9be34..589221b73 100644 --- a/gifieldinfo.h +++ b/gifieldinfo.h @@ -39,10 +39,10 @@ gint g_field_info_get_offset (GIFieldInfo *info); GITypeInfo * g_field_info_get_type (GIFieldInfo *info); gboolean g_field_info_get_field (GIFieldInfo *field_info, gpointer mem, - GArgument *value); + GIArgument *value); gboolean g_field_info_set_field (GIFieldInfo *field_info, gpointer mem, - const GArgument *value); + const GIArgument *value); G_END_DECLS diff --git a/gifunctioninfo.c b/gifunctioninfo.c index 736537024..9dd6daae7 100644 --- a/gifunctioninfo.c +++ b/gifunctioninfo.c @@ -217,11 +217,11 @@ g_invoke_error_quark (void) /** * g_function_info_invoke: * @info: a #GIFunctionInfo describing the function to invoke - * @in_args: an array of #GArguments, one for each in + * @in_args: an array of #GIArguments, one for each in * parameter of @info. If there are no in parameter, @in_args * can be %NULL * @n_in_args: the length of the @in_args array - * @out_args: an array of #GArguments, one for each out + * @out_args: an array of #GIArguments, one for each out * parameter of @info. If there are no out parameters, @out_args * may be %NULL * @n_out_args: the length of the @out_args array @@ -242,11 +242,11 @@ g_invoke_error_quark (void) */ gboolean g_function_info_invoke (GIFunctionInfo *info, - const GArgument *in_args, + const GIArgument *in_args, int n_in_args, - const GArgument *out_args, + const GIArgument *out_args, int n_out_args, - GArgument *return_value, + GIArgument *return_value, GError **error) { ffi_cif cif; diff --git a/gifunctioninfo.h b/gifunctioninfo.h index a07b60f74..b2fa1f762 100644 --- a/gifunctioninfo.h +++ b/gifunctioninfo.h @@ -61,11 +61,11 @@ typedef enum } GInvokeError; gboolean g_function_info_invoke (GIFunctionInfo *info, - const GArgument *in_args, + const GIArgument *in_args, int n_in_args, - const GArgument *out_args, + const GIArgument *out_args, int n_out_args, - GArgument *return_value, + GIArgument *return_value, GError **error); diff --git a/girwriter.c b/girwriter.c index bf7ea9dca..48f1a5d21 100644 --- a/girwriter.c +++ b/girwriter.c @@ -389,7 +389,7 @@ write_return_value_attributes (Xml *file, static void write_constant_value (const gchar *namespace, GITypeInfo *info, - GArgument *argument, + GIArgument *argument, Xml *file); static void @@ -409,7 +409,7 @@ write_field_info (const gchar *namespace, gint offset; GITypeInfo *type; GIBaseInfo *interface; - GArgument value; + GIArgument value; name = g_base_info_get_name ((GIBaseInfo *)info); flags = g_field_info_get_flags (info); @@ -725,7 +725,7 @@ write_value_info (const gchar *namespace, static void write_constant_value (const gchar *namespace, GITypeInfo *type, - GArgument *value, + GIArgument *value, Xml *file) { switch (g_type_info_get_tag (type)) @@ -780,7 +780,7 @@ write_constant_info (const gchar *namespace, GITypeInfo *type; const gchar *name; gboolean deprecated; - GArgument value; + GIArgument value; name = g_base_info_get_name ((GIBaseInfo *)info); deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); diff --git a/gitypes.h b/gitypes.h index eb1c1021c..882f00fb3 100644 --- a/gitypes.h +++ b/gitypes.h @@ -187,7 +187,7 @@ typedef union gsize v_size; gchar * v_string; gpointer v_pointer; -} GArgument; +} GIArgument; /** * GIInfoType: @@ -438,6 +438,11 @@ typedef enum GI_FUNCTION_THROWS = 1 << 5 } GIFunctionInfoFlags; +#ifndef __GI_SCANNER__ +/* backwards compatibility */ +typedef union GIArgument GArgument; +#endif + G_END_DECLS #endif /* __GITYPES_H__ */ From 14edb06326e36a086917dfafdee3bc8b1e49b783 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 31 Aug 2010 17:36:06 -0300 Subject: [PATCH 382/692] [GIRepository] Rename GTypelib to GITypelib Keep a typedef for backwards compatibility, until the major bindings has moved over. --- gibaseinfo.c | 16 +++--- gibaseinfo.h | 4 +- girepository-private.h | 12 ++--- girepository.c | 54 +++++++++---------- girepository.h | 6 +-- girmodule.c | 4 +- girmodule.h | 2 +- gitypelib-internal.h | 14 ++--- gitypelib.c | 120 ++++++++++++++++++++--------------------- gitypelib.h | 14 ++--- gitypes.h | 1 + 11 files changed, 124 insertions(+), 123 deletions(-) diff --git a/gibaseinfo.c b/gibaseinfo.c index 81b936d85..a4c9f90b6 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -35,7 +35,7 @@ GIBaseInfo * _g_info_new_full (GIInfoType type, GIRepository *repository, GIBaseInfo *container, - GTypelib *typelib, + GITypelib *typelib, guint32 offset) { GIRealInfo *info; @@ -58,7 +58,7 @@ _g_info_new_full (GIInfoType type, GIBaseInfo * g_info_new (GIInfoType type, GIBaseInfo *container, - GTypelib *typelib, + GITypelib *typelib, guint32 offset) { return _g_info_new_full (type, ((GIRealInfo*)container)->repository, container, typelib, offset); @@ -69,7 +69,7 @@ _g_info_init (GIRealInfo *info, GIInfoType type, GIRepository *repository, GIBaseInfo *container, - GTypelib *typelib, + GITypelib *typelib, guint32 offset) { memset (info, 0, sizeof (GIRealInfo)); @@ -90,7 +90,7 @@ _g_info_init (GIRealInfo *info, GIBaseInfo * _g_info_from_entry (GIRepository *repository, - GTypelib *typelib, + GITypelib *typelib, guint16 index) { GIBaseInfo *result; @@ -127,7 +127,7 @@ _g_info_from_entry (GIRepository *repository, GITypeInfo * _g_type_info_new (GIBaseInfo *container, - GTypelib *typelib, + GITypelib *typelib, guint32 offset) { SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset]; @@ -139,7 +139,7 @@ _g_type_info_new (GIBaseInfo *container, void _g_type_info_init (GIBaseInfo *info, GIBaseInfo *container, - GTypelib *typelib, + GITypelib *typelib, guint32 offset) { GIRealInfo *rinfo = (GIRealInfo*)container; @@ -153,7 +153,7 @@ _g_type_info_init (GIBaseInfo *info, /** * SECTION:gibaseinfo - * @Short_description: Base struct for all GTypelib structs + * @Short_description: Base struct for all GITypelib structs * @Title: GIBaseInfo * * GIBaseInfo is the common base struct of all other *Info structs @@ -611,7 +611,7 @@ g_base_info_get_container (GIBaseInfo *info) * * Returns: (transfer none): the typelib. */ -GTypelib * +GITypelib * g_base_info_get_typelib (GIBaseInfo *info) { return ((GIRealInfo*)info)->typelib; diff --git a/gibaseinfo.h b/gibaseinfo.h index 5d0cb8444..106aadfff 100644 --- a/gibaseinfo.h +++ b/gibaseinfo.h @@ -71,12 +71,12 @@ gboolean g_base_info_iterate_attributes (GIBaseInfo *info, char **name, char **value); GIBaseInfo * g_base_info_get_container (GIBaseInfo *info); -GTypelib * g_base_info_get_typelib (GIBaseInfo *info); +GITypelib * g_base_info_get_typelib (GIBaseInfo *info); gboolean g_base_info_equal (GIBaseInfo *info1, GIBaseInfo *info2); GIBaseInfo * g_info_new (GIInfoType type, GIBaseInfo *container, - GTypelib *typelib, + GITypelib *typelib, guint32 offset); G_END_DECLS diff --git a/girepository-private.h b/girepository-private.h index e2810d26e..46b898b09 100644 --- a/girepository-private.h +++ b/girepository-private.h @@ -49,7 +49,7 @@ struct _GIRealInfo /* Resolved specific */ - GTypelib *typelib; + GITypelib *typelib; guint32 offset; guint32 type_is_embedded : 1; /* Used by GITypeInfo */ @@ -76,26 +76,26 @@ void _g_info_init (GIRealInfo *info, GIInfoType type, GIRepository *repository, GIBaseInfo *container, - GTypelib *typelib, + GITypelib *typelib, guint32 offset); GIBaseInfo * _g_info_from_entry (GIRepository *repository, - GTypelib *typelib, + GITypelib *typelib, guint16 index); GIBaseInfo * _g_info_new_full (GIInfoType type, GIRepository *repository, GIBaseInfo *container, - GTypelib *typelib, + GITypelib *typelib, guint32 offset); GITypeInfo * _g_type_info_new (GIBaseInfo *container, - GTypelib *typelib, + GITypelib *typelib, guint32 offset); void _g_type_info_init (GIBaseInfo *info, GIBaseInfo *container, - GTypelib *typelib, + GITypelib *typelib, guint32 offset); GIFunctionInfo * _g_base_info_find_method (GIBaseInfo *base, diff --git a/girepository.c b/girepository.c index d22560661..db4fdc977 100644 --- a/girepository.c +++ b/girepository.c @@ -42,8 +42,8 @@ static GSList *override_search_path = NULL; struct _GIRepositoryPrivate { - GHashTable *typelibs; /* (string) namespace -> GTypelib */ - GHashTable *lazy_typelibs; /* (string) namespace-version -> GTypelib */ + GHashTable *typelibs; /* (string) namespace -> GITypelib */ + GHashTable *lazy_typelibs; /* (string) namespace-version -> GITypelib */ GHashTable *info_by_gtype; /* GType -> GIBaseInfo */ }; @@ -193,7 +193,7 @@ build_typelib_key (const char *name, const char *source) } static char ** -get_typelib_dependencies (GTypelib *typelib) +get_typelib_dependencies (GITypelib *typelib) { Header *header; const char *dependencies_glob; @@ -218,8 +218,8 @@ get_repository (GIRepository *repository) return default_repository; } -static GTypelib * -check_version_conflict (GTypelib *typelib, +static GITypelib * +check_version_conflict (GITypelib *typelib, const gchar *namespace, const gchar *expected_version, char **version_conflict) @@ -249,7 +249,7 @@ check_version_conflict (GTypelib *typelib, return typelib; } -static GTypelib * +static GITypelib * get_registered_status (GIRepository *repository, const char *namespace, const char *version, @@ -257,7 +257,7 @@ get_registered_status (GIRepository *repository, gboolean *lazy_status, char **version_conflict) { - GTypelib *typelib; + GITypelib *typelib; repository = get_repository (repository); if (lazy_status) *lazy_status = FALSE; @@ -274,7 +274,7 @@ get_registered_status (GIRepository *repository, return check_version_conflict (typelib, namespace, version, version_conflict); } -static GTypelib * +static GITypelib * get_registered (GIRepository *repository, const char *namespace, const char *version) @@ -284,7 +284,7 @@ get_registered (GIRepository *repository, static gboolean load_dependencies_recurse (GIRepository *repository, - GTypelib *typelib, + GITypelib *typelib, GError **error) { char **dependencies; @@ -324,7 +324,7 @@ static const char * register_internal (GIRepository *repository, const char *source, gboolean lazy, - GTypelib *typelib, + GITypelib *typelib, GError **error) { Header *header; @@ -388,7 +388,7 @@ char ** g_irepository_get_dependencies (GIRepository *repository, const char *namespace) { - GTypelib *typelib; + GITypelib *typelib; g_return_val_if_fail (namespace != NULL, NULL); @@ -402,7 +402,7 @@ g_irepository_get_dependencies (GIRepository *repository, const char * g_irepository_load_typelib (GIRepository *repository, - GTypelib *typelib, + GITypelib *typelib, GIRepositoryLoadFlags flags, GError **error) { @@ -497,7 +497,7 @@ gint g_irepository_get_n_infos (GIRepository *repository, const gchar *namespace) { - GTypelib *typelib; + GITypelib *typelib; gint n_interfaces = 0; g_return_val_if_fail (namespace != NULL, -1); @@ -529,7 +529,7 @@ find_interface (gpointer key, gpointer data) { gint i; - GTypelib *typelib = (GTypelib *)value; + GITypelib *typelib = (GITypelib *)value; Header *header = (Header *) typelib->data; IfaceData *iface_data = (IfaceData *)data; gint index; @@ -633,7 +633,7 @@ g_irepository_get_info (GIRepository *repository, gint index) { IfaceData data; - GTypelib *typelib; + GITypelib *typelib; g_return_val_if_fail (namespace != NULL, NULL); @@ -727,7 +727,7 @@ g_irepository_find_by_name (GIRepository *repository, const gchar *name) { IfaceData data; - GTypelib *typelib; + GITypelib *typelib; g_return_val_if_fail (namespace != NULL, NULL); @@ -804,7 +804,7 @@ const gchar * g_irepository_get_version (GIRepository *repository, const gchar *namespace) { - GTypelib *typelib; + GITypelib *typelib; Header *header; g_return_val_if_fail (namespace != NULL, NULL); @@ -838,7 +838,7 @@ const gchar * g_irepository_get_shared_library (GIRepository *repository, const gchar *namespace) { - GTypelib *typelib; + GITypelib *typelib; Header *header; g_return_val_if_fail (namespace != NULL, NULL); @@ -874,7 +874,7 @@ const gchar * g_irepository_get_c_prefix (GIRepository *repository, const gchar *namespace_) { - GTypelib *typelib; + GITypelib *typelib; Header *header; g_return_val_if_fail (namespace_ != NULL, NULL); @@ -1206,7 +1206,7 @@ g_irepository_enumerate_versions (GIRepository *repository, return ret; } -static GTypelib * +static GITypelib * require_internal (GIRepository *repository, const gchar *namespace, const gchar *version, @@ -1215,9 +1215,9 @@ require_internal (GIRepository *repository, GError **error) { GMappedFile *mfile; - GTypelib *ret = NULL; + GITypelib *ret = NULL; Header *header; - GTypelib *typelib = NULL; + GITypelib *typelib = NULL; const gchar *typelib_namespace, *typelib_version; gboolean allow_lazy = (flags & G_IREPOSITORY_LOAD_FLAG_LAZY) > 0; gboolean is_lazy; @@ -1335,9 +1335,9 @@ require_internal (GIRepository *repository, * version @version of namespace may be specified. If @version is * not specified, the latest will be used. * - * Returns: (transfer full): a pointer to the #GTypelib if successful, %NULL otherwise + * Returns: (transfer full): a pointer to the #GITypelib if successful, %NULL otherwise */ -GTypelib * +GITypelib * g_irepository_require (GIRepository *repository, const gchar *namespace, const gchar *version, @@ -1345,7 +1345,7 @@ g_irepository_require (GIRepository *repository, GError **error) { GSList *search_path; - GTypelib *typelib; + GITypelib *typelib; search_path = build_search_path_with_overrides (); typelib = require_internal (repository, namespace, version, flags, @@ -1370,9 +1370,9 @@ g_irepository_require (GIRepository *repository, * version @version of namespace should be specified. If @version is * not specified, the latest will be used. * - * Returns: (transfer full): a pointer to the #GTypelib if successful, %NULL otherwise + * Returns: (transfer full): a pointer to the #GITypelib if successful, %NULL otherwise */ -GTypelib * +GITypelib * g_irepository_require_private (GIRepository *repository, const gchar *typelib_dir, const gchar *namespace, diff --git a/girepository.h b/girepository.h index 5c6a1c0f1..476f183b8 100644 --- a/girepository.h +++ b/girepository.h @@ -92,7 +92,7 @@ GIRepository *g_irepository_get_default (void); void g_irepository_prepend_search_path (const char *directory); GSList * g_irepository_get_search_path (void); const char * g_irepository_load_typelib (GIRepository *repository, - GTypelib *typelib, + GITypelib *typelib, GIRepositoryLoadFlags flags, GError **error); gboolean g_irepository_is_registered (GIRepository *repository, @@ -103,12 +103,12 @@ GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, const gchar *name); GList * g_irepository_enumerate_versions (GIRepository *repository, const gchar *namespace_); -GTypelib * g_irepository_require (GIRepository *repository, +GITypelib * g_irepository_require (GIRepository *repository, const gchar *namespace_, const gchar *version, GIRepositoryLoadFlags flags, GError **error); -GTypelib * g_irepository_require_private (GIRepository *repository, +GITypelib * g_irepository_require_private (GIRepository *repository, const gchar *typelib_dir, const gchar *namespace, const gchar *version, diff --git a/girmodule.c b/girmodule.c index ebee26c5d..68ee64b3a 100644 --- a/girmodule.c +++ b/girmodule.c @@ -221,11 +221,11 @@ node_cmp_offset_func (gconstpointer a, } -GTypelib * +GITypelib * g_ir_module_build_typelib (GIrModule *module) { GError *error = NULL; - GTypelib *typelib; + GITypelib *typelib; gsize length; guint i; GList *e; diff --git a/girmodule.h b/girmodule.h index e8d7ad1e8..6c6d6201e 100644 --- a/girmodule.h +++ b/girmodule.h @@ -68,7 +68,7 @@ void g_ir_module_free (GIrModule *module); void g_ir_module_add_include_module (GIrModule *module, GIrModule *include_module); -GTypelib * g_ir_module_build_typelib (GIrModule *module); +GITypelib * g_ir_module_build_typelib (GIrModule *module); void g_ir_module_fatal (GIrTypelibBuild *build, guint line, const char *msg, ...) G_GNUC_PRINTF (3, 4) G_GNUC_NORETURN; diff --git a/gitypelib-internal.h b/gitypelib-internal.h index d1461fa1f..87a181700 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -1085,9 +1085,9 @@ typedef struct { } AttributeBlob; /** - * GTypelib: + * GITypelib: */ -struct _GTypelib { +struct _GITypelib { /* */ guchar *data; gsize len; @@ -1097,7 +1097,7 @@ struct _GTypelib { gboolean open_attempted; }; -DirEntry *g_typelib_get_dir_entry (GTypelib *typelib, +DirEntry *g_typelib_get_dir_entry (GITypelib *typelib, guint16 index); void g_typelib_check_sanity (void); @@ -1106,14 +1106,14 @@ void g_typelib_check_sanity (void); /** - * GTypelibError: + * GITypelibError: * @G_TYPELIB_ERROR_INVALID: the typelib is invalid * @G_TYPELIB_ERROR_INVALID_HEADER: the typelib header is invalid * @G_TYPELIB_ERROR_INVALID_DIRECTORY: the typelib directory is invalid * @G_TYPELIB_ERROR_INVALID_ENTRY: a typelib entry is invalid * @G_TYPELIB_ERROR_INVALID_BLOB: a typelib blob is invalid * - * A error set while validating the #GTypelib + * A error set while validating the #GITypelib */ typedef enum { @@ -1122,13 +1122,13 @@ typedef enum G_TYPELIB_ERROR_INVALID_DIRECTORY, G_TYPELIB_ERROR_INVALID_ENTRY, G_TYPELIB_ERROR_INVALID_BLOB -} GTypelibError; +} GITypelibError; #define G_TYPELIB_ERROR (g_typelib_error_quark ()) GQuark g_typelib_error_quark (void); -gboolean g_typelib_validate (GTypelib *typelib, +gboolean g_typelib_validate (GITypelib *typelib, GError **error); diff --git a/gitypelib.c b/gitypelib.c index f47a743d3..faeb3fc98 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -29,7 +29,7 @@ #include "glib-compat.h" typedef struct { - GTypelib *typelib; + GITypelib *typelib; GSList *context_stack; } ValidateContext; @@ -56,7 +56,7 @@ validate_interface_blob (ValidateContext *ctx, GError **error); static DirEntry * -get_dir_entry_checked (GTypelib *typelib, +get_dir_entry_checked (GITypelib *typelib, guint16 index, GError **error) { @@ -88,7 +88,7 @@ get_dir_entry_checked (GTypelib *typelib, static CommonBlob * -get_blob (GTypelib *typelib, +get_blob (GITypelib *typelib, guint32 offset, GError **error) { @@ -104,7 +104,7 @@ get_blob (GTypelib *typelib, } static InterfaceTypeBlob * -get_type_blob (GTypelib *typelib, +get_type_blob (GITypelib *typelib, SimpleTypeBlob *simple, GError **error) { @@ -131,7 +131,7 @@ get_type_blob (GTypelib *typelib, } DirEntry * -g_typelib_get_dir_entry (GTypelib *typelib, +g_typelib_get_dir_entry (GITypelib *typelib, guint16 index) { Header *header = (Header *)typelib->data; @@ -203,7 +203,7 @@ is_aligned (guint32 offset) #define MAX_NAME_LEN 200 static const char * -get_string (GTypelib *typelib, guint32 offset, GError **error) +get_string (GITypelib *typelib, guint32 offset, GError **error) { if (typelib->len < offset) { @@ -218,7 +218,7 @@ get_string (GTypelib *typelib, guint32 offset, GError **error) } static const char * -get_string_nofail (GTypelib *typelib, guint32 offset) +get_string_nofail (GITypelib *typelib, guint32 offset) { const char *ret = get_string (typelib, offset, NULL); g_assert (ret); @@ -226,7 +226,7 @@ get_string_nofail (GTypelib *typelib, guint32 offset) } static gboolean -validate_name (GTypelib *typelib, +validate_name (GITypelib *typelib, const char *msg, const guchar *data, guint32 offset, GError **error) @@ -386,7 +386,7 @@ static gboolean validate_header (ValidateContext *ctx, GError **error) { - GTypelib *typelib = ctx->typelib; + GITypelib *typelib = ctx->typelib; if (!validate_header_basic (typelib->data, typelib->len, error)) return FALSE; @@ -400,14 +400,14 @@ validate_header (ValidateContext *ctx, return TRUE; } -static gboolean validate_type_blob (GTypelib *typelib, +static gboolean validate_type_blob (GITypelib *typelib, guint32 offset, guint32 signature_offset, gboolean return_type, GError **error); static gboolean -validate_array_type_blob (GTypelib *typelib, +validate_array_type_blob (GITypelib *typelib, guint32 offset, guint32 signature_offset, gboolean return_type, @@ -437,7 +437,7 @@ validate_array_type_blob (GTypelib *typelib, } static gboolean -validate_iface_type_blob (GTypelib *typelib, +validate_iface_type_blob (GITypelib *typelib, guint32 offset, guint32 signature_offset, gboolean return_type, @@ -459,7 +459,7 @@ validate_iface_type_blob (GTypelib *typelib, } static gboolean -validate_param_type_blob (GTypelib *typelib, +validate_param_type_blob (GITypelib *typelib, guint32 offset, guint32 signature_offset, gboolean return_type, @@ -502,7 +502,7 @@ validate_param_type_blob (GTypelib *typelib, } static gboolean -validate_error_type_blob (GTypelib *typelib, +validate_error_type_blob (GITypelib *typelib, guint32 offset, guint32 signature_offset, gboolean return_type, @@ -554,7 +554,7 @@ validate_error_type_blob (GTypelib *typelib, } static gboolean -validate_type_blob (GTypelib *typelib, +validate_type_blob (GITypelib *typelib, guint32 offset, guint32 signature_offset, gboolean return_type, @@ -632,7 +632,7 @@ validate_type_blob (GTypelib *typelib, } static gboolean -validate_arg_blob (GTypelib *typelib, +validate_arg_blob (GITypelib *typelib, guint32 offset, guint32 signature_offset, GError **error) @@ -662,7 +662,7 @@ validate_arg_blob (GTypelib *typelib, } static SimpleTypeBlob * -return_type_from_signature (GTypelib *typelib, +return_type_from_signature (GITypelib *typelib, guint32 offset, GError **error) { @@ -690,7 +690,7 @@ return_type_from_signature (GTypelib *typelib, } static gboolean -validate_signature_blob (GTypelib *typelib, +validate_signature_blob (GITypelib *typelib, guint32 offset, GError **error) { @@ -737,7 +737,7 @@ validate_function_blob (ValidateContext *ctx, guint16 container_type, GError **error) { - GTypelib *typelib = ctx->typelib; + GITypelib *typelib = ctx->typelib; FunctionBlob *blob; SignatureBlob *sigblob; gboolean is_method; @@ -873,7 +873,7 @@ validate_callback_blob (ValidateContext *ctx, guint32 offset, GError **error) { - GTypelib *typelib = ctx->typelib; + GITypelib *typelib = ctx->typelib; CallbackBlob *blob; if (typelib->len < offset + sizeof (CallbackBlob)) @@ -910,7 +910,7 @@ validate_callback_blob (ValidateContext *ctx, } static gboolean -validate_constant_blob (GTypelib *typelib, +validate_constant_blob (GITypelib *typelib, guint32 offset, GError **error) { @@ -1006,7 +1006,7 @@ validate_constant_blob (GTypelib *typelib, } static gboolean -validate_value_blob (GTypelib *typelib, +validate_value_blob (GITypelib *typelib, guint32 offset, GError **error) { @@ -1034,7 +1034,7 @@ validate_field_blob (ValidateContext *ctx, guint32 offset, GError **error) { - GTypelib *typelib = ctx->typelib; + GITypelib *typelib = ctx->typelib; Header *header = (Header *)typelib->data; FieldBlob *blob; @@ -1066,7 +1066,7 @@ validate_field_blob (ValidateContext *ctx, } static gboolean -validate_property_blob (GTypelib *typelib, +validate_property_blob (GITypelib *typelib, guint32 offset, GError **error) { @@ -1095,7 +1095,7 @@ validate_property_blob (GTypelib *typelib, } static gboolean -validate_signal_blob (GTypelib *typelib, +validate_signal_blob (GITypelib *typelib, guint32 offset, guint32 container_offset, GError **error) @@ -1164,7 +1164,7 @@ validate_signal_blob (GTypelib *typelib, } static gboolean -validate_vfunc_blob (GTypelib *typelib, +validate_vfunc_blob (GITypelib *typelib, guint32 offset, guint32 container_offset, GError **error) @@ -1227,7 +1227,7 @@ validate_struct_blob (ValidateContext *ctx, guint16 blob_type, GError **error) { - GTypelib *typelib = ctx->typelib; + GITypelib *typelib = ctx->typelib; StructBlob *blob; gint i; guint32 field_offset; @@ -1324,7 +1324,7 @@ validate_enum_blob (ValidateContext *ctx, guint16 blob_type, GError **error) { - GTypelib *typelib = ctx->typelib; + GITypelib *typelib = ctx->typelib; EnumBlob *blob; gint i; @@ -1423,7 +1423,7 @@ validate_object_blob (ValidateContext *ctx, guint32 offset, GError **error) { - GTypelib *typelib = ctx->typelib; + GITypelib *typelib = ctx->typelib; Header *header; ObjectBlob *blob; gint i; @@ -1603,7 +1603,7 @@ validate_interface_blob (ValidateContext *ctx, guint32 offset, GError **error) { - GTypelib *typelib = ctx->typelib; + GITypelib *typelib = ctx->typelib; Header *header; InterfaceBlob *blob; gint i; @@ -1726,7 +1726,7 @@ validate_interface_blob (ValidateContext *ctx, } static gboolean -validate_errordomain_blob (GTypelib *typelib, +validate_errordomain_blob (GITypelib *typelib, guint32 offset, GError **error) { @@ -1734,7 +1734,7 @@ validate_errordomain_blob (GTypelib *typelib, } static gboolean -validate_union_blob (GTypelib *typelib, +validate_union_blob (GITypelib *typelib, guint32 offset, GError **error) { @@ -1746,7 +1746,7 @@ validate_blob (ValidateContext *ctx, guint32 offset, GError **error) { - GTypelib *typelib = ctx->typelib; + GITypelib *typelib = ctx->typelib; CommonBlob *common; if (typelib->len < offset + sizeof (CommonBlob)) @@ -1815,7 +1815,7 @@ static gboolean validate_directory (ValidateContext *ctx, GError **error) { - GTypelib *typelib = ctx->typelib; + GITypelib *typelib = ctx->typelib; Header *header = (Header *)typelib->data; DirEntry *entry; gint i; @@ -1892,7 +1892,7 @@ static gboolean validate_attributes (ValidateContext *ctx, GError **error) { - GTypelib *typelib = ctx->typelib; + GITypelib *typelib = ctx->typelib; Header *header = (Header *)typelib->data; if (header->size < header->attributes + header->n_attributes * sizeof (AttributeBlob)) @@ -1936,7 +1936,7 @@ prefix_with_context (GError **error, } gboolean -g_typelib_validate (GTypelib *typelib, +g_typelib_validate (GITypelib *typelib, GError **error) { ValidateContext ctx; @@ -1974,7 +1974,7 @@ g_typelib_error_quark (void) } static void -_g_typelib_do_dlopen (GTypelib *typelib) +_g_typelib_do_dlopen (GITypelib *typelib) { Header *header; const char *shlib_str; @@ -2060,7 +2060,7 @@ _g_typelib_do_dlopen (GTypelib *typelib) } static inline void -_g_typelib_ensure_open (GTypelib *typelib) +_g_typelib_ensure_open (GITypelib *typelib) { if (typelib->open_attempted) return; @@ -2074,23 +2074,23 @@ _g_typelib_ensure_open (GTypelib *typelib) * @len: length of memory chunk containing the typelib * @error: a #GError * - * Creates a new #GTypelib from a memory location. The memory block + * Creates a new #GITypelib from a memory location. The memory block * pointed to by @typelib will be automatically g_free()d when the * repository is destroyed. * - * Return value: the new #GTypelib + * Return value: the new #GITypelib **/ -GTypelib * +GITypelib * g_typelib_new_from_memory (guint8 *memory, gsize len, GError **error) { - GTypelib *meta; + GITypelib *meta; if (!validate_header_basic (memory, len, error)) return NULL; - meta = g_slice_new0 (GTypelib); + meta = g_slice_new0 (GITypelib); meta->data = memory; meta->len = len; meta->owns_memory = TRUE; @@ -2105,21 +2105,21 @@ g_typelib_new_from_memory (guint8 *memory, * @len: length of memory chunk containing the typelib * @error: A #GError * - * Creates a new #GTypelib from a memory location. + * Creates a new #GITypelib from a memory location. * - * Return value: the new #GTypelib + * Return value: the new #GITypelib **/ -GTypelib * +GITypelib * g_typelib_new_from_const_memory (const guchar *memory, gsize len, GError **error) { - GTypelib *meta; + GITypelib *meta; if (!validate_header_basic (memory, len, error)) return NULL; - meta = g_slice_new0 (GTypelib); + meta = g_slice_new0 (GITypelib); meta->data = (guchar *) memory; meta->len = len; meta->owns_memory = FALSE; @@ -2133,22 +2133,22 @@ g_typelib_new_from_const_memory (const guchar *memory, * @mfile: a #GMappedFile, that will be free'd when the repository is destroyed * @error: a #GError * - * Creates a new #GTypelib from a #GMappedFile. + * Creates a new #GITypelib from a #GMappedFile. * - * Return value: the new #GTypelib + * Return value: the new #GITypelib **/ -GTypelib * +GITypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile, GError **error) { - GTypelib *meta; + GITypelib *meta; guint8 *data = (guint8 *) g_mapped_file_get_contents (mfile); gsize len = g_mapped_file_get_length (mfile); if (!validate_header_basic (data, len, error)) return NULL; - meta = g_slice_new0 (GTypelib); + meta = g_slice_new0 (GITypelib); meta->mfile = mfile; meta->owns_memory = FALSE; meta->data = data; @@ -2159,12 +2159,12 @@ g_typelib_new_from_mapped_file (GMappedFile *mfile, /** * g_typelib_free: - * @typelib: a #GTypelib + * @typelib: a #GITypelib * - * Free a #GTypelib. + * Free a #GITypelib. **/ void -g_typelib_free (GTypelib *typelib) +g_typelib_free (GITypelib *typelib) { if (typelib->mfile) g_mapped_file_unref (typelib->mfile); @@ -2176,11 +2176,11 @@ g_typelib_free (GTypelib *typelib) g_list_foreach (typelib->modules, (GFunc) g_module_close, NULL); g_list_free (typelib->modules); } - g_slice_free (GTypelib, typelib); + g_slice_free (GITypelib, typelib); } const gchar * -g_typelib_get_namespace (GTypelib *typelib) +g_typelib_get_namespace (GITypelib *typelib) { return g_typelib_get_string (typelib, ((Header *) typelib->data)->namespace); } @@ -2191,12 +2191,12 @@ g_typelib_get_namespace (GTypelib *typelib) * @symbol_name: name of symbol to be loaded * @symbol: returns a pointer to the symbol value * - * Loads a symbol from #GTypelib. + * Loads a symbol from #GITypelib. * * Return value: #TRUE on success **/ gboolean -g_typelib_symbol (GTypelib *typelib, const char *symbol_name, gpointer *symbol) +g_typelib_symbol (GITypelib *typelib, const char *symbol_name, gpointer *symbol) { GList *l; diff --git a/gitypelib.h b/gitypelib.h index 0a61008ac..aadf6066e 100644 --- a/gitypelib.h +++ b/gitypelib.h @@ -32,22 +32,22 @@ G_BEGIN_DECLS -typedef struct _GTypelib GTypelib; +typedef struct _GITypelib GITypelib; -GTypelib * g_typelib_new_from_memory (guint8 *memory, +GITypelib * g_typelib_new_from_memory (guint8 *memory, gsize len, GError **error); -GTypelib * g_typelib_new_from_const_memory (const guint8 *memory, +GITypelib * g_typelib_new_from_const_memory (const guint8 *memory, gsize len, GError **error); -GTypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile, +GITypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile, GError **error); -void g_typelib_free (GTypelib *typelib); +void g_typelib_free (GITypelib *typelib); -gboolean g_typelib_symbol (GTypelib *typelib, +gboolean g_typelib_symbol (GITypelib *typelib, const gchar *symbol_name, gpointer *symbol); -const gchar * g_typelib_get_namespace (GTypelib *typelib); +const gchar * g_typelib_get_namespace (GITypelib *typelib); G_END_DECLS diff --git a/gitypes.h b/gitypes.h index 882f00fb3..2c19c6c78 100644 --- a/gitypes.h +++ b/gitypes.h @@ -441,6 +441,7 @@ typedef enum #ifndef __GI_SCANNER__ /* backwards compatibility */ typedef union GIArgument GArgument; +typedef union GITypelib GTypelib; #endif G_END_DECLS From ce1779b8dd08c832825885a7e61541a59e3edf7f Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 31 Aug 2010 17:50:44 -0300 Subject: [PATCH 383/692] [GIRepository] Add missing transfer and skip --- gibaseinfo.c | 4 ++-- giobjectinfo.c | 8 ++++---- gisignalinfo.c | 2 +- gitypeinfo.c | 2 +- givfuncinfo.c | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/gibaseinfo.c b/gibaseinfo.c index a4c9f90b6..07d05019a 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -198,7 +198,7 @@ _g_type_info_init (GIBaseInfo *info, */ /** - * g_base_info_ref: + * g_base_info_ref: (skip) * @info: a #GIBaseInfo * * Increases the reference count of @info. @@ -217,7 +217,7 @@ g_base_info_ref (GIBaseInfo *info) } /** - * g_base_info_unref: + * g_base_info_unref: (skip) * @info: a #GIBaseInfo * * Decreases the reference count of @info. When its reference count diff --git a/giobjectinfo.c b/giobjectinfo.c index bc2ddcd0f..03ed2a22a 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -721,7 +721,7 @@ g_object_info_get_ref_function (GIObjectInfo *info) } /** - * g_object_info_get_ref_function_pointer: + * g_object_info_get_ref_function_pointer: (skip) * @info: a #GIObjectInfo * * Obtain a pointer to a function which can be used to @@ -769,7 +769,7 @@ g_object_info_get_unref_function (GIObjectInfo *info) } /** - * g_object_info_get_unref_function_pointer: + * g_object_info_get_unref_function_pointer: (skip) * @info: a #GIObjectInfo * * Obtain a pointer to a function which can be used to @@ -818,7 +818,7 @@ g_object_info_get_set_value_function (GIObjectInfo *info) } /** - * g_object_info_get_set_value_function_pointer: + * g_object_info_get_set_value_function_pointer: (skip) * @info: a #GIObjectInfo * * Obtain a pointer to a function which can be used to @@ -867,7 +867,7 @@ g_object_info_get_get_value_function (GIObjectInfo *info) } /** - * g_object_info_get_get_value_function_pointer: + * g_object_info_get_get_value_function_pointer: (skip) * @info: a #GIObjectInfo * * Obtain a pointer to a function which can be used to diff --git a/gisignalinfo.c b/gisignalinfo.c index b19d98e9c..ddc891a41 100644 --- a/gisignalinfo.c +++ b/gisignalinfo.c @@ -102,7 +102,7 @@ g_signal_info_get_flags (GISignalInfo *info) * closure is a virtual function on the type that the signal belongs to. * If the signal lacks a closure %NULL will be returned. * - * Returns: the class closure or %NULL + * Returns: (transfer full): the class closure or %NULL */ GIVFuncInfo * g_signal_info_get_class_closure (GISignalInfo *info) diff --git a/gitypeinfo.c b/gitypeinfo.c index 4904c2ba9..1bc9b0a13 100644 --- a/gitypeinfo.c +++ b/gitypeinfo.c @@ -118,7 +118,7 @@ g_type_info_get_tag (GITypeInfo *info) * * Obtain the parameter type @n. * - * Returns: the param type info + * Returns: (transfer full): the param type info */ GITypeInfo * g_type_info_get_param_type (GITypeInfo *info, diff --git a/givfuncinfo.c b/givfuncinfo.c index da86ed4df..98ac94539 100644 --- a/givfuncinfo.c +++ b/givfuncinfo.c @@ -138,7 +138,7 @@ g_vfunc_info_get_offset (GIVFuncInfo *info) * The signal comes from the object or interface to which * this virtual function belongs. * - * Returns: the signal or %NULL if none set + * Returns: (transfer full): the signal or %NULL if none set */ GISignalInfo * g_vfunc_info_get_signal (GIVFuncInfo *info) From 36bf5dd721c0e0c804ea5a2d00c9730a0d302f6d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 1 Sep 2010 15:54:52 -0400 Subject: [PATCH 384/692] girepository: Fix compatibility typedefs --- gitypes.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gitypes.h b/gitypes.h index 2c19c6c78..a356800ca 100644 --- a/gitypes.h +++ b/gitypes.h @@ -164,7 +164,7 @@ typedef GIBaseInfo GIErrorDomainInfo; */ typedef struct _GIUnresolvedInfo GIUnresolvedInfo; -typedef union +union _GIArgument { gboolean v_boolean; gint8 v_int8; @@ -187,7 +187,8 @@ typedef union gsize v_size; gchar * v_string; gpointer v_pointer; -} GIArgument; +}; +typedef union _GIArgument GIArgument; /** * GIInfoType: @@ -440,8 +441,8 @@ typedef enum #ifndef __GI_SCANNER__ /* backwards compatibility */ -typedef union GIArgument GArgument; -typedef union GITypelib GTypelib; +typedef union _GIArgument GArgument; +typedef struct _GITypelib GTypelib; #endif G_END_DECLS From b18a6580d25101524ad7fd975c93b8642dcbf19a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 2 Sep 2010 17:40:54 -0400 Subject: [PATCH 385/692] girepository: Call init_globals() This fixes the search path initialization if g_irepository_require is called first thing. --- girepository.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/girepository.c b/girepository.c index db4fdc977..a8c661ab7 100644 --- a/girepository.c +++ b/girepository.c @@ -168,19 +168,21 @@ g_irepository_get_search_path (void) return search_path; } -static -GSList * +static GSList * build_search_path_with_overrides (void) { - GSList *result; - if (override_search_path != NULL) - { - result = g_slist_copy (override_search_path); - g_slist_last (result)->next = g_slist_copy (search_path); - } - else - result = g_slist_copy (search_path); - return result; + GSList *result; + + init_globals (); + + if (override_search_path != NULL) + { + result = g_slist_copy (override_search_path); + g_slist_last (result)->next = g_slist_copy (search_path); + } + else + result = g_slist_copy (search_path); + return result; } static char * From f0eeec8cd8ebf2735123875527fb4bd267e24bb5 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 3 Sep 2010 18:07:16 -0400 Subject: [PATCH 386/692] scanner: Fix rename-to handling We were writing the attributes backwards. Also actually use the attribute in the typelib generation. --- girparser.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/girparser.c b/girparser.c index bdb878111..0c022f92f 100644 --- a/girparser.c +++ b/girparser.c @@ -774,6 +774,7 @@ start_function (GMarkupParseContext *context, GError **error) { const gchar *name; + const gchar *shadows; const gchar *symbol; const gchar *deprecated; const gchar *throws; @@ -817,6 +818,7 @@ start_function (GMarkupParseContext *context, ctx->in_embedded_type = in_embedded_type; name = find_attribute ("name", attribute_names, attribute_values); + shadows = find_attribute ("name", attribute_names, attribute_values); symbol = find_attribute ("c:identifier", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); throws = find_attribute ("throws", attribute_names, attribute_values); @@ -832,6 +834,9 @@ start_function (GMarkupParseContext *context, return FALSE; } + if (shadows) + name = shadows; + function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION, ctx->current_module); From 9a464755846e4949c3fbfb7aaf12a67927f57dad Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 3 Sep 2010 18:09:35 -0400 Subject: [PATCH 387/692] scanner: Fix previous rename-to handling commit --- girparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index 0c022f92f..53f1c415d 100644 --- a/girparser.c +++ b/girparser.c @@ -818,7 +818,7 @@ start_function (GMarkupParseContext *context, ctx->in_embedded_type = in_embedded_type; name = find_attribute ("name", attribute_names, attribute_values); - shadows = find_attribute ("name", attribute_names, attribute_values); + shadows = find_attribute ("shadows", attribute_names, attribute_values); symbol = find_attribute ("c:identifier", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); throws = find_attribute ("throws", attribute_names, attribute_values); From bc6a8d2f23a2e9943c0d825cca2fc064eab14844 Mon Sep 17 00:00:00 2001 From: Pavel Holejsovsky Date: Sun, 5 Sep 2010 10:58:31 -0300 Subject: [PATCH 388/692] [girepository] Document GIStructInfo & GIUnionInfo https://bugzilla.gnome.org/show_bug.cgi?id=628753 --- giconstantinfo.c | 2 +- gifieldinfo.c | 4 +- gifunctioninfo.c | 2 +- giobjectinfo.h | 12 ++--- girepository.c | 2 +- gistructinfo.c | 90 +++++++++++++++++++++++++++++++++++ giunioninfo.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 221 insertions(+), 11 deletions(-) diff --git a/giconstantinfo.c b/giconstantinfo.c index ea7d41605..b6b67d1a8 100644 --- a/giconstantinfo.c +++ b/giconstantinfo.c @@ -65,7 +65,7 @@ g_constant_info_get_type (GIConstantInfo *info) } /** - * g_constant_info_get_value: + * g_constant_info_get_value: (skip) * @info: a #GIConstantInfo * @value: (out): an argument * diff --git a/gifieldinfo.c b/gifieldinfo.c index 4acc8e3a0..21a6db021 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -161,7 +161,7 @@ g_field_info_get_type (GIFieldInfo *info) } /** - * g_field_info_get_field: + * g_field_info_get_field: (skip) * @field_info: a #GIFieldInfo * @mem: pointer to a block of memory representing a C structure or union * @value: a #GIArgument into which to store the value retrieved @@ -343,7 +343,7 @@ g_field_info_get_field (GIFieldInfo *field_info, } /** - * g_field_info_set_field: + * g_field_info_set_field: (skip) * @field_info: a #GIFieldInfo * @mem: pointer to a block of memory representing a C structure or union * @value: a #GIArgument holding the value to store diff --git a/gifunctioninfo.c b/gifunctioninfo.c index 9dd6daae7..2f8920de6 100644 --- a/gifunctioninfo.c +++ b/gifunctioninfo.c @@ -215,7 +215,7 @@ g_invoke_error_quark (void) } /** - * g_function_info_invoke: + * g_function_info_invoke: (skip) * @info: a #GIFunctionInfo describing the function to invoke * @in_args: an array of #GIArguments, one for each in * parameter of @info. If there are no in parameter, @in_args diff --git a/giobjectinfo.h b/giobjectinfo.h index 630def618..11c1c5ac3 100644 --- a/giobjectinfo.h +++ b/giobjectinfo.h @@ -31,17 +31,17 @@ G_BEGIN_DECLS /** - * GIObjectInfoRefFunction: + * GIObjectInfoRefFunction: (skip) * @object: object instance pointer * * Increases the reference count of an object instance. * - * Returns: the object instance + * Returns: (transfer full): the object instance */ typedef void * (*GIObjectInfoRefFunction) (void *object); /** - * GIObjectInfoUnrefFunction: + * GIObjectInfoUnrefFunction: (skip) * @object: object instance pointer * * Decreases the reference count of an object instance. @@ -50,7 +50,7 @@ typedef void * (*GIObjectInfoRefFunction) (void *object); typedef void (*GIObjectInfoUnrefFunction) (void *object); /** - * GIObjectInfoSetValueFunction: + * GIObjectInfoSetValueFunction: (skip) * @value: a #GValue * @object: object instance pointer * @@ -60,12 +60,12 @@ typedef void (*GIObjectInfoUnrefFunction) (void *object); typedef void (*GIObjectInfoSetValueFunction) (GValue *value, void *object); /** - * GIObjectInfoGetValueFunction: + * GIObjectInfoGetValueFunction: (skip) * @value: a #GValue * * Extract an object instance out of @value * - * Returns: the object instance + * Returns: (transfer full): the object instance */ typedef void * (*GIObjectInfoGetValueFunction) (const GValue *value); diff --git a/girepository.c b/girepository.c index a8c661ab7..0908099a7 100644 --- a/girepository.c +++ b/girepository.c @@ -1413,7 +1413,7 @@ static const GOptionEntry introspection_args[] = { }; /** - * g_irepository_get_option_group: + * g_irepository_get_option_group: (skip) * * Obtain the option group for girepository, it's used * by the dumper and for programs that wants to provide diff --git a/gistructinfo.c b/gistructinfo.c index aaecebbf2..ad1916830 100644 --- a/gistructinfo.c +++ b/gistructinfo.c @@ -25,6 +25,33 @@ #include "girepository-private.h" #include "gitypelib-internal.h" +/** + * SECTION:gistructinfo + * @Short_description: Struct representing a C structure + * @Title: GIStructInfo + * + * GIStructInfo represents a generic C structure type. + * + * A structure has methods and fields. + * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GIRegisteredTypeInfo + * +----GIStructInfo + * + * + */ + +/** + * g_struct_info_get_n_fields: + * @info: a #GIStructInfo + * + * Obtain the number of fields this structure has. + * + * Returns: number of fields + */ gint g_struct_info_get_n_fields (GIStructInfo *info) { @@ -34,6 +61,15 @@ g_struct_info_get_n_fields (GIStructInfo *info) return blob->n_fields; } +/** + * g_struct_info_get_field_offset: + * @info: a #GIStructInfo + * @n: index of queried field + * + * Obtain the offset of the specified field. + * + * Returns: field offset in bytes + */ static gint32 g_struct_get_field_offset (GIStructInfo *info, gint n) @@ -55,6 +91,16 @@ g_struct_get_field_offset (GIStructInfo *info, return offset; } +/** + * g_struct_info_get_field: + * @info: a #GIStructInfo + * @n: a field index + * + * Obtain the type information for field with specified index. + * + * Returns: (transfer full): the #GIFieldInfo, free it with g_base_info_unref() + * when done. + */ GIFieldInfo * g_struct_info_get_field (GIStructInfo *info, gint n) @@ -65,6 +111,14 @@ g_struct_info_get_field (GIStructInfo *info, g_struct_get_field_offset (info, n)); } +/** + * g_struct_info_get_n_methods: + * @info: a #GIStructInfo + * + * Obtain the number of methods this structure has. + * + * Returns: number of methods + */ gint g_struct_info_get_n_methods (GIStructInfo *info) { @@ -74,6 +128,16 @@ g_struct_info_get_n_methods (GIStructInfo *info) return blob->n_methods; } +/** + * g_struct_info_get_method: + * @info: a #GIStructInfo + * @n: a method index + * + * Obtain the type information for method with specified index. + * + * Returns: (transfer full): the #GIFunctionInfo, free it with g_base_info_unref() + * when done. + */ GIFunctionInfo * g_struct_info_get_method (GIStructInfo *info, gint n) @@ -88,6 +152,16 @@ g_struct_info_get_method (GIStructInfo *info, rinfo->typelib, offset); } +/** + * g_struct_info_find_method: + * @info: a #GIStructInfo + * @name: a method name + * + * Obtain the type information for method named @name. + * + * Returns: (transfer full): the #GIFunctionInfo, free it with g_base_info_unref() + * when done. + */ GIFunctionInfo * g_struct_info_find_method (GIStructInfo *info, const gchar *name) @@ -103,6 +177,14 @@ g_struct_info_find_method (GIStructInfo *info, return _g_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_methods, name); } +/** + * g_struct_info_get_size: + * @info: a #GIStructInfo + * + * Obtain the total size of the structure. + * + * Returns: size of the structure in bytes + */ gsize g_struct_info_get_size (GIStructInfo *info) { @@ -112,6 +194,14 @@ g_struct_info_get_size (GIStructInfo *info) return blob->size; } +/** + * g_struct_info_get_alignment: + * @info: a #GIStructInfo + * + * Obtain the required alignment of the structure. + * + * Returns: required alignment in bytes + */ gsize g_struct_info_get_alignment (GIStructInfo *info) { diff --git a/giunioninfo.c b/giunioninfo.c index 5db7c0472..15a4c7d14 100644 --- a/giunioninfo.c +++ b/giunioninfo.c @@ -25,6 +25,35 @@ #include "girepository-private.h" #include "gitypelib-internal.h" +/** + * SECTION:giunioninfo + * @Short_description: Struct representing a union. + * @Title: GIUnionInfo + * + * GIUnionInfo represents a union type. + * + * A union has methods and fields. Unions can optionally have a + * discriminator, which is a field deciding what type of real union + * fields is valid for specified instance. + * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GIRegisteredTypeInfo + * +----GIUnionInfo + * + * + */ + +/** + * g_union_info_get_n_fields: + * @info: a #GIUnionInfo + * + * Obtain the number of fields this union has. + * + * Returns: number of fields + */ gint g_union_info_get_n_fields (GIUnionInfo *info) { @@ -34,6 +63,16 @@ g_union_info_get_n_fields (GIUnionInfo *info) return blob->n_fields; } +/** + * g_union_info_get_field: + * @info: a #GIUnionInfo + * @n: a field index + * + * Obtain the type information for field with specified index. + * + * Returns: (transfer full): the #GIFieldInfo, free it with g_base_info_unref() + * when done. + */ GIFieldInfo * g_union_info_get_field (GIUnionInfo *info, gint n) @@ -46,6 +85,14 @@ g_union_info_get_field (GIUnionInfo *info, n * header->field_blob_size); } +/** + * g_union_info_get_n_methods: + * @info: a #GIUnionInfo + * + * Obtain the number of methods this union has. + * + * Returns: number of methods + */ gint g_union_info_get_n_methods (GIUnionInfo *info) { @@ -55,6 +102,16 @@ g_union_info_get_n_methods (GIUnionInfo *info) return blob->n_functions; } +/** + * g_union_info_get_method: + * @info: a #GIUnionInfo + * @n: a method index + * + * Obtain the type information for method with specified index. + * + * Returns: (transfer full): the #GIFunctionInfo, free it with g_base_info_unref() + * when done. + */ GIFunctionInfo * g_union_info_get_method (GIUnionInfo *info, gint n) @@ -71,6 +128,14 @@ g_union_info_get_method (GIUnionInfo *info, rinfo->typelib, offset); } +/** + * g_union_info_is_discriminated: + * @info: a #GIUnionInfo + * + * Return true if this union contains discriminator field. + * + * Returns: %TRUE if this is a discriminated union, %FALSE otherwise + */ gboolean g_union_info_is_discriminated (GIUnionInfo *info) { @@ -80,6 +145,14 @@ g_union_info_is_discriminated (GIUnionInfo *info) return blob->discriminated; } +/** + * g_union_info_get_discrimintor_offset: + * @info: a #GIUnionInfo + * + * Returns offset of the discriminator field in the structure. + * + * Returns: (transfer full): offset in bytes of the discriminator + */ gint g_union_info_get_discriminator_offset (GIUnionInfo *info) { @@ -89,6 +162,15 @@ g_union_info_get_discriminator_offset (GIUnionInfo *info) return blob->discriminator_offset; } +/** + * g_union_info_get_discriminator_type: + * @info: a #GIUnionInfo + * + * Obtain the type information of the union discriminator. + * + * Returns: (transfer full): the #GITypeInfo, free it with g_base_info_unref() + * when done. + */ GITypeInfo * g_union_info_get_discriminator_type (GIUnionInfo *info) { @@ -97,6 +179,18 @@ g_union_info_get_discriminator_type (GIUnionInfo *info) return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 24); } +/** + * g_union_info_get_discriminator: + * @info: a #GIUnionInfo + * @n: a union field index + * + * Obtain discriminator value assigned for n-th union field, i.e. n-th + * union field is the active one if discriminator contains this + * constant. + * + * Returns: (transfer full): the #GIConstantInfo, free it with g_base_info_unref() + * when done. + */ GIConstantInfo * g_union_info_get_discriminator (GIUnionInfo *info, gint n) @@ -121,6 +215,16 @@ g_union_info_get_discriminator (GIUnionInfo *info, return NULL; } +/** + * g_union_info_find_method: + * @info: a #GIUnionInfo + * @name: a method name + * + * Obtain the type information for method named @name. + * + * Returns: (transfer full): the #GIFunctionInfo, free it with g_base_info_unref() + * when done. + */ GIFunctionInfo * g_union_info_find_method (GIUnionInfo *info, const gchar *name) @@ -136,6 +240,14 @@ g_union_info_find_method (GIUnionInfo *info, return _g_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_functions, name); } +/** + * g_union_info_get_size: + * @info: a #GIUnionInfo + * + * Obtain the total size of the union. + * + * Returns: size of the union in bytes + */ gsize g_union_info_get_size (GIUnionInfo *info) { @@ -145,6 +257,14 @@ g_union_info_get_size (GIUnionInfo *info) return blob->size; } +/** + * g_union_info_get_alignment: + * @info: a #GIUnionInfo + * + * Obtain the required alignment of the union. + * + * Returns: required alignment in bytes + */ gsize g_union_info_get_alignment (GIUnionInfo *info) { From 8548baf3b9ef89f190f05c564593e9fa2d26590e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steve=20Fr=C3=A9cinaux?= Date: Sun, 29 Aug 2010 22:48:54 +0200 Subject: [PATCH 389/692] [VFuncBlob] Unknown struct offset should be 0xFFFF Documentation says about g_vfunc_get_offset(): "Obtain the offset of the function pointer in the class struct. The value 0xFFFF indicates that the struct offset is unknown." But g-ir-compiler did set the value to 0 when the offset is unknown. This patch fixes it. https://bugzilla.gnome.org/show_bug.cgi?id=628270 --- girparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index 53f1c415d..cff230576 100644 --- a/girparser.c +++ b/girparser.c @@ -2418,7 +2418,7 @@ start_vfunc (GMarkupParseContext *context, if (offset) vfunc->offset = atoi (offset); else - vfunc->offset = 0; + vfunc->offset = 0xFFFF; vfunc->invoker = g_strdup (invoker); From 30922b36c1770b6fbd2425d3b4d3d6fe1bbeba99 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 6 Sep 2010 11:23:01 +0200 Subject: [PATCH 390/692] Remove extra lines from the license comment --- gitypelib.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/gitypelib.h b/gitypelib.h index aadf6066e..2906a8f2c 100644 --- a/gitypelib.h +++ b/gitypelib.h @@ -7,8 +7,6 @@ * 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. -..skipping... - * 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 From 09afe7361dc8b6f0cde381ec4e7999b19d023dc1 Mon Sep 17 00:00:00 2001 From: Joe Marcus Clarke Date: Tue, 7 Sep 2010 11:42:49 -0300 Subject: [PATCH 391/692] [girepository] Support strict align platforms Such as Sparc64. https://bugzilla.gnome.org/show_bug.cgi?id=620769 --- giconstantinfo.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/giconstantinfo.c b/giconstantinfo.c index b6b67d1a8..0c40d8a74 100644 --- a/giconstantinfo.c +++ b/giconstantinfo.c @@ -64,6 +64,9 @@ g_constant_info_get_type (GIConstantInfo *info) return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 8); } +#define DO_ALIGNED_COPY(dest_addr, src_addr, type) \ + memcpy((dest_addr), (src_addr), sizeof(type)) + /** * g_constant_info_get_value: (skip) * @info: a #GIConstantInfo @@ -118,16 +121,16 @@ g_constant_info_get_value (GIConstantInfo *info, value->v_uint32 = *(guint32*)&rinfo->typelib->data[blob->offset]; break; case GI_TYPE_TAG_INT64: - value->v_int64 = *(gint64*)&rinfo->typelib->data[blob->offset]; + DO_ALIGNED_COPY(&value->v_int64, &rinfo->typelib->data[blob->offset], gint64); break; case GI_TYPE_TAG_UINT64: - value->v_uint64 = *(guint64*)&rinfo->typelib->data[blob->offset]; + DO_ALIGNED_COPY(&value->v_uint64, &rinfo->typelib->data[blob->offset], guint64); break; case GI_TYPE_TAG_FLOAT: - value->v_float = *(gfloat*)&rinfo->typelib->data[blob->offset]; + DO_ALIGNED_COPY(&value->v_float, &rinfo->typelib->data[blob->offset], gfloat); break; case GI_TYPE_TAG_DOUBLE: - value->v_double = *(gdouble*)&rinfo->typelib->data[blob->offset]; + DO_ALIGNED_COPY(&value->v_double, &rinfo->typelib->data[blob->offset], gdouble); break; } } From 2e360c3fb70a3b3b3dc3a46a05e9957f438db9ea Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 7 Sep 2010 14:56:57 -0300 Subject: [PATCH 392/692] [girepository] Add a missing include --- giconstantinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/giconstantinfo.c b/giconstantinfo.c index 0c40d8a74..c0823030d 100644 --- a/giconstantinfo.c +++ b/giconstantinfo.c @@ -20,6 +20,7 @@ */ #include +#include // memcpy #include #include "girepository-private.h" From 6bc078f1eef503608fa032518474d45c6570d1c0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 14 Sep 2010 12:31:58 -0400 Subject: [PATCH 393/692] typelib compiler: Passthrough at any point This should have been in the previous commit. --- girparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index cff230576..a89aea258 100644 --- a/girparser.c +++ b/girparser.c @@ -2123,7 +2123,7 @@ start_doc (GMarkupParseContext *context, ParseContext *ctx, GError **error) { - if (strcmp (element_name, "doc") != 0 || ctx->node_stack == NULL) + if (strcmp (element_name, "doc") != 0) return FALSE; state_switch (ctx, STATE_DOC); From c664ffed5f85e568dc1ab2e12146195fcc8b336e Mon Sep 17 00:00:00 2001 From: Pavel Holejsovsky Date: Fri, 3 Sep 2010 15:20:43 +0200 Subject: [PATCH 394/692] Box GIBaseInfo structure. This puts it into typelibs and allows to use it safely from scripts. https://bugzilla.gnome.org/show_bug.cgi?id=628753 --- gibaseinfo.c | 15 +++++++++++++++ gibaseinfo.h | 3 +++ 2 files changed, 18 insertions(+) diff --git a/gibaseinfo.c b/gibaseinfo.c index 07d05019a..057cde729 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -30,6 +30,21 @@ #define INVALID_REFCOUNT 0x7FFFFFFF +/* GBoxed registration of BaseInfo. */ +GType +g_base_info_gtype_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = + g_boxed_type_register_static ("GIBaseInfo", + (GBoxedCopyFunc) g_base_info_ref, + (GBoxedFreeFunc) g_base_info_unref); + + return our_type; +} + /* info creation */ GIBaseInfo * _g_info_new_full (GIInfoType type, diff --git a/gibaseinfo.h b/gibaseinfo.h index 106aadfff..7bb1cab09 100644 --- a/gibaseinfo.h +++ b/gibaseinfo.h @@ -58,6 +58,9 @@ typedef struct { gpointer data4; } GIAttributeIter; +#define GI_TYPE_BASE_INFO (g_base_info_gtype_get_type ()) + +GType g_base_info_gtype_get_type (void) G_GNUC_CONST; GIBaseInfo * g_base_info_ref (GIBaseInfo *info); void g_base_info_unref (GIBaseInfo *info); GIInfoType g_base_info_get_type (GIBaseInfo *info); From 916798b704adf5c9543aa51ef023f62bcac17116 Mon Sep 17 00:00:00 2001 From: Pavel Holejsovsky Date: Fri, 10 Sep 2010 14:33:15 +0200 Subject: [PATCH 395/692] Update annotations for GIRepository.Repository. https://bugzilla.gnome.org/show_bug.cgi?id=628753 --- girepository.c | 26 +++++++++++++------------- gitypelib.c | 6 +++--- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/girepository.c b/girepository.c index 0908099a7..7a768a9a0 100644 --- a/girepository.c +++ b/girepository.c @@ -374,7 +374,7 @@ register_internal (GIRepository *repository, /** * g_irepository_get_dependencies: - * @repository: A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository, may be %NULL for the default * @namespace_: Namespace of interest * * Return an array of all (transitive) dependencies for namespace @@ -440,7 +440,7 @@ g_irepository_load_typelib (GIRepository *repository, /** * g_irepository_is_registered: - * @repository: A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository, may be %NULL for the default * @namespace_: Namespace of interest * @version: (allow-none): Required version, may be %NULL for latest * @@ -486,7 +486,7 @@ g_irepository_get_default (void) /** * g_irepository_get_n_infos: - * @repository: A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository, may be %NULL for the default * @namespace_: Namespace to inspect * * This function returns the number of metadata entries in @@ -619,7 +619,7 @@ find_interface (gpointer key, /** * g_irepository_get_info: - * @repository: A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository, may be %NULL for the default * @namespace_: Namespace to inspect * @index: Offset into namespace metadata for entry * @@ -658,7 +658,7 @@ g_irepository_get_info (GIRepository *repository, /** * g_irepository_find_by_gtype: - * @repository: A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository, may be %NULL for the default * @gtype: GType to search for * * Searches all loaded namespaces for a particular #GType. Note that @@ -712,7 +712,7 @@ g_irepository_find_by_gtype (GIRepository *repository, /** * g_irepository_find_by_name: - * @repository: A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository, may be %NULL for the default * @namespace_: Namespace which will be searched * @name: Entry name to find * @@ -762,7 +762,7 @@ collect_namespaces (gpointer key, /** * g_irepository_get_loaded_namespaces: - * @repository: A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository, may be %NULL for the default * * Return the list of currently loaded namespaces. * @@ -791,7 +791,7 @@ g_irepository_get_loaded_namespaces (GIRepository *repository) /** * g_irepository_get_version: - * @repository: A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository, may be %NULL for the default * @namespace_: Namespace to inspect * * This function returns the loaded version associated with the given @@ -823,7 +823,7 @@ g_irepository_get_version (GIRepository *repository, /** * g_irepository_get_shared_library: - * @repository: A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository, may be %NULL for the default * @namespace_: Namespace to inspect * * This function returns the full path to the shared C library @@ -860,7 +860,7 @@ g_irepository_get_shared_library (GIRepository *repository, /** * g_irepository_get_c_prefix - * @repository: A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository, may be %NULL for the default * @namespace_: Namespace to inspect * * This function returns the "C prefix", or the C level namespace @@ -896,7 +896,7 @@ g_irepository_get_c_prefix (GIRepository *repository, /** * g_irepository_get_typelib_path - * @repository: Repository, may be %NULL for the default + * @repository: (allow-none): Repository, may be %NULL for the default * @namespace_: GI namespace to use, e.g. "Gtk" * * If namespace @namespace_ is loaded, return the full path to the @@ -1337,7 +1337,7 @@ require_internal (GIRepository *repository, * version @version of namespace may be specified. If @version is * not specified, the latest will be used. * - * Returns: (transfer full): a pointer to the #GITypelib if successful, %NULL otherwise + * Returns: (transfer none): a pointer to the #GITypelib if successful, %NULL otherwise */ GITypelib * g_irepository_require (GIRepository *repository, @@ -1372,7 +1372,7 @@ g_irepository_require (GIRepository *repository, * version @version of namespace should be specified. If @version is * not specified, the latest will be used. * - * Returns: (transfer full): a pointer to the #GITypelib if successful, %NULL otherwise + * Returns: (transfer none): a pointer to the #GITypelib if successful, %NULL otherwise */ GITypelib * g_irepository_require_private (GIRepository *repository, diff --git a/gitypelib.c b/gitypelib.c index faeb3fc98..9e818b999 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -2069,7 +2069,7 @@ _g_typelib_ensure_open (GITypelib *typelib) } /** - * g_typelib_new_from_memory: + * g_typelib_new_from_memory: (skip) * @memory: address of memory chunk containing the typelib * @len: length of memory chunk containing the typelib * @error: a #GError @@ -2100,7 +2100,7 @@ g_typelib_new_from_memory (guint8 *memory, } /** - * g_typelib_new_from_const_memory: + * g_typelib_new_from_const_memory: (skip) * @memory: address of memory chunk containing the typelib * @len: length of memory chunk containing the typelib * @error: A #GError @@ -2129,7 +2129,7 @@ g_typelib_new_from_const_memory (const guchar *memory, } /** - * g_typelib_new_from_mapped_file: + * g_typelib_new_from_mapped_file: (skip) * @mfile: a #GMappedFile, that will be free'd when the repository is destroyed * @error: a #GError * From 508edb91ad2cd2b245740c6e44b2824689bea1a4 Mon Sep 17 00:00:00 2001 From: Pavel Holejsovsky Date: Sat, 25 Sep 2010 07:12:07 +0200 Subject: [PATCH 396/692] Fix memory leak. --- girepository.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/girepository.c b/girepository.c index 7a768a9a0..712118dc5 100644 --- a/girepository.c +++ b/girepository.c @@ -1094,13 +1094,19 @@ enumerate_namespace_versions (const gchar *namespace, last_dash = strrchr (entry, '-'); version = g_strndup (last_dash+1, name_end-(last_dash+1)); if (!parse_version (version, &major, &minor)) - continue; + { + g_free (version); + continue; + } } else continue; if (g_hash_table_lookup (found_versions, version) != NULL) - continue; + { + g_free (version); + continue; + } g_hash_table_insert (found_versions, version, version); path = g_build_filename (dirname, entry, NULL); From 9468bd36c9985b80e651eb5dd405fa0c3ab0e037 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 27 Sep 2010 11:52:55 +0200 Subject: [PATCH 397/692] Actually do something about fundamentals when parsing a .gir https://bugzilla.gnome.org/show_bug.cgi?id=630710 --- girparser.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/girparser.c b/girparser.c index a89aea258..8f8f6f4da 100644 --- a/girparser.c +++ b/girparser.c @@ -1791,6 +1791,8 @@ start_class (GMarkupParseContext *context, iface->abstract = abstract && strcmp (abstract, "1") == 0; + if (fundamental) + iface->fundamental = TRUE; if (ref_func) iface->ref_func = g_strdup (ref_func); if (unref_func) From 26841c0b512de6d4ce9b4d39acfc441d760ee834 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 30 Sep 2010 10:44:12 -0400 Subject: [PATCH 398/692] scanner: Don't link to -lgirepository when dumping This helps us avoid a problematic case where in say jhbuild, using a system (/usr/lib) glib, adding in -l girepository-1.0 will inject -L /path/to/builddir, when we don't want that. https://bugzilla.gnome.org/show_bug.cgi?id=630342 --- Makefile.am | 4 +++- gdump.c | 9 ++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index e0f2b1bab..168732208 100644 --- a/Makefile.am +++ b/Makefile.am @@ -53,7 +53,7 @@ libgirepository_1_0_la_SOURCES = \ giunioninfo.c \ givfuncinfo.c -libgirepository_1_0_la_CPPFLAGS = $(GIREPO_CFLAGS) +libgirepository_1_0_la_CPPFLAGS = $(GIREPO_CFLAGS) -DG_IREPOSITORY_COMPILATION libgirepository_1_0_la_LIBADD = $(GIREPO_LIBS) libgirepository_1_0_la_LDFLAGS = -no-undefined -version-number 1:0:0 @@ -69,3 +69,5 @@ libgirepository_parser_la_SOURCES = \ girwriter.h libgirepository_parser_la_CFLAGS = $(GIREPO_CFLAGS) +gdumpdir = $(datadir)/gobject-introspection-1.0/ +gdump_DATA = gdump.c diff --git a/gdump.c b/gdump.c index 84ac3c718..166a9e72a 100644 --- a/gdump.c +++ b/gdump.c @@ -24,8 +24,15 @@ #include #include -#include "girepository.h" +/* This file is both compiled into libgirepository.so, and installed + * on the filesystem. But for the dumper, we want to avoid linking + * to libgirepository; see + * https://bugzilla.gnome.org/show_bug.cgi?id=630342 + */ +#ifdef G_IREPOSITORY_COMPILATION #include "config.h" +#include "girepository.h" +#endif #include From 795116b391f3309621a87179263449f26f720acd Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 1 Oct 2010 12:44:08 -0400 Subject: [PATCH 399/692] dumper: Make g_irepository_dump static when being used in dumper Otherwise we'll bomb out if CFLAGS contains -Werror. --- gdump.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gdump.c b/gdump.c index 166a9e72a..cdede612b 100644 --- a/gdump.c +++ b/gdump.c @@ -380,6 +380,9 @@ dump_type (GType type, const char *symbol, GOutputStream *out) * * Returns: %TRUE on success, %FALSE on error */ +#ifndef G_IREPOSITORY_COMPILATION +static +#endif gboolean g_irepository_dump (const char *arg, GError **error) { From b31fdc51522ea5b73d8e3de9ce3bad65455a54cb Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Wed, 6 Oct 2010 12:51:44 -0300 Subject: [PATCH 400/692] Improve documentation for g_registered_type_info_get_g_type --- giregisteredtypeinfo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/giregisteredtypeinfo.c b/giregisteredtypeinfo.c index cc43d284e..ca06b9f83 100644 --- a/giregisteredtypeinfo.c +++ b/giregisteredtypeinfo.c @@ -114,7 +114,10 @@ g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info) * g_registered_type_info_get_g_type: * @info: a #GIRegisteredTypeInfo * - * Obtain the #GType for this registered type. + * Obtain the #GType for this registered type or G_TYPE_NONE which a special meaning. + * It means that either there is no type information associated with this @info or + * that the shared library which provides the type_init function for this + * @info cannot be called. * * Returns: the #GType. */ From 8d9a9838487c68fc5b6f35ecf2d9582137333fae Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 11 Oct 2010 12:40:15 -0400 Subject: [PATCH 401/692] typelib: Don't fail on minor version Previously we bombed out if the minor version didn't match what we expected; this was silly since the whole point of the minor version is to enumerate compatible changes. --- gitypelib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitypelib.c b/gitypelib.c index 9e818b999..cab697a25 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -288,7 +288,7 @@ validate_header_basic (const guint8 *memory, } - if (header->major_version != 4 || header->minor_version != 0) + if (header->major_version != 4) { g_set_error (error, G_TYPELIB_ERROR, From 54a1a7be490852a32ac01fdc9451011650fa9d26 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 18 Oct 2010 12:04:08 -0400 Subject: [PATCH 402/692] girepository: Refactor lookup code This is a cleanup patch in preparation for future indexing patches. The lookup code was a mess trying to mash in the 3 different cases of name, GType, and index into one mega-function. Split it up properly, and move the core typelib internal-scanning bits into gitypelib.c where it belongs. --- girepository.c | 213 ++++++++++++++----------------------------- gitypelib-internal.h | 7 ++ gitypelib.c | 74 +++++++++++++++ 3 files changed, 149 insertions(+), 145 deletions(-) diff --git a/girepository.c b/girepository.c index 712118dc5..18ecafbe5 100644 --- a/girepository.c +++ b/girepository.c @@ -515,108 +515,6 @@ g_irepository_get_n_infos (GIRepository *repository, return n_interfaces; } -typedef struct -{ - GIRepository *repo; - gint index; - const gchar *name; - gboolean type_firstpass; - const gchar *type; - GIBaseInfo *iface; -} IfaceData; - -static void -find_interface (gpointer key, - gpointer value, - gpointer data) -{ - gint i; - GITypelib *typelib = (GITypelib *)value; - Header *header = (Header *) typelib->data; - IfaceData *iface_data = (IfaceData *)data; - gint index; - gint n_entries; - const gchar *name; - const gchar *type; - DirEntry *entry; - - index = 0; - n_entries = ((Header *)typelib->data)->n_local_entries; - - if (iface_data->name) - { - for (i = 1; i <= n_entries; i++) - { - entry = g_typelib_get_dir_entry (typelib, i); - name = g_typelib_get_string (typelib, entry->name); - if (strcmp (name, iface_data->name) == 0) - { - index = i; - break; - } - } - } - else if (iface_data->type) - { - const char *c_prefix; - /* Inside each typelib, we include the "C prefix" which acts as - * a namespace mechanism. For GtkTreeView, the C prefix is Gtk. - * Given the assumption that GTypes for a library also use the - * C prefix, we know we can skip examining a typelib if our - * target type does not have this typelib's C prefix. - * - * However, not every class library necessarily conforms to this, - * e.g. Clutter has Cogl inside it. So, we split this into two - * passes. First we try a lookup, skipping things which don't - * have the prefix. If that fails then we try a global lookup, - * ignoring the prefix. - * - * See http://bugzilla.gnome.org/show_bug.cgi?id=564016 - */ - c_prefix = g_typelib_get_string (typelib, header->c_prefix); - if (iface_data->type_firstpass && c_prefix != NULL) - { - if (g_ascii_strncasecmp (c_prefix, iface_data->type, strlen (c_prefix)) != 0) - return; - } - - for (i = 1; i <= n_entries; i++) - { - RegisteredTypeBlob *blob; - - entry = g_typelib_get_dir_entry (typelib, i); - if (!BLOB_IS_REGISTERED_TYPE (entry)) - continue; - - blob = (RegisteredTypeBlob *)(&typelib->data[entry->offset]); - if (!blob->gtype_name) - continue; - - type = g_typelib_get_string (typelib, blob->gtype_name); - if (strcmp (type, iface_data->type) == 0) - { - index = i; - break; - } - } - } - else if (iface_data->index > n_entries) - iface_data->index -= n_entries; - else if (iface_data->index > 0) - { - index = iface_data->index; - iface_data->index = 0; - } - - if (index != 0) - { - entry = g_typelib_get_dir_entry (typelib, index); - iface_data->iface = _g_info_new_full (entry->blob_type, - iface_data->repo, - NULL, typelib, entry->offset); - } -} - /** * g_irepository_get_info: * @repository: (allow-none): A #GIRepository, may be %NULL for the default @@ -634,26 +532,48 @@ g_irepository_get_info (GIRepository *repository, const gchar *namespace, gint index) { - IfaceData data; GITypelib *typelib; + DirEntry *entry; g_return_val_if_fail (namespace != NULL, NULL); repository = get_repository (repository); - data.repo = repository; - data.name = NULL; - data.type = NULL; - data.index = index + 1; - data.iface = NULL; - typelib = get_registered (repository, namespace, NULL); g_return_val_if_fail (typelib != NULL, NULL); - find_interface ((void *)namespace, typelib, &data); + entry = g_typelib_get_dir_entry (typelib, index); + if (entry == NULL) + return NULL; + return _g_info_new_full (entry->blob_type, + repository, + NULL, typelib, entry->offset); +} - return data.iface; +typedef struct { + GIRepository *repository; + GType type; + + gboolean fastpass; + GITypelib *result_typelib; + DirEntry *result; +} FindByGTypeData; + +static void +find_by_gtype_foreach (gpointer key, + gpointer value, + gpointer datap) +{ + GITypelib *typelib = (GITypelib*)value; + FindByGTypeData *data = datap; + + if (data->result != NULL) + return; + + data->result = g_typelib_get_dir_entry_by_gtype (typelib, data->fastpass, data->type); + if (data->result) + data->result_typelib = typelib; } /** @@ -674,40 +594,48 @@ GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository, GType gtype) { - IfaceData data; + FindByGTypeData data; + GIBaseInfo *cached; repository = get_repository (repository); - data.iface = g_hash_table_lookup (repository->priv->info_by_gtype, - (gpointer)gtype); + cached = g_hash_table_lookup (repository->priv->info_by_gtype, + (gpointer)gtype); - if (data.iface) - return g_base_info_ref (data.iface); + if (cached != NULL) + return g_base_info_ref (cached); - data.repo = repository; - data.name = NULL; - data.type_firstpass = TRUE; - data.type = g_type_name (gtype); - data.index = -1; - data.iface = NULL; + data.repository = repository; + data.fastpass = TRUE; + data.type = gtype; + data.result_typelib = NULL; + data.result = NULL; - g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); - g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data); + g_hash_table_foreach (repository->priv->typelibs, find_by_gtype_foreach, &data); + if (data.result == NULL) + g_hash_table_foreach (repository->priv->lazy_typelibs, find_by_gtype_foreach, &data); /* We do two passes; see comment in find_interface */ - if (!data.iface) + if (data.result == NULL) { - data.type_firstpass = FALSE; - g_hash_table_foreach (repository->priv->typelibs, find_interface, &data); - g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data); + data.fastpass = FALSE; + g_hash_table_foreach (repository->priv->typelibs, find_by_gtype_foreach, &data); } + if (data.result == NULL) + g_hash_table_foreach (repository->priv->lazy_typelibs, find_by_gtype_foreach, &data); - if (data.iface) - g_hash_table_insert (repository->priv->info_by_gtype, - (gpointer) gtype, - g_base_info_ref (data.iface)); + if (data.result != NULL) + { + cached = _g_info_new_full (data.result->blob_type, + repository, + NULL, data.result_typelib, data.result->offset); - return data.iface; + g_hash_table_insert (repository->priv->info_by_gtype, + (gpointer) gtype, + g_base_info_ref (cached)); + return cached; + } + return NULL; } /** @@ -728,26 +656,21 @@ g_irepository_find_by_name (GIRepository *repository, const gchar *namespace, const gchar *name) { - IfaceData data; GITypelib *typelib; + DirEntry *entry; g_return_val_if_fail (namespace != NULL, NULL); repository = get_repository (repository); - - data.repo = repository; - data.name = name; - data.type = NULL; - data.index = -1; - data.iface = NULL; - typelib = get_registered (repository, namespace, NULL); - g_return_val_if_fail (typelib != NULL, NULL); - find_interface ((void *)namespace, typelib, &data); - - return data.iface; + entry = g_typelib_get_dir_entry_by_name (typelib, name); + if (entry == NULL) + return NULL; + return _g_info_new_full (entry->blob_type, + repository, + NULL, typelib, entry->offset); } static void diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 87a181700..26fd6bfbf 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -1100,6 +1100,13 @@ struct _GITypelib { DirEntry *g_typelib_get_dir_entry (GITypelib *typelib, guint16 index); +DirEntry *g_typelib_get_dir_entry_by_name (GITypelib *typelib, + const char *name); + +DirEntry *g_typelib_get_dir_entry_by_gtype (GITypelib *typelib, + gboolean fastpass, + GType gtype); + void g_typelib_check_sanity (void); #define g_typelib_get_string(typelib,offset) ((const gchar*)&(typelib->data)[(offset)]) diff --git a/gitypelib.c b/gitypelib.c index cab697a25..4f8517026 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -139,6 +139,80 @@ g_typelib_get_dir_entry (GITypelib *typelib, return (DirEntry *)&typelib->data[header->directory + (index - 1) * header->entry_blob_size]; } +DirEntry * +g_typelib_get_dir_entry_by_name (GITypelib *typelib, + const char *name) +{ + Header *header = (Header *)typelib->data; + guint n_entries = header->n_local_entries; + DirEntry *entry; + guint i; + + for (i = 1; i <= n_entries; i++) + { + const char *entry_name; + + entry = g_typelib_get_dir_entry (typelib, i); + entry_name = g_typelib_get_string (typelib, entry->name); + if (strcmp (name, entry_name) == 0) + return entry; + } + return NULL; +} + +DirEntry * +g_typelib_get_dir_entry_by_gtype (GITypelib *typelib, + gboolean fastpass, + GType gtype) +{ + Header *header = (Header *)typelib->data; + guint n_entries = header->n_local_entries; + const char *gtype_name = g_type_name (gtype); + DirEntry *entry; + guint i; + const char *c_prefix; + + /* Inside each typelib, we include the "C prefix" which acts as + * a namespace mechanism. For GtkTreeView, the C prefix is Gtk. + * Given the assumption that GTypes for a library also use the + * C prefix, we know we can skip examining a typelib if our + * target type does not have this typelib's C prefix. + * + * However, not every class library necessarily conforms to this, + * e.g. Clutter has Cogl inside it. So, we split this into two + * passes. First we try a lookup, skipping things which don't + * have the prefix. If that fails then we try a global lookup, + * ignoring the prefix. + * + * See http://bugzilla.gnome.org/show_bug.cgi?id=564016 + */ + c_prefix = g_typelib_get_string (typelib, header->c_prefix); + if (fastpass && c_prefix != NULL) + { + if (g_ascii_strncasecmp (c_prefix, gtype_name, strlen (c_prefix)) != 0) + return NULL; + } + + for (i = 1; i <= n_entries; i++) + { + RegisteredTypeBlob *blob; + const char *type; + + entry = g_typelib_get_dir_entry (typelib, i); + if (!BLOB_IS_REGISTERED_TYPE (entry)) + continue; + + blob = (RegisteredTypeBlob *)(&typelib->data[entry->offset]); + if (!blob->gtype_name) + continue; + + type = g_typelib_get_string (typelib, blob->gtype_name); + if (strcmp (type, gtype_name) == 0) + return entry; + } + return NULL; +} + void g_typelib_check_sanity (void) { From 3d7bb7feaf2ee8bf96ec4dfa2d7c835c4ad0505a Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 21 Oct 2010 14:59:42 -0400 Subject: [PATCH 403/692] Fix regression in g_irepository_get_info Commit f97cc8687469f25752f79275 broke the lookup in g_irepository_get_info; the passed offset is 0-based, then we convert it to 1-based (and then back to 0 later...which needs to be fixed). --- girepository.c | 6 ++++-- girwriter.c | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/girepository.c b/girepository.c index 18ecafbe5..7ac407a1a 100644 --- a/girepository.c +++ b/girepository.c @@ -519,11 +519,13 @@ g_irepository_get_n_infos (GIRepository *repository, * g_irepository_get_info: * @repository: (allow-none): A #GIRepository, may be %NULL for the default * @namespace_: Namespace to inspect - * @index: Offset into namespace metadata for entry + * @index: 0-based offset into namespace metadata for entry * * This function returns a particular metadata entry in the * given namespace @namespace_. The namespace must have * already been loaded before calling this function. + * See g_irepository_get_n_infos() to find the maximum number of + * entries. * * Returns: (transfer full): #GIBaseInfo containing metadata */ @@ -543,7 +545,7 @@ g_irepository_get_info (GIRepository *repository, g_return_val_if_fail (typelib != NULL, NULL); - entry = g_typelib_get_dir_entry (typelib, index); + entry = g_typelib_get_dir_entry (typelib, index + 1); if (entry == NULL) return NULL; return _g_info_new_full (entry->blob_type, diff --git a/girwriter.c b/girwriter.c index 48f1a5d21..8c4fa2c35 100644 --- a/girwriter.c +++ b/girwriter.c @@ -1349,6 +1349,7 @@ gir_writer_write (const char *filename, const gchar *c_prefix; const char *ns = namespace; const char *version; + gint n_infos; version = g_irepository_get_version (repository, ns); @@ -1361,7 +1362,8 @@ gir_writer_write (const char *filename, if (c_prefix) xml_printf (xml, " c:prefix=\"%s\"", c_prefix); - for (j = 0; j < g_irepository_get_n_infos (repository, ns); j++) + n_infos = g_irepository_get_n_infos (repository, ns); + for (j = 0; j < n_infos; j++) { GIBaseInfo *info = g_irepository_get_info (repository, ns, j); switch (g_base_info_get_type (info)) From aa154a1776dd694eaec9abaf305c36340f217824 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 26 Oct 2010 10:03:29 -0400 Subject: [PATCH 404/692] girepository: Use G_TYPE_TAG_IS_BASIC consistently This is a preparatory patch for adding a new basic tag. --- girnode.c | 8 +++----- gitypelib.c | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/girnode.c b/girnode.c index 2f6a27090..46fd3c7d9 100644 --- a/girnode.c +++ b/girnode.c @@ -636,7 +636,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeType *type = (GIrNodeType *)node; size = sizeof (SimpleTypeBlob); - if (type->tag >= GI_TYPE_TAG_ARRAY) + if (!G_TYPE_TAG_IS_BASIC(type->tag)) { g_debug ("node %p type tag '%s'", node, g_type_tag_to_string (type->tag)); @@ -1220,7 +1220,7 @@ serialize_type (GIrTypelibBuild *build, { gint i; - if (node->tag < GI_TYPE_TAG_ARRAY) + if (G_TYPE_TAG_IS_BASIC(node->tag)) { g_string_append_printf (str, "%s%s", g_type_tag_to_string (node->tag), node->is_pointer ? "*" : ""); @@ -1415,9 +1415,7 @@ g_ir_node_build_typelib (GIrNode *node, *offset += sizeof (SimpleTypeBlob); - if (type->tag < GI_TYPE_TAG_ARRAY || - type->tag == GI_TYPE_TAG_UTF8 || - type->tag == GI_TYPE_TAG_FILENAME) + if (G_TYPE_TAG_IS_BASIC(type->tag)) { blob->flags.reserved = 0; blob->flags.reserved2 = 0; diff --git a/gitypelib.c b/gitypelib.c index 4f8517026..4d119b731 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -642,7 +642,7 @@ validate_type_blob (GITypelib *typelib, if (simple->flags.reserved == 0 && simple->flags.reserved2 == 0) { - if (simple->flags.tag >= GI_TYPE_TAG_ARRAY) + if (!G_TYPE_TAG_IS_BASIC(simple->flags.tag)) { g_set_error (error, G_TYPELIB_ERROR, From 7fa7162361237770d77ad0c533ade4e65745daad Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Tue, 14 Sep 2010 14:17:35 -0400 Subject: [PATCH 405/692] Compute enumeration storage types more accurately Previously we just were sloppy and didn't bother to accurately compute signed/unsigned for enumeration types. But since we expect bindings to decode a field value or function return value from an integer to an enumeration they have know whether an integer value is 0xffffffff or -1, so we need to do the full computation. https://bugzilla.gnome.org/show_bug.cgi?id=629704 --- giroffsets.c | 86 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 25 deletions(-) diff --git a/giroffsets.c b/giroffsets.c index bcac716c3..94fdc6646 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -23,9 +23,9 @@ #include /* The C standard specifies that an enumeration can be any char or any signed - * or unsigned integer type capable of resresenting all the values of the + * or unsigned integer type capable of representing all the values of the * enumeration. We use test enumerations to figure out what choices the - * compiler makes. + * compiler makes. (Ignoring > 32 bit enumerations) */ typedef enum { @@ -52,24 +52,26 @@ typedef enum { ENUM_6 = ((guint)G_MAXINT) + 1 /* compiler could use uint32 */ } Enum6; -/* GIrNodeValue has guint32 values, so if it matters to the ABI whether - * constant values are signed, we are in trouble. And we don't handle - * enums with > 32 bit values. */ - -#if 0 typedef enum { ENUM_7 = -1 /* compiler could use int8, int16, int32 */ } Enum7; -/* etc... */ -#endif +typedef enum { + ENUM_8 = -129 /* compiler could use int16, int32 */ +} Enum8; + +typedef enum { + ENUM_9 = G_MINSHORT - 1 /* compiler could use int32 */ +} Enum9; static void compute_enum_storage_type (GIrNodeEnum *enum_node) { GList *l; - gint32 max_value = 0; + gint64 max_value = 0; + gint64 min_value = 0; int width; + gboolean signed_type; if (enum_node->storage_type != GI_TYPE_TAG_VOID) /* already done */ return; @@ -79,29 +81,63 @@ compute_enum_storage_type (GIrNodeEnum *enum_node) GIrNodeValue *value = l->data; if (value->value > max_value) max_value = value->value; + if (value->value < min_value) + min_value = value->value; } - if (max_value < 128) - width = sizeof (Enum1); - else if (max_value < 256) - width = sizeof (Enum2); - else if (max_value < G_MAXSHORT) - width = sizeof (Enum3); - else if (max_value < G_MAXUSHORT) - width = sizeof (Enum4); - else if (max_value < G_MAXINT) - width = sizeof (Enum5); + if (min_value < 0) + { + signed_type = TRUE; + + if (min_value > -128 && max_value <= 127) + width = sizeof(Enum7); + else if (min_value >= G_MINSHORT && max_value <= G_MAXSHORT) + width = sizeof(Enum8); + else + width = sizeof(Enum9); + } else - width = sizeof (Enum6); + { + if (max_value <= 127) + { + width = sizeof (Enum1); + signed_type = (gint64)(Enum1)(-1) < 0; + } + else if (max_value <= 255) + { + width = sizeof (Enum2); + signed_type = (gint64)(Enum2)(-1) < 0; + } + else if (max_value <= G_MAXSHORT) + { + width = sizeof (Enum3); + signed_type = (gint64)(Enum3)(-1) < 0; + } + else if (max_value <= G_MAXUSHORT) + { + width = sizeof (Enum4); + signed_type = (gint64)(Enum4)(-1) < 0; + } + else if (max_value <= G_MAXINT) + { + width = sizeof (Enum5); + signed_type = (gint64)(Enum5)(-1) < 0; + } + else + { + width = sizeof (Enum6); + signed_type = (gint64)(Enum6)(-1) < 0; + } + } if (width == 1) - enum_node->storage_type = GI_TYPE_TAG_UINT8; + enum_node->storage_type = signed_type ? GI_TYPE_TAG_INT8 : GI_TYPE_TAG_UINT8; else if (width == 2) - enum_node->storage_type = GI_TYPE_TAG_UINT16; + enum_node->storage_type = signed_type ? GI_TYPE_TAG_INT16 : GI_TYPE_TAG_UINT16; else if (width == 4) - enum_node->storage_type = GI_TYPE_TAG_UINT32; + enum_node->storage_type = signed_type ? GI_TYPE_TAG_INT32 : GI_TYPE_TAG_UINT32; else if (width == 8) - enum_node->storage_type = GI_TYPE_TAG_UINT64; + enum_node->storage_type = signed_type ? GI_TYPE_TAG_INT64 : GI_TYPE_TAG_UINT64; else g_error ("Unexpected enum width %d", width); } From ec76ea86285cd3bec63f6e19f4c5ccffe5d9d865 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Tue, 14 Sep 2010 11:59:03 -0400 Subject: [PATCH 406/692] Handle enumerations with the full range of signed and unsigned values The C compiler will pick an enumeration type that accomodates the specified values for the enumeration, so ignoring 64-bit enumerations, we can have enumeration values from MININT32 to MAXUINT32. To handle this properly: - Use gint64 for holding eumeration values when scanning - Add a 'unsigned_value' bit to ValueBlob so we can distinguish the int32 vs. uint32 cases in the typelib - Change the return value of g_value_info_get_value() to gint64. https://bugzilla.gnome.org/show_bug.cgi?id=629704 --- gienuminfo.c | 11 ++++++++--- gienuminfo.h | 2 +- gifieldinfo.c | 6 +++--- girnode.c | 3 ++- girnode.h | 2 +- girparser.c | 10 +++++----- girwriter.c | 7 +++++-- gitypelib-internal.h | 4 +++- 8 files changed, 28 insertions(+), 17 deletions(-) diff --git a/gienuminfo.c b/gienuminfo.c index 9ecbc2aba..062f3abf2 100644 --- a/gienuminfo.c +++ b/gienuminfo.c @@ -127,9 +127,11 @@ g_enum_info_get_storage_type (GIEnumInfo *info) * * Obtain the enumeration value of the #GIValueInfo. * - * Returns: the enumeration value + * Returns: the enumeration value. This will always be representable + * as a 32-bit signed or unsigned value. The use of gint64 as the + * return type is to allow both. */ -glong +gint64 g_value_info_get_value (GIValueInfo *info) { GIRealInfo *rinfo = (GIRealInfo *)info; @@ -140,6 +142,9 @@ g_value_info_get_value (GIValueInfo *info) blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset]; - return (glong)blob->value; + if (blob->unsigned_value) + return (gint64)(guint32)blob->value; + else + return (gint64)blob->value; } diff --git a/gienuminfo.h b/gienuminfo.h index 211ea6efb..6b24fe7ef 100644 --- a/gienuminfo.h +++ b/gienuminfo.h @@ -42,7 +42,7 @@ GIValueInfo * g_enum_info_get_value (GIEnumInfo *info, gint n); GITypeTag g_enum_info_get_storage_type (GIEnumInfo *info); -glong g_value_info_get_value (GIValueInfo *info); +gint64 g_value_info_get_value (GIValueInfo *info); G_END_DECLS diff --git a/gifieldinfo.c b/gifieldinfo.c index 21a6db021..1a6b688c3 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -269,9 +269,9 @@ g_field_info_get_field (GIFieldInfo *field_info, case GI_INFO_TYPE_FLAGS: { /* FIXME: there's a mismatch here between the value->v_int we use - * here and the glong result returned from g_value_info_get_value(). - * But to switch this to glong, we'd have to make g_function_info_invoke() - * translate value->v_long to the proper ABI for an enum function + * here and the gint64 result returned from g_value_info_get_value(). + * But to switch this to gint64, we'd have to make g_function_info_invoke() + * translate value->v_int64 to the proper ABI for an enum function * call parameter, which will usually be int, and then fix up language * bindings. */ diff --git a/girnode.c b/girnode.c index 46fd3c7d9..5b9df585d 100644 --- a/girnode.c +++ b/girnode.c @@ -2201,8 +2201,9 @@ g_ir_node_build_typelib (GIrNode *node, blob->deprecated = value->deprecated; blob->reserved = 0; + blob->unsigned_value = value->value >= 0 ? 1 : 0; blob->name = write_string (node->name, strings, data, offset2); - blob->value = value->value; + blob->value = (gint32)value->value; } break; diff --git a/girnode.h b/girnode.h index edb94008f..0df100880 100644 --- a/girnode.h +++ b/girnode.h @@ -262,7 +262,7 @@ struct _GIrNodeValue gboolean deprecated; - gint32 value; + gint64 value; }; struct _GIrNodeConstant diff --git a/girparser.c b/girparser.c index 8f8f6f4da..42525ecde 100644 --- a/girparser.c +++ b/girparser.c @@ -1440,7 +1440,7 @@ start_property (GMarkupParseContext *context, return TRUE; } -static gint +static gint64 parse_value (const gchar *str) { gchar *shift_op; @@ -1450,15 +1450,15 @@ parse_value (const gchar *str) if (shift_op) { - gint base, shift; + gint64 base, shift; - base = strtol (str, NULL, 10); - shift = strtol (shift_op + 3, NULL, 10); + base = g_ascii_strtoll (str, NULL, 10); + shift = g_ascii_strtoll (shift_op + 3, NULL, 10); return base << shift; } else - return strtol (str, NULL, 10); + return g_ascii_strtoll (str, NULL, 10); return 0; } diff --git a/girwriter.c b/girwriter.c index 8c4fa2c35..e90799c13 100644 --- a/girwriter.c +++ b/girwriter.c @@ -704,7 +704,8 @@ write_value_info (const gchar *namespace, Xml *file) { const gchar *name; - glong value; + gint64 value; + gchar *value_str; gboolean deprecated; name = g_base_info_get_name ((GIBaseInfo *)info); @@ -712,7 +713,9 @@ write_value_info (const gchar *namespace, deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); xml_start_element (file, "member"); - xml_printf (file, " name=\"%s\" value=\"%ld\"", name, value); + value_str = g_strdup_printf ("%" G_GINT64_FORMAT, value); + xml_printf (file, " name=\"%s\" value=\"%s\"", name, value_str); + g_free (value_str); if (deprecated) xml_printf (file, " deprecated=\"1\""); diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 26fd6bfbf..de2f131b6 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -632,6 +632,7 @@ typedef struct { /** * ValueBlob: * @deprecated: Whether this value is deprecated + * @unsigned_value: if set, value is a 32-bit unsigned integer cast to gint32 * @value: The numerical value * @name: Name of blob * @@ -639,8 +640,9 @@ typedef struct { */ typedef struct { guint32 deprecated : 1; + guint32 unsigned_value : 1; /* */ - guint32 reserved :31; + guint32 reserved :30; /* */ guint32 name; gint32 value; From 307843c55ff377b8e47fc194446f4d6ac9abdc4d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 4 Nov 2010 13:12:12 -0400 Subject: [PATCH 407/692] Switch to nonrecursive make for core (i.e. not tests/) This is cleaner and faster, and prepares us better for an incoming import of CMPH. --- Makefile.am | 73 ----------------------------------------------------- 1 file changed, 73 deletions(-) delete mode 100644 Makefile.am diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 168732208..000000000 --- a/Makefile.am +++ /dev/null @@ -1,73 +0,0 @@ -girepodir = $(includedir)/gobject-introspection-1.0/ -girepo_HEADERS = \ - giarginfo.h \ - gibaseinfo.h \ - gicallableinfo.h \ - giconstantinfo.h \ - gienuminfo.h \ - gierrordomaininfo.h \ - gifieldinfo.h \ - gifunctioninfo.h \ - giinterfaceinfo.h \ - giobjectinfo.h \ - gipropertyinfo.h \ - giregisteredtypeinfo.h \ - girepository.h \ - girffi.h \ - gisignalinfo.h \ - gistructinfo.h \ - gitypeinfo.h \ - gitypelib.h \ - gitypes.h \ - giunioninfo.h \ - givfuncinfo.h - -lib_LTLIBRARIES = libgirepository-1.0.la -noinst_LTLIBRARIES = libgirepository-parser.la - -libgirepository_1_0_la_SOURCES = \ - gdump.c \ - giarginfo.c \ - gibaseinfo.c \ - gicallableinfo.c \ - giconstantinfo.c \ - gienuminfo.c \ - gierrordomaininfo.c \ - gifieldinfo.c \ - gifunctioninfo.c \ - ginvoke.c \ - giinterfaceinfo.c \ - giobjectinfo.c \ - gipropertyinfo.c \ - giregisteredtypeinfo.c \ - girepository.c \ - girepository-private.h \ - girffi.c \ - girffi.h \ - gisignalinfo.c \ - gistructinfo.c \ - gitypeinfo.c \ - gitypelib.c \ - gitypelib-internal.h \ - glib-compat.h \ - giunioninfo.c \ - givfuncinfo.c - -libgirepository_1_0_la_CPPFLAGS = $(GIREPO_CFLAGS) -DG_IREPOSITORY_COMPILATION -libgirepository_1_0_la_LIBADD = $(GIREPO_LIBS) -libgirepository_1_0_la_LDFLAGS = -no-undefined -version-number 1:0:0 - -libgirepository_parser_la_SOURCES = \ - girmodule.c \ - girmodule.h \ - girnode.c \ - girnode.h \ - giroffsets.c \ - girparser.c \ - girparser.h \ - girwriter.c \ - girwriter.h -libgirepository_parser_la_CFLAGS = $(GIREPO_CFLAGS) - -gdumpdir = $(datadir)/gobject-introspection-1.0/ -gdump_DATA = gdump.c From e6bb30500c80dd1b7a27d383e63f46f5910a44c3 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 9 Nov 2010 17:06:29 -0500 Subject: [PATCH 408/692] Export gi_type_tag_get_ffi_type This is needed by the offsets code, and is generally useful. We need to export it for a future patch which won't export symbols with a leading _. --- girepository-private.h | 2 -- girffi.c | 13 ++++++++++--- girffi.h | 2 ++ giroffsets.c | 4 ++-- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/girepository-private.h b/girepository-private.h index 46b898b09..897c52c4c 100644 --- a/girepository-private.h +++ b/girepository-private.h @@ -108,8 +108,6 @@ GIVFuncInfo * _g_base_info_find_vfunc (GIRealInfo *rinfo, gint n_vfuncs, const gchar *name); -ffi_type * _gi_type_tag_get_ffi_type (GITypeTag type_tag, gboolean is_pointer); - extern ffi_status ffi_prep_closure_loc (ffi_closure *, ffi_cif *, void (*fun)(ffi_cif *, void *, void **, void *), diff --git a/girffi.c b/girffi.c index 23b076bca..c46d3d3c2 100644 --- a/girffi.c +++ b/girffi.c @@ -30,9 +30,16 @@ #include "girepository.h" #include "girepository-private.h" +/** + * gi_type_tag_get_ffi_type: + * @tag: A #GITypeTag + * @is_pointer: Whether or not this is a pointer type + * + * Returns: A #ffi_type corresponding to the platform default C ABI for @tag and @is_pointer. + */ ffi_type * -_gi_type_tag_get_ffi_type (GITypeTag tag, - gboolean is_pointer) +gi_type_tag_get_ffi_type (GITypeTag tag, + gboolean is_pointer) { switch (tag) { @@ -96,7 +103,7 @@ _gi_type_tag_get_ffi_type (GITypeTag tag, ffi_type * g_type_info_get_ffi_type (GITypeInfo *info) { - return _gi_type_tag_get_ffi_type (g_type_info_get_tag (info), g_type_info_is_pointer (info)); + return gi_type_tag_get_ffi_type (g_type_info_get_tag (info), g_type_info_is_pointer (info)); } /** diff --git a/girffi.h b/girffi.h index 56d85a189..a5cc9e460 100644 --- a/girffi.h +++ b/girffi.h @@ -45,6 +45,8 @@ struct _GIFunctionInvoker { gpointer padding[3]; }; +ffi_type * gi_type_tag_get_ffi_type (GITypeTag type_tag, gboolean is_pointer); + ffi_type * g_type_info_get_ffi_type (GITypeInfo *info); gboolean g_function_info_prep_invoker (GIFunctionInfo *info, diff --git a/giroffsets.c b/giroffsets.c index 94fdc6646..5c16f811c 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -18,7 +18,7 @@ * Boston, MA 02111-1307, USA. */ -#include "girepository-private.h" +#include "girffi.h" #include "girnode.h" #include @@ -296,7 +296,7 @@ get_type_size_alignment (GIrTypelibBuild *build, } else { - type_ffi = _gi_type_tag_get_ffi_type (type->tag, type->is_pointer); + type_ffi = gi_type_tag_get_ffi_type (type->tag, type->is_pointer); if (type_ffi == &ffi_type_void) { From 30d5255a03f5f1fb5ecdc1b219cb5a8dcc0586f8 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 26 Oct 2010 11:47:00 -0400 Subject: [PATCH 409/692] Add g_object_info_find_signal This matches g_object_info_find_method, and allows us to add indexing later. https://bugzilla.gnome.org/show_bug.cgi?id=633204 --- giobjectinfo.c | 31 +++++++++++++++++++++++++++++++ giobjectinfo.h | 4 ++++ 2 files changed, 35 insertions(+) diff --git a/giobjectinfo.c b/giobjectinfo.c index 03ed2a22a..e1f0bc1df 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -471,6 +471,37 @@ g_object_info_get_signal (GIObjectInfo *info, rinfo->typelib, offset); } +/** + * g_object_info_find_signal: + * @info: a #GIObjectInfo + * @name: Name of signal + * + * Returns: Info for the signal with name @name in @info, or %NULL on failure. + */ +GISignalInfo * +g_object_info_find_signal (GIObjectInfo *info, + const gchar *name) +{ + gint n_signals; + gint i; + + n_signals = g_object_info_get_n_signals (info); + for (i = 0; i < n_signals; i++) + { + GISignalInfo *siginfo = g_object_info_get_signal (info, i); + + if (g_strcmp0 (g_base_info_get_name (siginfo), name) != 0) + { + g_base_info_unref ((GIBaseInfo*)siginfo); + continue; + } + + return siginfo; + } + return NULL; +} + + /** * g_object_info_get_n_vfuncs: * @info: a #GIObjectInfo diff --git a/giobjectinfo.h b/giobjectinfo.h index 11c1c5ac3..09e4bec98 100644 --- a/giobjectinfo.h +++ b/giobjectinfo.h @@ -94,6 +94,10 @@ GIFunctionInfo * g_object_info_find_method (GIObjectInfo *info, gint g_object_info_get_n_signals (GIObjectInfo *info); GISignalInfo * g_object_info_get_signal (GIObjectInfo *info, gint n); + +GISignalInfo * g_object_info_find_signal (GIObjectInfo *info, + const gchar *name); + gint g_object_info_get_n_vfuncs (GIObjectInfo *info); GIVFuncInfo * g_object_info_get_vfunc (GIObjectInfo *info, gint n); From f9a3bb7300dfcf3c3ba433cb966dd93160549921 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 26 Oct 2010 11:12:26 -0400 Subject: [PATCH 410/692] Add support for gunichar in typelib Some API such as gtk_text_iter_get_char returns an individual "gunichar"; we should support this. https://bugzilla.gnome.org/show_bug.cgi?id=633197 --- gifieldinfo.c | 2 ++ girepository.c | 2 ++ girffi.c | 1 + girnode.c | 2 +- girparser.c | 3 ++- gitypeinfo.h | 2 +- gitypelib.c | 4 +++- gitypes.h | 9 ++++++--- 8 files changed, 18 insertions(+), 7 deletions(-) diff --git a/gifieldinfo.c b/gifieldinfo.c index 1a6b688c3..d4fd14e2a 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -220,6 +220,7 @@ g_field_info_get_field (GIFieldInfo *field_info, break; case GI_TYPE_TAG_INT32: case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_UNICHAR: value->v_uint32 = G_STRUCT_MEMBER (guint32, mem, offset); result = TRUE; break; @@ -399,6 +400,7 @@ g_field_info_set_field (GIFieldInfo *field_info, break; case GI_TYPE_TAG_INT32: case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_UNICHAR: G_STRUCT_MEMBER (guint32, mem, offset) = value->v_uint32; result = TRUE; break; diff --git a/girepository.c b/girepository.c index 7ac407a1a..f7f55e5a6 100644 --- a/girepository.c +++ b/girepository.c @@ -1408,6 +1408,8 @@ g_type_tag_to_string (GITypeTag type) return "gfloat"; case GI_TYPE_TAG_DOUBLE: return "gdouble"; + case GI_TYPE_TAG_UNICHAR: + return "gunichar"; case GI_TYPE_TAG_GTYPE: return "GType"; case GI_TYPE_TAG_UTF8: diff --git a/girffi.c b/girffi.c index c46d3d3c2..d2afca0a5 100644 --- a/girffi.c +++ b/girffi.c @@ -56,6 +56,7 @@ gi_type_tag_get_ffi_type (GITypeTag tag, case GI_TYPE_TAG_INT32: return &ffi_type_sint32; case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_UNICHAR: return &ffi_type_uint32; case GI_TYPE_TAG_INT64: return &ffi_type_sint64; diff --git a/girnode.c b/girnode.c index 5b9df585d..b298c9528 100644 --- a/girnode.c +++ b/girnode.c @@ -1415,7 +1415,7 @@ g_ir_node_build_typelib (GIrNode *node, *offset += sizeof (SimpleTypeBlob); - if (G_TYPE_TAG_IS_BASIC(type->tag)) + if (G_TYPE_TAG_IS_BASIC (type->tag)) { blob->flags.reserved = 0; blob->flags.reserved2 = 0; diff --git a/girparser.c b/girparser.c index 42525ecde..0e31e9f6d 100644 --- a/girparser.c +++ b/girparser.c @@ -396,6 +396,7 @@ static BasicTypeInfo basic_types[] = { { "GType", GI_TYPE_TAG_GTYPE, 0 }, { "utf8", GI_TYPE_TAG_UTF8, 1 }, { "filename", GI_TYPE_TAG_FILENAME,1 }, + { "gunichar", GI_TYPE_TAG_UNICHAR, 0 }, }; static const BasicTypeInfo * @@ -579,7 +580,7 @@ parse_type_internal (GIrModule *module, if (next) *next = (char*)str; - g_assert (type->tag >= 0 && type->tag <= GI_TYPE_TAG_ERROR); + g_assert (type->tag >= 0 && type->tag < GI_TYPE_TAG_N_TYPES); g_free (temporary_type); return type; diff --git a/gitypeinfo.h b/gitypeinfo.h index 39890a7d9..5c4fc8351 100644 --- a/gitypeinfo.h +++ b/gitypeinfo.h @@ -33,7 +33,7 @@ G_BEGIN_DECLS #define GI_IS_TYPE_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_TYPE) -#define G_TYPE_TAG_IS_BASIC(tag) (tag < GI_TYPE_TAG_ARRAY) +#define G_TYPE_TAG_IS_BASIC(tag) (tag < GI_TYPE_TAG_ARRAY || tag == GI_TYPE_TAG_UNICHAR) const gchar* g_type_tag_to_string (GITypeTag type); const gchar* g_info_type_to_string (GIInfoType type); diff --git a/gitypelib.c b/gitypelib.c index 4d119b731..e77866aa2 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -652,6 +652,7 @@ validate_type_blob (GITypelib *typelib, } if (simple->flags.tag >= GI_TYPE_TAG_UTF8 && + simple->flags.tag != GI_TYPE_TAG_UNICHAR && !simple->flags.pointer) { g_set_error (error, @@ -1010,11 +1011,12 @@ validate_constant_blob (GITypelib *typelib, 0, /* GSLIST */ 0, /* GHASH */ 0, /* ERROR */ + 4 /* UNICHAR */ }; ConstantBlob *blob; SimpleTypeBlob *type; - g_assert (G_N_ELEMENTS (value_size) == GI_TYPE_TAG_ERROR + 1); + g_assert (G_N_ELEMENTS (value_size) == GI_TYPE_TAG_N_TYPES); if (typelib->len < offset + sizeof (ConstantBlob)) { diff --git a/gitypes.h b/gitypes.h index a356800ca..d15b121a3 100644 --- a/gitypes.h +++ b/gitypes.h @@ -322,6 +322,7 @@ typedef enum { * @GI_TYPE_TAG_UINT64: 64-bit unsigned integer * @GI_TYPE_TAG_FLOAT: float * @GI_TYPE_TAG_DOUBLE: double floating point + * @GI_TYPE_TAG_UNICHAR: Unicode character * @GI_TYPE_TAG_GTYPE: a #GType * @GI_TYPE_TAG_UTF8: a UTF-8 encoded string * @GI_TYPE_TAG_FILENAME: a filename, encoded in the same encoding @@ -352,18 +353,20 @@ typedef enum { GI_TYPE_TAG_GTYPE = 12, GI_TYPE_TAG_UTF8 = 13, GI_TYPE_TAG_FILENAME = 14, - /* Non-basic types */ + /* Non-basic types; compare with G_TYPE_TAG_IS_BASIC */ GI_TYPE_TAG_ARRAY = 15, GI_TYPE_TAG_INTERFACE = 16, GI_TYPE_TAG_GLIST = 17, GI_TYPE_TAG_GSLIST = 18, GI_TYPE_TAG_GHASH = 19, - GI_TYPE_TAG_ERROR = 20 + GI_TYPE_TAG_ERROR = 20, + /* Another basic type */ + GI_TYPE_TAG_UNICHAR = 21 /* Note - there is only room currently for 32 tags. * See docs/typelib-format.txt SimpleTypeBlob definition */ } GITypeTag; -#define GI_TYPE_TAG_N_TYPES (GI_TYPE_TAG_ERROR+1) +#define GI_TYPE_TAG_N_TYPES (GI_TYPE_TAG_UNICHAR+1) /* These were removed and no longer appear in the typelib; * instead, the machine-specific versions like INT32 are From 61e5bdb7ba07a475d9489bfedf9800cca12f3991 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 16 Nov 2010 15:13:41 -0500 Subject: [PATCH 411/692] gitypelib: Extend warning for validation --- gitypelib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitypelib.c b/gitypelib.c index e77866aa2..a0b74d3d6 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -647,7 +647,7 @@ validate_type_blob (GITypelib *typelib, g_set_error (error, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, - "Wrong tag in simple type"); + "Invalid non-basic tag %d in simple type", simple->flags.tag); return FALSE; } From ff33cc07911cd1752e54c0580ea9e106b9d6b75b Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 16 Nov 2010 15:08:33 -0500 Subject: [PATCH 412/692] girepository: Consistently prefix internal functions with _ This should better avoid them being exported. Rename girepository-parser.la to girepository-internals.la for clarity. --- girmodule.c | 58 ++++----- girmodule.h | 16 +-- girnode.c | 346 +++++++++++++++++++++++++-------------------------- girnode.h | 42 +++---- giroffsets.c | 14 +-- girparser.c | 96 +++++++------- girparser.h | 26 ++-- 7 files changed, 299 insertions(+), 299 deletions(-) diff --git a/girmodule.c b/girmodule.c index 68ee64b3a..d15b940f6 100644 --- a/girmodule.c +++ b/girmodule.c @@ -30,10 +30,10 @@ GIrModule * -g_ir_module_new (const gchar *name, - const gchar *version, - const gchar *shared_library, - const gchar *c_prefix) +_g_ir_module_new (const gchar *name, + const gchar *version, + const gchar *shared_library, + const gchar *c_prefix) { GIrModule *module; @@ -56,14 +56,14 @@ g_ir_module_new (const gchar *name, } void -g_ir_module_free (GIrModule *module) +_g_ir_module_free (GIrModule *module) { GList *e; g_free (module->name); for (e = module->entries; e; e = e->next) - g_ir_node_free ((GIrNode *)e->data); + _g_ir_node_free ((GIrNode *)e->data); g_list_free (module->entries); /* Don't free dependencies, we inherit that from the parser */ @@ -77,7 +77,7 @@ g_ir_module_free (GIrModule *module) } /** - * g_ir_module_fatal: + * _g_ir_module_fatal: * @build: Current build * @line: Origin line number, or 0 if unknown * @msg: printf-format string @@ -86,10 +86,10 @@ g_ir_module_free (GIrModule *module) * Report a fatal error, then exit. */ void -g_ir_module_fatal (GIrTypelibBuild *build, - guint line, - const char *msg, - ...) +_g_ir_module_fatal (GIrTypelibBuild *build, + guint line, + const char *msg, + ...) { GString *context; char *formatted; @@ -149,8 +149,8 @@ add_disguised_structure_foreach (gpointer key, } void -g_ir_module_add_include_module (GIrModule *module, - GIrModule *include_module) +_g_ir_module_add_include_module (GIrModule *module, + GIrModule *include_module) { module->include_modules = g_list_prepend (module->include_modules, include_module); @@ -184,8 +184,8 @@ write_attribute (gpointer key, gpointer value, gpointer datap) *(data->offset) += sizeof (AttributeBlob); blob->offset = data->node->offset; - blob->name = write_string ((const char*) key, data->strings, data->databuf, data->offset2); - blob->value = write_string ((const char*) value, data->strings, data->databuf, data->offset2); + blob->name = _g_ir_write_string ((const char*) key, data->strings, data->databuf, data->offset2); + blob->value = _g_ir_write_string ((const char*) value, data->strings, data->databuf, data->offset2); data->count++; } @@ -222,7 +222,7 @@ node_cmp_offset_func (gconstpointer a, GITypelib * -g_ir_module_build_typelib (GIrModule *module) +_g_ir_module_build_typelib (GIrModule *module) { GError *error = NULL; GITypelib *typelib; @@ -286,7 +286,7 @@ g_ir_module_build_typelib (GIrModule *module) { GIrNode *node = e->data; - size += g_ir_node_get_full_size (node); + size += _g_ir_node_get_full_size (node); /* Also reset the offset here */ node->offset = 0; @@ -320,17 +320,17 @@ g_ir_module_build_typelib (GIrModule *module) * the size calculations above. */ if (dependencies != NULL) - header->dependencies = write_string (dependencies, strings, data, &header_size); + header->dependencies = _g_ir_write_string (dependencies, strings, data, &header_size); else header->dependencies = 0; header->size = 0; /* filled in later */ - header->namespace = write_string (module->name, strings, data, &header_size); - header->nsversion = write_string (module->version, strings, data, &header_size); + header->namespace = _g_ir_write_string (module->name, strings, data, &header_size); + header->nsversion = _g_ir_write_string (module->version, strings, data, &header_size); header->shared_library = (module->shared_library? - write_string (module->shared_library, strings, data, &header_size) + _g_ir_write_string (module->shared_library, strings, data, &header_size) : 0); if (module->c_prefix != NULL) - header->c_prefix = write_string (module->c_prefix, strings, data, &header_size); + header->c_prefix = _g_ir_write_string (module->c_prefix, strings, data, &header_size); else header->c_prefix = 0; header->directory = ALIGN_VALUE (header_size, 4); @@ -398,18 +398,18 @@ g_ir_module_build_typelib (GIrModule *module) entry->blob_type = 0; entry->local = FALSE; - entry->offset = write_string (namespace, strings, data, &offset2); - entry->name = write_string (node->name, strings, data, &offset2); + entry->offset = _g_ir_write_string (namespace, strings, data, &offset2); + entry->name = _g_ir_write_string (node->name, strings, data, &offset2); } else { old_offset = offset; - offset2 = offset + g_ir_node_get_size (node); + offset2 = offset + _g_ir_node_get_size (node); entry->blob_type = node->type; entry->local = TRUE; entry->offset = offset; - entry->name = write_string (node->name, strings, data, &offset2); + entry->name = _g_ir_write_string (node->name, strings, data, &offset2); memset (&build, 0, sizeof (build)); build.module = module; @@ -418,13 +418,13 @@ g_ir_module_build_typelib (GIrModule *module) build.nodes_with_attributes = nodes_with_attributes; build.n_attributes = header->n_attributes; build.data = data; - g_ir_node_build_typelib (node, NULL, &build, &offset, &offset2); + _g_ir_node_build_typelib (node, NULL, &build, &offset, &offset2); nodes_with_attributes = build.nodes_with_attributes; header->n_attributes = build.n_attributes; - if (offset2 > old_offset + g_ir_node_get_full_size (node)) - g_error ("left a hole of %d bytes\n", offset2 - old_offset - g_ir_node_get_full_size (node)); + if (offset2 > old_offset + _g_ir_node_get_full_size (node)) + g_error ("left a hole of %d bytes\n", offset2 - old_offset - _g_ir_node_get_full_size (node)); } entry++; diff --git a/girmodule.h b/girmodule.h index 6c6d6201e..c81dec322 100644 --- a/girmodule.h +++ b/girmodule.h @@ -59,18 +59,18 @@ struct _GIrModule GHashTable *disguised_structures; }; -GIrModule *g_ir_module_new (const gchar *name, - const gchar *nsversion, - const gchar *module_filename, - const gchar *c_prefix); -void g_ir_module_free (GIrModule *module); +GIrModule *_g_ir_module_new (const gchar *name, + const gchar *nsversion, + const gchar *module_filename, + const gchar *c_prefix); +void _g_ir_module_free (GIrModule *module); -void g_ir_module_add_include_module (GIrModule *module, +void _g_ir_module_add_include_module (GIrModule *module, GIrModule *include_module); -GITypelib * g_ir_module_build_typelib (GIrModule *module); +GITypelib * _g_ir_module_build_typelib (GIrModule *module); -void g_ir_module_fatal (GIrTypelibBuild *build, guint line, const char *msg, ...) G_GNUC_PRINTF (3, 4) G_GNUC_NORETURN; +void _g_ir_module_fatal (GIrTypelibBuild *build, guint line, const char *msg, ...) G_GNUC_PRINTF (3, 4) G_GNUC_NORETURN; void _g_irnode_init_stats (void); void _g_irnode_dump_stats (void); diff --git a/girnode.c b/girnode.c index b298c9528..fe45503d7 100644 --- a/girnode.c +++ b/girnode.c @@ -65,7 +65,7 @@ do { \ const gchar * -g_ir_node_type_to_string (GIrNodeTypeId type) +_g_ir_node_type_to_string (GIrNodeTypeId type) { switch (type) { @@ -113,7 +113,7 @@ g_ir_node_type_to_string (GIrNodeTypeId type) } GIrNode * -g_ir_node_new (GIrNodeTypeId type, +_g_ir_node_new (GIrNodeTypeId type, GIrModule *module) { GIrNode *node = NULL; @@ -202,7 +202,7 @@ g_ir_node_new (GIrNodeTypeId type, } void -g_ir_node_free (GIrNode *node) +_g_ir_node_free (GIrNode *node) { GList *l; @@ -218,9 +218,9 @@ g_ir_node_free (GIrNode *node) g_free (node->name); g_free (function->symbol); - g_ir_node_free ((GIrNode *)function->result); + _g_ir_node_free ((GIrNode *)function->result); for (l = function->parameters; l; l = l->next) - g_ir_node_free ((GIrNode *)l->data); + _g_ir_node_free ((GIrNode *)l->data); g_list_free (function->parameters); } break; @@ -230,8 +230,8 @@ g_ir_node_free (GIrNode *node) GIrNodeType *type = (GIrNodeType *)node; g_free (node->name); - g_ir_node_free ((GIrNode *)type->parameter_type1); - g_ir_node_free ((GIrNode *)type->parameter_type2); + _g_ir_node_free ((GIrNode *)type->parameter_type1); + _g_ir_node_free ((GIrNode *)type->parameter_type2); g_free (type->interface); g_strfreev (type->errors); @@ -244,7 +244,7 @@ g_ir_node_free (GIrNode *node) GIrNodeParam *param = (GIrNodeParam *)node; g_free (node->name); - g_ir_node_free ((GIrNode *)param->type); + _g_ir_node_free ((GIrNode *)param->type); } break; @@ -253,7 +253,7 @@ g_ir_node_free (GIrNode *node) GIrNodeProperty *property = (GIrNodeProperty *)node; g_free (node->name); - g_ir_node_free ((GIrNode *)property->type); + _g_ir_node_free ((GIrNode *)property->type); } break; @@ -263,9 +263,9 @@ g_ir_node_free (GIrNode *node) g_free (node->name); for (l = signal->parameters; l; l = l->next) - g_ir_node_free ((GIrNode *)l->data); + _g_ir_node_free ((GIrNode *)l->data); g_list_free (signal->parameters); - g_ir_node_free ((GIrNode *)signal->result); + _g_ir_node_free ((GIrNode *)signal->result); } break; @@ -276,9 +276,9 @@ g_ir_node_free (GIrNode *node) g_free (node->name); g_free (vfunc->invoker); for (l = vfunc->parameters; l; l = l->next) - g_ir_node_free ((GIrNode *)l->data); + _g_ir_node_free ((GIrNode *)l->data); g_list_free (vfunc->parameters); - g_ir_node_free ((GIrNode *)vfunc->result); + _g_ir_node_free ((GIrNode *)vfunc->result); } break; @@ -287,8 +287,8 @@ g_ir_node_free (GIrNode *node) GIrNodeField *field = (GIrNodeField *)node; g_free (node->name); - g_ir_node_free ((GIrNode *)field->type); - g_ir_node_free ((GIrNode *)field->callback); + _g_ir_node_free ((GIrNode *)field->type); + _g_ir_node_free ((GIrNode *)field->callback); } break; @@ -314,7 +314,7 @@ g_ir_node_free (GIrNode *node) g_list_free (iface->interfaces); for (l = iface->members; l; l = l->next) - g_ir_node_free ((GIrNode *)l->data); + _g_ir_node_free ((GIrNode *)l->data); g_list_free (iface->members); } @@ -336,7 +336,7 @@ g_ir_node_free (GIrNode *node) g_free (enum_->gtype_init); for (l = enum_->values; l; l = l->next) - g_ir_node_free ((GIrNode *)l->data); + _g_ir_node_free ((GIrNode *)l->data); g_list_free (enum_->values); } break; @@ -350,7 +350,7 @@ g_ir_node_free (GIrNode *node) g_free (boxed->gtype_init); for (l = boxed->members; l; l = l->next) - g_ir_node_free ((GIrNode *)l->data); + _g_ir_node_free ((GIrNode *)l->data); g_list_free (boxed->members); } break; @@ -364,7 +364,7 @@ g_ir_node_free (GIrNode *node) g_free (struct_->gtype_init); for (l = struct_->members; l; l = l->next) - g_ir_node_free ((GIrNode *)l->data); + _g_ir_node_free ((GIrNode *)l->data); g_list_free (struct_->members); } break; @@ -375,7 +375,7 @@ g_ir_node_free (GIrNode *node) g_free (node->name); g_free (constant->value); - g_ir_node_free ((GIrNode *)constant->type); + _g_ir_node_free ((GIrNode *)constant->type); } break; @@ -406,11 +406,11 @@ g_ir_node_free (GIrNode *node) g_free (union_->gtype_name); g_free (union_->gtype_init); - g_ir_node_free ((GIrNode *)union_->discriminator_type); + _g_ir_node_free ((GIrNode *)union_->discriminator_type); for (l = union_->members; l; l = l->next) - g_ir_node_free ((GIrNode *)l->data); + _g_ir_node_free ((GIrNode *)l->data); for (l = union_->discriminators; l; l = l->next) - g_ir_node_free ((GIrNode *)l->data); + _g_ir_node_free ((GIrNode *)l->data); } break; @@ -426,7 +426,7 @@ g_ir_node_free (GIrNode *node) /* returns the fixed size of the blob */ guint32 -g_ir_node_get_size (GIrNode *node) +_g_ir_node_get_size (GIrNode *node) { GList *l; gint size, n; @@ -458,7 +458,7 @@ g_ir_node_get_size (GIrNode *node) size = sizeof (ObjectBlob) + 2 * (n + (n % 2)); for (l = iface->members; l; l = l->next) - size += g_ir_node_get_size ((GIrNode *)l->data); + size += _g_ir_node_get_size ((GIrNode *)l->data); } break; @@ -470,7 +470,7 @@ g_ir_node_get_size (GIrNode *node) size = sizeof (InterfaceBlob) + 2 * (n + (n % 2)); for (l = iface->members; l; l = l->next) - size += g_ir_node_get_size ((GIrNode *)l->data); + size += _g_ir_node_get_size ((GIrNode *)l->data); } break; @@ -481,7 +481,7 @@ g_ir_node_get_size (GIrNode *node) size = sizeof (EnumBlob); for (l = enum_->values; l; l = l->next) - size += g_ir_node_get_size ((GIrNode *)l->data); + size += _g_ir_node_get_size ((GIrNode *)l->data); } break; @@ -495,7 +495,7 @@ g_ir_node_get_size (GIrNode *node) size = sizeof (StructBlob); for (l = struct_->members; l; l = l->next) - size += g_ir_node_get_size ((GIrNode *)l->data); + size += _g_ir_node_get_size ((GIrNode *)l->data); } break; @@ -505,7 +505,7 @@ g_ir_node_get_size (GIrNode *node) size = sizeof (StructBlob); for (l = boxed->members; l; l = l->next) - size += g_ir_node_get_size ((GIrNode *)l->data); + size += _g_ir_node_get_size ((GIrNode *)l->data); } break; @@ -527,7 +527,7 @@ g_ir_node_get_size (GIrNode *node) size = sizeof (FieldBlob); if (field->callback) - size += g_ir_node_get_size ((GIrNode *)field->callback); + size += _g_ir_node_get_size ((GIrNode *)field->callback); } break; @@ -549,20 +549,20 @@ g_ir_node_get_size (GIrNode *node) size = sizeof (UnionBlob); for (l = union_->members; l; l = l->next) - size += g_ir_node_get_size ((GIrNode *)l->data); + size += _g_ir_node_get_size ((GIrNode *)l->data); for (l = union_->discriminators; l; l = l->next) - size += g_ir_node_get_size ((GIrNode *)l->data); + size += _g_ir_node_get_size ((GIrNode *)l->data); } break; default: g_error ("Unhandled node type '%s'\n", - g_ir_node_type_to_string (node->type)); + _g_ir_node_type_to_string (node->type)); size = 0; } g_debug ("node %p type '%s' size %d", node, - g_ir_node_type_to_string (node->type), size); + _g_ir_node_type_to_string (node->type), size); return size; } @@ -581,7 +581,7 @@ add_attribute_size (gpointer key, gpointer value, gpointer data) /* returns the full size of the blob including variable-size parts (including attributes) */ static guint32 -g_ir_node_get_full_size_internal (GIrNode *parent, +_g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node) { GList *l; @@ -591,7 +591,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, g_error ("Caught NULL node, parent=%s", parent->name); g_debug ("node %p type '%s'", node, - g_ir_node_type_to_string (node->type)); + _g_ir_node_type_to_string (node->type)); switch (node->type) { @@ -602,9 +602,9 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size += ALIGN_VALUE (strlen (node->name) + 1, 4); for (l = function->parameters; l; l = l->next) { - size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); } - size += g_ir_node_get_full_size_internal (node, (GIrNode *)function->result); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)function->result); } break; @@ -615,8 +615,8 @@ g_ir_node_get_full_size_internal (GIrNode *parent, 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_ir_node_get_full_size_internal (node, (GIrNode *)l->data); - size += g_ir_node_get_full_size_internal (node, (GIrNode *)function->result); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)function->result); } break; @@ -628,7 +628,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob); if (node->name) size += ALIGN_VALUE (strlen (node->name) + 1, 4); - size += g_ir_node_get_full_size_internal (node, (GIrNode *)param->type); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)param->type); } break; @@ -646,7 +646,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, case GI_TYPE_TAG_ARRAY: size = sizeof (ArrayTypeBlob); if (type->parameter_type1) - size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1); break; case GI_TYPE_TAG_INTERFACE: size += sizeof (InterfaceTypeBlob); @@ -655,14 +655,14 @@ g_ir_node_get_full_size_internal (GIrNode *parent, case GI_TYPE_TAG_GSLIST: size += sizeof (ParamTypeBlob); if (type->parameter_type1) - size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1); break; case GI_TYPE_TAG_GHASH: size += sizeof (ParamTypeBlob) * 2; if (type->parameter_type1) - size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1); if (type->parameter_type2) - size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type2); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type2); break; case GI_TYPE_TAG_ERROR: { @@ -709,7 +709,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size += 2 * (n + (n % 2)); for (l = iface->members; l; l = l->next) - size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); } break; @@ -725,7 +725,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size += 2 * (n + (n % 2)); for (l = iface->members; l; l = l->next) - size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); } break; @@ -743,7 +743,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, } for (l = enum_->values; l; l = l->next) - size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); } break; @@ -765,7 +765,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, if (struct_->gtype_init) size += ALIGN_VALUE (strlen (struct_->gtype_init) + 1, 4); for (l = struct_->members; l; l = l->next) - size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); } break; @@ -781,7 +781,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size += ALIGN_VALUE (strlen (boxed->gtype_init) + 1, 4); } for (l = boxed->members; l; l = l->next) - size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); } break; @@ -791,7 +791,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size = sizeof (PropertyBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); - size += g_ir_node_get_full_size_internal (node, (GIrNode *)prop->type); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)prop->type); } break; @@ -802,8 +802,8 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size = sizeof (SignalBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); for (l = signal->parameters; l; l = l->next) - size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); - size += g_ir_node_get_full_size_internal (node, (GIrNode *)signal->result); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)signal->result); } break; @@ -814,8 +814,8 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size = sizeof (VFuncBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); for (l = vfunc->parameters; l; l = l->next) - size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); - size += g_ir_node_get_full_size_internal (node, (GIrNode *)vfunc->result); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)vfunc->result); } break; @@ -826,9 +826,9 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size = sizeof (FieldBlob); size += ALIGN_VALUE (strlen (node->name) + 1, 4); if (field->callback) - size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->callback); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)field->callback); else - size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->type); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)field->type); } break; @@ -840,7 +840,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, size += ALIGN_VALUE (strlen (node->name) + 1, 4); /* FIXME non-string values */ size += ALIGN_VALUE (strlen (constant->value) + 1, 4); - size += g_ir_node_get_full_size_internal (node, (GIrNode *)constant->type); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)constant->type); } break; @@ -875,9 +875,9 @@ g_ir_node_get_full_size_internal (GIrNode *parent, if (union_->gtype_init) size += ALIGN_VALUE (strlen (union_->gtype_init) + 1, 4); for (l = union_->members; l; l = l->next) - size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); for (l = union_->discriminators; l; l = l->next) - size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); } break; @@ -890,7 +890,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, node->name ? "'" : "", node->name ? node->name : "", node->name ? "' " : "", - node, g_ir_node_type_to_string (node->type), size); + node, _g_ir_node_type_to_string (node->type), size); g_hash_table_foreach (node->attributes, add_attribute_size, &size); @@ -898,13 +898,13 @@ g_ir_node_get_full_size_internal (GIrNode *parent, } guint32 -g_ir_node_get_full_size (GIrNode *node) +_g_ir_node_get_full_size (GIrNode *node) { - return g_ir_node_get_full_size_internal (NULL, node); + return _g_ir_node_get_full_size_internal (NULL, node); } int -g_ir_node_cmp (GIrNode *node, +_g_ir_node_cmp (GIrNode *node, GIrNode *other) { if (node->type < other->type) @@ -916,7 +916,7 @@ g_ir_node_cmp (GIrNode *node, } gboolean -g_ir_node_can_have_member (GIrNode *node) +_g_ir_node_can_have_member (GIrNode *node) { switch (node->type) { @@ -950,7 +950,7 @@ g_ir_node_can_have_member (GIrNode *node) } void -g_ir_node_add_member (GIrNode *node, +_g_ir_node_add_member (GIrNode *node, GIrNodeFunction *member) { g_return_if_fail (node != NULL); @@ -964,7 +964,7 @@ g_ir_node_add_member (GIrNode *node, GIrNodeInterface *iface = (GIrNodeInterface *)node; iface->members = g_list_insert_sorted (iface->members, member, - (GCompareFunc) g_ir_node_cmp); + (GCompareFunc) _g_ir_node_cmp); break; } case G_IR_NODE_BOXED: @@ -972,7 +972,7 @@ g_ir_node_add_member (GIrNode *node, GIrNodeBoxed *boxed = (GIrNodeBoxed *)node; boxed->members = g_list_insert_sorted (boxed->members, member, - (GCompareFunc) g_ir_node_cmp); + (GCompareFunc) _g_ir_node_cmp); break; } case G_IR_NODE_STRUCT: @@ -980,7 +980,7 @@ g_ir_node_add_member (GIrNode *node, GIrNodeStruct *struct_ = (GIrNodeStruct *)node; struct_->members = g_list_insert_sorted (struct_->members, member, - (GCompareFunc) g_ir_node_cmp); + (GCompareFunc) _g_ir_node_cmp); break; } case G_IR_NODE_UNION: @@ -988,7 +988,7 @@ g_ir_node_add_member (GIrNode *node, GIrNodeUnion *union_ = (GIrNodeUnion *)node; union_->members = g_list_insert_sorted (union_->members, member, - (GCompareFunc) g_ir_node_cmp); + (GCompareFunc) _g_ir_node_cmp); break; } default: @@ -999,7 +999,7 @@ g_ir_node_add_member (GIrNode *node, } const gchar * -g_ir_node_param_direction_string (GIrNodeParam * node) +_g_ir_node_param_direction_string (GIrNodeParam * node) { if (node->out) { @@ -1088,7 +1088,7 @@ find_entry_node (GIrTypelibBuild *build, if (n_names > 1) { - GIrNode *node = g_ir_node_new (G_IR_NODE_XREF, module); + GIrNode *node = _g_ir_node_new (G_IR_NODE_XREF, module); ((GIrNodeXRef *)node)->namespace = g_strdup (names[0]); node->name = g_strdup (names[1]); @@ -1106,8 +1106,8 @@ find_entry_node (GIrTypelibBuild *build, } - g_ir_module_fatal (build, -1, "type reference '%s' not found", - name); + _g_ir_module_fatal (build, -1, "type reference '%s' not found", + name); out: g_strfreev (names); @@ -1151,7 +1151,7 @@ find_namespace (GIrModule *module, } GIrNode * -g_ir_find_node (GIrTypelibBuild *build, +_g_ir_find_node (GIrTypelibBuild *build, GIrModule *src_module, const char *name) { @@ -1312,7 +1312,7 @@ serialize_type (GIrTypelibBuild *build, } static void -g_ir_node_build_members (GList **members, +_g_ir_node_build_members (GList **members, GIrNodeTypeId type, guint16 *count, GIrNode *parent, @@ -1330,7 +1330,7 @@ g_ir_node_build_members (GList **members, if (member->type == type) { (*count)++; - g_ir_node_build_typelib (member, parent, build, offset, offset2); + _g_ir_node_build_typelib (member, parent, build, offset, offset2); *members = g_list_delete_link (*members, l); } l = next; @@ -1338,8 +1338,8 @@ g_ir_node_build_members (GList **members, } static void -g_ir_node_check_unhandled_members (GList **members, - GIrNodeTypeId container_type) +_g_ir_node_check_unhandled_members (GList **members, + GIrNodeTypeId container_type) { #if 0 if (*members) @@ -1350,9 +1350,9 @@ g_ir_node_check_unhandled_members (GList **members, { GIrNode *member = (GIrNode *)l->data; g_printerr ("Unhandled '%s' member '%s' type '%s'\n", - g_ir_node_type_to_string (container_type), + _g_ir_node_type_to_string (container_type), member->name, - g_ir_node_type_to_string (member->type)); + _g_ir_node_type_to_string (member->type)); } g_list_free (*members); @@ -1367,11 +1367,11 @@ g_ir_node_check_unhandled_members (GList **members, } void -g_ir_node_build_typelib (GIrNode *node, - GIrNode *parent, - GIrTypelibBuild *build, - guint32 *offset, - guint32 *offset2) +_g_ir_node_build_typelib (GIrNode *node, + GIrNode *parent, + GIrTypelibBuild *build, + guint32 *offset, + guint32 *offset2) { gboolean appended_stack; GHashTable *strings = build->strings; @@ -1386,7 +1386,7 @@ g_ir_node_build_typelib (GIrNode *node, g_debug ("build_typelib: %s%s(%s)", node->name ? node->name : "", node->name ? " " : "", - g_ir_node_type_to_string (node->type)); + _g_ir_node_type_to_string (node->type)); if (build->stack) appended_stack = node != (GIrNode*)build->stack->data; @@ -1395,7 +1395,7 @@ g_ir_node_build_typelib (GIrNode *node, if (appended_stack) build->stack = g_list_prepend (build->stack, node); - g_ir_node_compute_offsets (build, node); + _g_ir_node_compute_offsets (build, node); /* We should only be building each node once. If we do a typelib expansion, we also * reset the offset in girmodule.c. @@ -1471,7 +1471,7 @@ g_ir_node_build_typelib (GIrNode *node, pos = *offset2 + G_STRUCT_OFFSET (ArrayTypeBlob, type); *offset2 += sizeof (ArrayTypeBlob); - g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, + _g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, node, build, &pos, offset2); } break; @@ -1505,7 +1505,7 @@ g_ir_node_build_typelib (GIrNode *node, pos = *offset2 + G_STRUCT_OFFSET (ParamTypeBlob, type); *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob); - g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, + _g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, node, build, &pos, offset2); } break; @@ -1524,9 +1524,9 @@ g_ir_node_build_typelib (GIrNode *node, pos = *offset2 + G_STRUCT_OFFSET (ParamTypeBlob, type); *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob)*2; - g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, + _g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, node, build, &pos, offset2); - g_ir_node_build_typelib ((GIrNode *)type->parameter_type2, + _g_ir_node_build_typelib ((GIrNode *)type->parameter_type2, node, build, &pos, offset2); } break; @@ -1568,7 +1568,7 @@ g_ir_node_build_typelib (GIrNode *node, blob = (FieldBlob *)&data[*offset]; - blob->name = write_string (node->name, strings, data, offset2); + blob->name = _g_ir_write_string (node->name, strings, data, offset2); blob->readable = field->readable; blob->writable = field->writable; blob->reserved = 0; @@ -1583,7 +1583,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->has_embedded_type = TRUE; blob->type.offset = GI_INFO_TYPE_CALLBACK; *offset += sizeof (FieldBlob); - g_ir_node_build_typelib ((GIrNode *)field->callback, + _g_ir_node_build_typelib ((GIrNode *)field->callback, node, build, offset, offset2); } else @@ -1591,7 +1591,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->has_embedded_type = FALSE; /* We handle the size member specially below, so subtract it */ *offset += sizeof (FieldBlob) - sizeof (SimpleTypeBlob); - g_ir_node_build_typelib ((GIrNode *)field->type, + _g_ir_node_build_typelib ((GIrNode *)field->type, node, build, offset, offset2); } } @@ -1604,7 +1604,7 @@ g_ir_node_build_typelib (GIrNode *node, /* We handle the size member specially below, so subtract it */ *offset += sizeof (PropertyBlob) - sizeof (SimpleTypeBlob); - blob->name = write_string (node->name, strings, data, offset2); + blob->name = _g_ir_write_string (node->name, strings, data, offset2); blob->deprecated = prop->deprecated; blob->readable = prop->readable; blob->writable = prop->writable; @@ -1614,7 +1614,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->transfer_container_ownership = prop->shallow_transfer; blob->reserved = 0; - g_ir_node_build_typelib ((GIrNode *)prop->type, + _g_ir_node_build_typelib ((GIrNode *)prop->type, node, build, offset, offset2); } break; @@ -1642,8 +1642,8 @@ g_ir_node_build_typelib (GIrNode *node, blob->wraps_vfunc = function->wraps_vfunc; blob->throws = function->throws; blob->index = 0; - blob->name = write_string (node->name, strings, data, offset2); - blob->symbol = write_string (function->symbol, strings, data, offset2); + blob->name = _g_ir_write_string (node->name, strings, data, offset2); + blob->symbol = _g_ir_write_string (function->symbol, strings, data, offset2); blob->signature = signature; /* function->result is special since it doesn't appear in the serialized format but @@ -1656,7 +1656,7 @@ g_ir_node_build_typelib (GIrNode *node, g_debug ("building function '%s'", function->symbol); - g_ir_node_build_typelib ((GIrNode *)function->result->type, + _g_ir_node_build_typelib ((GIrNode *)function->result->type, node, build, &signature, offset2); blob2->may_return_null = function->result->allow_none; @@ -1671,7 +1671,7 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - g_ir_node_build_typelib (param, node, build, &signature, offset2); + _g_ir_node_build_typelib (param, node, build, &signature, offset2); } } @@ -1694,10 +1694,10 @@ g_ir_node_build_typelib (GIrNode *node, blob->blob_type = BLOB_TYPE_CALLBACK; blob->deprecated = function->deprecated; blob->reserved = 0; - blob->name = write_string (node->name, strings, data, offset2); + blob->name = _g_ir_write_string (node->name, strings, data, offset2); blob->signature = signature; - g_ir_node_build_typelib ((GIrNode *)function->result->type, + _g_ir_node_build_typelib ((GIrNode *)function->result->type, node, build, &signature, offset2); blob2->may_return_null = function->result->allow_none; @@ -1712,7 +1712,7 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - g_ir_node_build_typelib (param, node, build, &signature, offset2); + _g_ir_node_build_typelib (param, node, build, &signature, offset2); } } break; @@ -1743,7 +1743,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->true_stops_emit = 0; /* FIXME */ blob->reserved = 0; blob->class_closure = 0; /* FIXME */ - blob->name = write_string (node->name, strings, data, offset2); + blob->name = _g_ir_write_string (node->name, strings, data, offset2); blob->signature = signature; /* signal->result is special since it doesn't appear in the serialized format but @@ -1754,7 +1754,7 @@ g_ir_node_build_typelib (GIrNode *node, g_assert (((GIrNode *) signal->result)->offset == 0); ((GIrNode *) signal->result)->offset = signature; - g_ir_node_build_typelib ((GIrNode *)signal->result->type, + _g_ir_node_build_typelib ((GIrNode *)signal->result->type, node, build, &signature, offset2); blob2->may_return_null = signal->result->allow_none; @@ -1769,7 +1769,7 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - g_ir_node_build_typelib (param, node, build, &signature, offset2); + _g_ir_node_build_typelib (param, node, build, &signature, offset2); } } break; @@ -1788,7 +1788,7 @@ g_ir_node_build_typelib (GIrNode *node, *offset += sizeof (VFuncBlob); *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob); - blob->name = write_string (node->name, strings, data, offset2); + blob->name = _g_ir_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 */ @@ -1811,7 +1811,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->reserved2 = 0; blob->signature = signature; - g_ir_node_build_typelib ((GIrNode *)vfunc->result->type, + _g_ir_node_build_typelib ((GIrNode *)vfunc->result->type, node, build, &signature, offset2); blob2->may_return_null = vfunc->result->allow_none; @@ -1826,7 +1826,7 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - g_ir_node_build_typelib (param, node, build, &signature, offset2); + _g_ir_node_build_typelib (param, node, build, &signature, offset2); } } break; @@ -1841,7 +1841,7 @@ g_ir_node_build_typelib (GIrNode *node, */ *offset += sizeof (ArgBlob) - sizeof (SimpleTypeBlob); - blob->name = write_string (node->name, strings, data, offset2); + blob->name = _g_ir_write_string (node->name, strings, data, offset2); blob->in = param->in; blob->out = param->out; blob->caller_allocates = param->caller_allocates; @@ -1855,7 +1855,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->closure = param->closure; blob->destroy = param->destroy; - g_ir_node_build_typelib ((GIrNode *)param->type, node, build, offset, offset2); + _g_ir_node_build_typelib ((GIrNode *)param->type, node, build, offset, offset2); } break; @@ -1870,15 +1870,15 @@ g_ir_node_build_typelib (GIrNode *node, blob->deprecated = struct_->deprecated; blob->is_gtype_struct = struct_->is_gtype_struct; blob->reserved = 0; - blob->name = write_string (node->name, strings, data, offset2); + blob->name = _g_ir_write_string (node->name, strings, data, offset2); blob->alignment = struct_->alignment; blob->size = struct_->size; if (struct_->gtype_name) { blob->unregistered = FALSE; - blob->gtype_name = write_string (struct_->gtype_name, strings, data, offset2); - blob->gtype_init = write_string (struct_->gtype_init, strings, data, offset2); + blob->gtype_name = _g_ir_write_string (struct_->gtype_name, strings, data, offset2); + blob->gtype_init = _g_ir_write_string (struct_->gtype_init, strings, data, offset2); } else { @@ -1894,13 +1894,13 @@ g_ir_node_build_typelib (GIrNode *node, members = g_list_copy (struct_->members); - g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, + _g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, node, build, offset, offset2); - g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, + _g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, node, build, offset, offset2); - g_ir_node_check_unhandled_members (&members, node->type); + _g_ir_node_check_unhandled_members (&members, node->type); g_assert (members == NULL); } @@ -1916,9 +1916,9 @@ g_ir_node_build_typelib (GIrNode *node, 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->name = _g_ir_write_string (node->name, strings, data, offset2); + blob->gtype_name = _g_ir_write_string (boxed->gtype_name, strings, data, offset2); + blob->gtype_init = _g_ir_write_string (boxed->gtype_init, strings, data, offset2); blob->alignment = boxed->alignment; blob->size = boxed->size; @@ -1929,13 +1929,13 @@ g_ir_node_build_typelib (GIrNode *node, members = g_list_copy (boxed->members); - g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, - node, build, offset, offset2); + _g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, + node, build, offset, offset2); - g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, - node, build, offset, offset2); + _g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, + node, build, offset, offset2); - g_ir_node_check_unhandled_members (&members, node->type); + _g_ir_node_check_unhandled_members (&members, node->type); g_assert (members == NULL); } @@ -1950,14 +1950,14 @@ g_ir_node_build_typelib (GIrNode *node, blob->blob_type = BLOB_TYPE_UNION; blob->deprecated = union_->deprecated; blob->reserved = 0; - blob->name = write_string (node->name, strings, data, offset2); + blob->name = _g_ir_write_string (node->name, strings, data, offset2); blob->alignment = union_->alignment; blob->size = union_->size; 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); + blob->gtype_name = _g_ir_write_string (union_->gtype_name, strings, data, offset2); + blob->gtype_init = _g_ir_write_string (union_->gtype_init, strings, data, offset2); } else { @@ -1977,7 +1977,7 @@ g_ir_node_build_typelib (GIrNode *node, { *offset += 28; blob->discriminated = TRUE; - g_ir_node_build_typelib ((GIrNode *)union_->discriminator_type, + _g_ir_node_build_typelib ((GIrNode *)union_->discriminator_type, build, offset, offset2); } else @@ -1989,13 +1989,13 @@ g_ir_node_build_typelib (GIrNode *node, members = g_list_copy (union_->members); - g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, + _g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, node, build, offset, offset2); - g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_functions, + _g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_functions, node, build, offset, offset2); - g_ir_node_check_unhandled_members (&members, node->type); + _g_ir_node_check_unhandled_members (&members, node->type); g_assert (members == NULL); @@ -2005,7 +2005,7 @@ g_ir_node_build_typelib (GIrNode *node, { GIrNode *member = (GIrNode *)l->data; - g_ir_node_build_typelib (member, node, build, offset, offset2); + _g_ir_node_build_typelib (member, node, build, offset, offset2); } } } @@ -2027,12 +2027,12 @@ g_ir_node_build_typelib (GIrNode *node, blob->deprecated = enum_->deprecated; blob->reserved = 0; blob->storage_type = enum_->storage_type; - blob->name = write_string (node->name, strings, data, offset2); + blob->name = _g_ir_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); + blob->gtype_name = _g_ir_write_string (enum_->gtype_name, strings, data, offset2); + blob->gtype_init = _g_ir_write_string (enum_->gtype_init, strings, data, offset2); } else { @@ -2049,7 +2049,7 @@ g_ir_node_build_typelib (GIrNode *node, GIrNode *value = (GIrNode *)l->data; blob->n_values++; - g_ir_node_build_typelib (value, node, build, offset, offset2); + _g_ir_node_build_typelib (value, node, build, offset, offset2); } } break; @@ -2065,17 +2065,17 @@ g_ir_node_build_typelib (GIrNode *node, blob->fundamental = object->fundamental; 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); + blob->name = _g_ir_write_string (node->name, strings, data, offset2); + blob->gtype_name = _g_ir_write_string (object->gtype_name, strings, data, offset2); + blob->gtype_init = _g_ir_write_string (object->gtype_init, strings, data, offset2); if (object->ref_func) - blob->ref_func = write_string (object->ref_func, strings, data, offset2); + blob->ref_func = _g_ir_write_string (object->ref_func, strings, data, offset2); if (object->unref_func) - blob->unref_func = write_string (object->unref_func, strings, data, offset2); + blob->unref_func = _g_ir_write_string (object->unref_func, strings, data, offset2); if (object->set_value_func) - blob->set_value_func = write_string (object->set_value_func, strings, data, offset2); + blob->set_value_func = _g_ir_write_string (object->set_value_func, strings, data, offset2); if (object->get_value_func) - blob->get_value_func = write_string (object->get_value_func, strings, data, offset2); + blob->get_value_func = _g_ir_write_string (object->get_value_func, strings, data, offset2); if (object->parent) blob->parent = find_entry (build, object->parent); else @@ -2104,30 +2104,30 @@ g_ir_node_build_typelib (GIrNode *node, members = g_list_copy (object->members); *offset = ALIGN_VALUE (*offset, 4); - g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, + _g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); - g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties, + _g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties, node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); - g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, + _g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); - g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals, + _g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals, node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); - g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs, + _g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs, node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); - g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants, + _g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants, node, build, offset, offset2); - g_ir_node_check_unhandled_members (&members, node->type); + _g_ir_node_check_unhandled_members (&members, node->type); g_assert (members == NULL); } @@ -2142,9 +2142,9 @@ g_ir_node_build_typelib (GIrNode *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->name = _g_ir_write_string (node->name, strings, data, offset2); + blob->gtype_name = _g_ir_write_string (iface->gtype_name, strings, data, offset2); + blob->gtype_init = _g_ir_write_string (iface->gtype_init, strings, data, offset2); if (iface->glib_type_struct) blob->gtype_struct = find_entry (build, iface->glib_type_struct); else @@ -2167,26 +2167,26 @@ g_ir_node_build_typelib (GIrNode *node, members = g_list_copy (iface->members); *offset = ALIGN_VALUE (*offset, 4); - g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties, + _g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties, node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); - g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, + _g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); - g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals, + _g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals, node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); - g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs, + _g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs, node, build, offset, offset2); *offset = ALIGN_VALUE (*offset, 4); - g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants, + _g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants, node, build, offset, offset2); - g_ir_node_check_unhandled_members (&members, node->type); + _g_ir_node_check_unhandled_members (&members, node->type); g_assert (members == NULL); } @@ -2202,7 +2202,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->deprecated = value->deprecated; blob->reserved = 0; blob->unsigned_value = value->value >= 0 ? 1 : 0; - blob->name = write_string (node->name, strings, data, offset2); + blob->name = _g_ir_write_string (node->name, strings, data, offset2); blob->value = (gint32)value->value; } break; @@ -2216,8 +2216,8 @@ g_ir_node_build_typelib (GIrNode *node, 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->name = _g_ir_write_string (node->name, strings, data, offset2); + blob->get_quark = _g_ir_write_string (domain->getquark, strings, data, offset2); blob->error_codes = find_entry (build, domain->codes); blob->reserved2 = 0; } @@ -2235,7 +2235,7 @@ g_ir_node_build_typelib (GIrNode *node, blob->blob_type = BLOB_TYPE_CONSTANT; blob->deprecated = constant->deprecated; blob->reserved = 0; - blob->name = write_string (node->name, strings, data, offset2); + blob->name = _g_ir_write_string (node->name, strings, data, offset2); blob->offset = *offset2; switch (constant->type->tag) @@ -2292,7 +2292,7 @@ g_ir_node_build_typelib (GIrNode *node, } *offset2 += ALIGN_VALUE (blob->size, 4); - g_ir_node_build_typelib ((GIrNode *)constant->type, node, build, &pos, offset2); + _g_ir_node_build_typelib ((GIrNode *)constant->type, node, build, &pos, offset2); } break; default: @@ -2303,12 +2303,12 @@ g_ir_node_build_typelib (GIrNode *node, node->name ? "'" : "", node->name ? node->name : "", node->name ? "' " : "", - node, g_ir_node_type_to_string (node->type), + node, _g_ir_node_type_to_string (node->type), old_offset, *offset, old_offset2, *offset2); - if (*offset2 - old_offset2 + *offset - old_offset > g_ir_node_get_full_size (node)) + if (*offset2 - old_offset2 + *offset - old_offset > _g_ir_node_get_full_size (node)) g_error ("exceeding space reservation; offset: %d (prev %d) offset2: %d (prev %d) nodesize: %d", - *offset, old_offset, *offset2, old_offset2, g_ir_node_get_full_size (node)); + *offset, old_offset, *offset2, old_offset2, _g_ir_node_get_full_size (node)); if (appended_stack) build->stack = g_list_delete_link (build->stack, build->stack); @@ -2319,10 +2319,10 @@ g_ir_node_build_typelib (GIrNode *node, * typelib is not large enough to hold the string, reallocate it. */ guint32 -write_string (const gchar *str, - GHashTable *strings, - guchar *data, - guint32 *offset) +_g_ir_write_string (const gchar *str, + GHashTable *strings, + guchar *data, + guint32 *offset) { gpointer value; guint32 start; diff --git a/girnode.h b/girnode.h index 0df100880..e215e2cde 100644 --- a/girnode.h +++ b/girnode.h @@ -354,36 +354,36 @@ struct _GIrNodeErrorDomain }; -GIrNode * g_ir_node_new (GIrNodeTypeId type, +GIrNode * _g_ir_node_new (GIrNodeTypeId type, GIrModule *module); -void g_ir_node_free (GIrNode *node); -guint32 g_ir_node_get_size (GIrNode *node); -guint32 g_ir_node_get_full_size (GIrNode *node); -void g_ir_node_build_typelib (GIrNode *node, - GIrNode *parent, - GIrTypelibBuild *build, - guint32 *offset, - guint32 *offset2); -int g_ir_node_cmp (GIrNode *node, +void _g_ir_node_free (GIrNode *node); +guint32 _g_ir_node_get_size (GIrNode *node); +guint32 _g_ir_node_get_full_size (GIrNode *node); +void _g_ir_node_build_typelib (GIrNode *node, + GIrNode *parent, + GIrTypelibBuild *build, + guint32 *offset, + guint32 *offset2); +int _g_ir_node_cmp (GIrNode *node, GIrNode *other); -gboolean g_ir_node_can_have_member (GIrNode *node); -void g_ir_node_add_member (GIrNode *node, - GIrNodeFunction *member); -guint32 write_string (const gchar *str, - GHashTable *strings, - guchar *data, - guint32 *offset); +gboolean _g_ir_node_can_have_member (GIrNode *node); +void _g_ir_node_add_member (GIrNode *node, + GIrNodeFunction *member); +guint32 _g_ir_write_string (const gchar *str, + GHashTable *strings, + guchar *data, + guint32 *offset); -const gchar * g_ir_node_param_direction_string (GIrNodeParam * node); -const gchar * g_ir_node_type_to_string (GIrNodeTypeId type); +const gchar * _g_ir_node_param_direction_string (GIrNodeParam * node); +const gchar * _g_ir_node_type_to_string (GIrNodeTypeId type); -GIrNode *g_ir_find_node (GIrTypelibBuild *build, +GIrNode *_g_ir_find_node (GIrTypelibBuild *build, GIrModule *module, const char *name); /* In giroffsets.c */ -void g_ir_node_compute_offsets (GIrTypelibBuild *build, +void _g_ir_node_compute_offsets (GIrTypelibBuild *build, GIrNode *node); diff --git a/giroffsets.c b/giroffsets.c index 5c16f811c..7b30809c2 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -189,16 +189,16 @@ get_interface_size_alignment (GIrTypelibBuild *build, { GIrNode *iface; - iface = g_ir_find_node (build, ((GIrNode*)type)->module, type->interface); + iface = _g_ir_find_node (build, ((GIrNode*)type)->module, type->interface); if (!iface) { - g_ir_module_fatal (build, 0, "Can't resolve type '%s' for %s", type->interface, who); + _g_ir_module_fatal (build, 0, "Can't resolve type '%s' for %s", type->interface, who); *size = -1; *alignment = -1; return FALSE; } - g_ir_node_compute_offsets (build, iface); + _g_ir_node_compute_offsets (build, iface); switch (iface->type) { @@ -247,7 +247,7 @@ get_interface_size_alignment (GIrTypelibBuild *build, { g_warning ("%s has is not a pointer and is of type %s", who, - g_ir_node_type_to_string (iface->type)); + _g_ir_node_type_to_string (iface->type)); *size = -1; *alignment = -1; break; @@ -497,7 +497,7 @@ check_needs_computation (GIrTypelibBuild *build, } /** - * g_ir_node_compute_offsets: + * _g_ir_node_compute_offsets: * @build: Current typelib build * @node: a #GIrNode * @@ -506,8 +506,8 @@ check_needs_computation (GIrTypelibBuild *build, * alignment for the type. */ void -g_ir_node_compute_offsets (GIrTypelibBuild *build, - GIrNode *node) +_g_ir_node_compute_offsets (GIrTypelibBuild *build, + GIrNode *node) { gboolean appended_stack; diff --git a/girparser.c b/girparser.c index 0e31e9f6d..0b0583929 100644 --- a/girparser.c +++ b/girparser.c @@ -161,7 +161,7 @@ static const gchar *find_attribute (const gchar *name, GIrParser * -g_ir_parser_new (void) +_g_ir_parser_new (void) { GIrParser *parser = g_slice_new0 (GIrParser); @@ -169,7 +169,7 @@ g_ir_parser_new (void) } void -g_ir_parser_free (GIrParser *parser) +_g_ir_parser_free (GIrParser *parser) { GList *l; @@ -177,14 +177,14 @@ g_ir_parser_free (GIrParser *parser) g_strfreev (parser->includes); for (l = parser->parsed_modules; l; l = l->next) - g_ir_module_free (l->data); + _g_ir_module_free (l->data); g_slice_free (GIrParser, parser); } void -g_ir_parser_set_includes (GIrParser *parser, - const gchar *const *includes) +_g_ir_parser_set_includes (GIrParser *parser, + const gchar *const *includes) { if (parser->includes) g_strfreev (parser->includes); @@ -457,7 +457,7 @@ parse_type_internal (GIrModule *module, GIrNodeType *type; char *temporary_type = NULL; - type = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE, module); + type = (GIrNodeType *)_g_ir_node_new (G_IR_NODE_TYPE, module); type->unparsed = g_strdup (str); @@ -585,7 +585,7 @@ parse_type_internal (GIrModule *module, return type; /* error: */ - g_ir_node_free ((GIrNode *)type); + _g_ir_node_free ((GIrNode *)type); g_free (temporary_type); return NULL; } @@ -748,7 +748,7 @@ start_glib_boxed (GMarkupParseContext *context, return FALSE; } - boxed = (GIrNodeBoxed *) g_ir_node_new (G_IR_NODE_BOXED, + boxed = (GIrNodeBoxed *) _g_ir_node_new (G_IR_NODE_BOXED, ctx->current_module); ((GIrNode *)boxed)->name = g_strdup (name); @@ -838,7 +838,7 @@ start_function (GMarkupParseContext *context, if (shadows) name = shadows; - function = (GIrNodeFunction *) g_ir_node_new (G_IR_NODE_FUNCTION, + function = (GIrNodeFunction *) _g_ir_node_new (G_IR_NODE_FUNCTION, ctx->current_module); ((GIrNode *)function)->name = g_strdup (name); @@ -1045,8 +1045,8 @@ start_parameter (GMarkupParseContext *context, if (name == NULL) name = "unknown"; - param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM, - ctx->current_module); + param = (GIrNodeParam *)_g_ir_node_new (G_IR_NODE_PARAM, + ctx->current_module); ctx->current_typed = (GIrNode*) param; ctx->current_typed->name = g_strdup (name); @@ -1201,8 +1201,8 @@ start_field (GMarkupParseContext *context, return FALSE; } - field = (GIrNodeField *)g_ir_node_new (G_IR_NODE_FIELD, - ctx->current_module); + field = (GIrNodeField *)_g_ir_node_new (G_IR_NODE_FIELD, + ctx->current_module); if (introspectable) { ctx->current_typed = (GIrNode*) field; @@ -1268,7 +1268,7 @@ start_field (GMarkupParseContext *context, { GIrNodeConstant *constant; - constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT, + constant = (GIrNodeConstant *) _g_ir_node_new (G_IR_NODE_CONSTANT, ctx->current_module); ((GIrNode *)constant)->name = g_strdup (name); constant->value = g_strdup (branch); @@ -1342,10 +1342,10 @@ start_enum (GMarkupParseContext *context, } if (strcmp (element_name, "enumeration") == 0) - enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_ENUM, + enum_ = (GIrNodeEnum *) _g_ir_node_new (G_IR_NODE_ENUM, ctx->current_module); else - enum_ = (GIrNodeEnum *) g_ir_node_new (G_IR_NODE_FLAGS, + enum_ = (GIrNodeEnum *) _g_ir_node_new (G_IR_NODE_FLAGS, ctx->current_module); ((GIrNode *)enum_)->name = g_strdup (name); enum_->gtype_name = g_strdup (typename); @@ -1409,7 +1409,7 @@ start_property (GMarkupParseContext *context, return FALSE; } - property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY, + property = (GIrNodeProperty *) _g_ir_node_new (G_IR_NODE_PROPERTY, ctx->current_module); ctx->current_typed = (GIrNode*) property; @@ -1492,7 +1492,7 @@ start_member (GMarkupParseContext *context, return FALSE; } - value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE, + value_ = (GIrNodeValue *) _g_ir_node_new (G_IR_NODE_VALUE, ctx->current_module); ((GIrNode *)value_)->name = g_strdup (name); @@ -1566,7 +1566,7 @@ start_constant (GMarkupParseContext *context, return FALSE; } - constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT, + constant = (GIrNodeConstant *) _g_ir_node_new (G_IR_NODE_CONSTANT, ctx->current_module); ((GIrNode *)constant)->name = g_strdup (name); @@ -1639,7 +1639,7 @@ start_errordomain (GMarkupParseContext *context, return FALSE; } - domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN, + domain = (GIrNodeErrorDomain *) _g_ir_node_new (G_IR_NODE_ERROR_DOMAIN, ctx->current_module); ((GIrNode *)domain)->name = g_strdup (name); @@ -1702,7 +1702,7 @@ start_interface (GMarkupParseContext *context, return FALSE; } - iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_INTERFACE, + iface = (GIrNodeInterface *) _g_ir_node_new (G_IR_NODE_INTERFACE, ctx->current_module); ((GIrNode *)iface)->name = g_strdup (name); iface->gtype_name = g_strdup (typename); @@ -1778,7 +1778,7 @@ start_class (GMarkupParseContext *context, return FALSE; } - iface = (GIrNodeInterface *) g_ir_node_new (G_IR_NODE_OBJECT, + iface = (GIrNodeInterface *) _g_ir_node_new (G_IR_NODE_OBJECT, ctx->current_module); ((GIrNode *)iface)->name = g_strdup (name); iface->gtype_name = g_strdup (typename); @@ -1915,8 +1915,8 @@ start_type (GMarkupParseContext *context, const char *len; const char *size; - typenode = (GIrNodeType *)g_ir_node_new (G_IR_NODE_TYPE, - ctx->current_module); + typenode = (GIrNodeType *)_g_ir_node_new (G_IR_NODE_TYPE, + ctx->current_module); typenode->tag = GI_TYPE_TAG_ARRAY; typenode->is_pointer = TRUE; @@ -2194,8 +2194,8 @@ start_return_value (GMarkupParseContext *context, ctx->state == STATE_FUNCTION)) return FALSE; - param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM, - ctx->current_module); + param = (GIrNodeParam *)_g_ir_node_new (G_IR_NODE_PARAM, + ctx->current_module); param->in = FALSE; param->out = FALSE; param->retval = TRUE; @@ -2305,8 +2305,8 @@ start_glib_signal (GMarkupParseContext *context, MISSING_ATTRIBUTE (context, error, element_name, "name"); return FALSE; } - signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL, - ctx->current_module); + signal = (GIrNodeSignal *)_g_ir_node_new (G_IR_NODE_SIGNAL, + ctx->current_module); ((GIrNode *)signal)->name = g_strdup (name); @@ -2387,8 +2387,8 @@ start_vfunc (GMarkupParseContext *context, return FALSE; } - vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC, - ctx->current_module); + vfunc = (GIrNodeVFunc *)_g_ir_node_new (G_IR_NODE_VFUNC, + ctx->current_module); ((GIrNode *)vfunc)->name = g_strdup (name); @@ -2484,7 +2484,7 @@ start_struct (GMarkupParseContext *context, return FALSE; } - struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT, + struct_ = (GIrNodeStruct *) _g_ir_node_new (G_IR_NODE_STRUCT, ctx->current_module); ((GIrNode *)struct_)->name = g_strdup (name ? name : ""); @@ -2545,7 +2545,7 @@ start_union (GMarkupParseContext *context, return FALSE; } - union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION, + union_ = (GIrNodeUnion *) _g_ir_node_new (G_IR_NODE_UNION, ctx->current_module); ((GIrNode *)union_)->name = g_strdup (name ? name : ""); @@ -2654,7 +2654,7 @@ parse_include (GMarkupParseContext *context, return FALSE; } - module = g_ir_parser_parse_string (ctx->parser, name, girpath, buffer, length, &error); + module = _g_ir_parser_parse_string (ctx->parser, name, girpath, buffer, length, &error); g_free (buffer); if (error != NULL) { @@ -2890,7 +2890,7 @@ start_element_handler (GMarkupParseContext *context, " name element '%s' doesn't match file name '%s'", name, ctx->namespace); - ctx->current_module = g_ir_module_new (name, version, shared_library, cprefix); + ctx->current_module = _g_ir_module_new (name, version, shared_library, cprefix); ctx->current_module->aliases = ctx->aliases; ctx->aliases = NULL; @@ -2898,7 +2898,7 @@ start_element_handler (GMarkupParseContext *context, ctx->disguised_structures = NULL; for (l = ctx->include_modules; l; l = l->next) - g_ir_module_add_include_module (ctx->current_module, l->data); + _g_ir_module_add_include_module (ctx->current_module, l->data); g_list_free (ctx->include_modules); ctx->include_modules = NULL; @@ -3445,7 +3445,7 @@ cleanup (GMarkupParseContext *context, GList *m; for (m = ctx->modules; m; m = m->next) - g_ir_module_free (m->data); + _g_ir_module_free (m->data); g_list_free (ctx->modules); ctx->modules = NULL; @@ -3453,7 +3453,7 @@ cleanup (GMarkupParseContext *context, } /** - * g_ir_parser_parse_string: + * _g_ir_parser_parse_string: * @parser: a #GIrParser * @namespace: the namespace of the string * @filename: (allow-none): Path to parsed file, or %NULL @@ -3467,12 +3467,12 @@ cleanup (GMarkupParseContext *context, * Returns: (transfer none): a new #GirModule */ GIrModule * -g_ir_parser_parse_string (GIrParser *parser, - const gchar *namespace, - const gchar *filename, - const gchar *buffer, - gssize length, - GError **error) +_g_ir_parser_parse_string (GIrParser *parser, + const gchar *namespace, + const gchar *filename, + const gchar *buffer, + gssize length, + GError **error) { ParseContext ctx = { 0 }; GMarkupParseContext *context; @@ -3531,7 +3531,7 @@ g_ir_parser_parse_string (GIrParser *parser, } /** - * g_ir_parser_parse_file: + * _g_ir_parser_parse_file: * @parser: a #GIrParser * @filename: filename to parse * @error: return location for a #GError, or %NULL @@ -3543,9 +3543,9 @@ g_ir_parser_parse_string (GIrParser *parser, * are owned by the #GIrParser and will be freed along with the parser. */ GIrModule * -g_ir_parser_parse_file (GIrParser *parser, - const gchar *filename, - GError **error) +_g_ir_parser_parse_file (GIrParser *parser, + const gchar *filename, + GError **error) { gchar *buffer; gsize length; @@ -3580,7 +3580,7 @@ g_ir_parser_parse_file (GIrParser *parser, if (!g_file_get_contents (filename, &buffer, &length, error)) return NULL; - module = g_ir_parser_parse_string (parser, namespace, filename, buffer, length, error); + module = _g_ir_parser_parse_string (parser, namespace, filename, buffer, length, error); g_free (namespace); diff --git a/girparser.h b/girparser.h index 076c9818b..e56c63b51 100644 --- a/girparser.h +++ b/girparser.h @@ -29,20 +29,20 @@ G_BEGIN_DECLS typedef struct _GIrParser GIrParser; -GIrParser *g_ir_parser_new (void); -void g_ir_parser_free (GIrParser *parser); -void g_ir_parser_set_includes (GIrParser *parser, - const gchar *const *includes); +GIrParser *_g_ir_parser_new (void); +void _g_ir_parser_free (GIrParser *parser); +void _g_ir_parser_set_includes (GIrParser *parser, + const gchar *const *includes); -GIrModule *g_ir_parser_parse_string (GIrParser *parser, - const gchar *namespace, - const gchar *filename, - const gchar *buffer, - gssize length, - GError **error); -GIrModule *g_ir_parser_parse_file (GIrParser *parser, - const gchar *filename, - GError **error); +GIrModule *_g_ir_parser_parse_string (GIrParser *parser, + const gchar *namespace, + const gchar *filename, + const gchar *buffer, + gssize length, + GError **error); +GIrModule *_g_ir_parser_parse_file (GIrParser *parser, + const gchar *filename, + GError **error); G_END_DECLS From 6178293a83b77635fddfe0ba8da1626877edb0c0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 11 Nov 2010 15:01:07 -0500 Subject: [PATCH 413/692] Import CMPH 1.0 This will be used for typelib indexing. See README-CMPH-IMPORT.txt for more information. --- cmph/README-CMPH-IMPORT.txt | 5 + cmph/bdz.c | 703 +++++++++++++++++++++++++ cmph/bdz.h | 43 ++ cmph/bdz_gen_lookup_table.c | 33 ++ cmph/bdz_ph.c | 621 ++++++++++++++++++++++ cmph/bdz_ph.h | 42 ++ cmph/bdz_structs.h | 36 ++ cmph/bdz_structs_ph.h | 26 + cmph/bitbool.h | 179 +++++++ cmph/bmz.c | 620 ++++++++++++++++++++++ cmph/bmz.h | 42 ++ cmph/bmz8.c | 632 +++++++++++++++++++++++ cmph/bmz8.h | 42 ++ cmph/bmz8_structs.h | 25 + cmph/bmz_structs.h | 25 + cmph/brz.c | 985 +++++++++++++++++++++++++++++++++++ cmph/brz.h | 47 ++ cmph/brz_structs.h | 39 ++ cmph/buffer_entry.c | 103 ++++ cmph/buffer_entry.h | 14 + cmph/buffer_manage.c | 66 +++ cmph/buffer_manage.h | 12 + cmph/buffer_manager.c | 64 +++ cmph/buffer_manager.h | 12 + cmph/chd.c | 271 ++++++++++ cmph/chd.h | 59 +++ cmph/chd_ph.c | 988 ++++++++++++++++++++++++++++++++++++ cmph/chd_ph.h | 59 +++ cmph/chd_structs.h | 21 + cmph/chd_structs_ph.h | 29 ++ cmph/chm.c | 381 ++++++++++++++ cmph/chm.h | 42 ++ cmph/chm_structs.h | 24 + cmph/cmph.c | 845 ++++++++++++++++++++++++++++++ cmph/cmph.h | 112 ++++ cmph/cmph_structs.c | 69 +++ cmph/cmph_structs.h | 33 ++ cmph/cmph_time.h | 62 +++ cmph/cmph_types.h | 42 ++ cmph/compressed_rank.c | 321 ++++++++++++ cmph/compressed_rank.h | 55 ++ cmph/compressed_seq.c | 378 ++++++++++++++ cmph/compressed_seq.h | 84 +++ cmph/debug.h | 53 ++ cmph/djb2_hash.c | 49 ++ cmph/djb2_hash.h | 18 + cmph/fch.c | 517 +++++++++++++++++++ cmph/fch.h | 48 ++ cmph/fch_buckets.c | 214 ++++++++ cmph/fch_buckets.h | 30 ++ cmph/fch_structs.h | 30 ++ cmph/fnv_hash.c | 53 ++ cmph/fnv_hash.h | 18 + cmph/graph.c | 338 ++++++++++++ cmph/graph.h | 40 ++ cmph/hash.c | 216 ++++++++ cmph/hash.h | 76 +++ cmph/hash_state.h | 12 + cmph/hashtree.c | 289 +++++++++++ cmph/hashtree.h | 19 + cmph/hashtree_structs.h | 32 ++ cmph/jenkins_hash.c | 297 +++++++++++ cmph/jenkins_hash.h | 65 +++ cmph/main.c | 342 +++++++++++++ cmph/miller_rabin.c | 67 +++ cmph/miller_rabin.h | 5 + cmph/sdbm_hash.c | 49 ++ cmph/sdbm_hash.h | 18 + cmph/select.c | 337 ++++++++++++ cmph/select.h | 61 +++ cmph/select_lookup_tables.h | 170 +++++++ cmph/vqueue.c | 51 ++ cmph/vqueue.h | 18 + cmph/vstack.c | 79 +++ cmph/vstack.h | 18 + cmph/wingetopt.c | 179 +++++++ cmph/wingetopt.h | 25 + 77 files changed, 12124 insertions(+) create mode 100644 cmph/README-CMPH-IMPORT.txt create mode 100755 cmph/bdz.c create mode 100755 cmph/bdz.h create mode 100755 cmph/bdz_gen_lookup_table.c create mode 100755 cmph/bdz_ph.c create mode 100755 cmph/bdz_ph.h create mode 100755 cmph/bdz_structs.h create mode 100755 cmph/bdz_structs_ph.h create mode 100644 cmph/bitbool.h create mode 100644 cmph/bmz.c create mode 100644 cmph/bmz.h create mode 100644 cmph/bmz8.c create mode 100644 cmph/bmz8.h create mode 100644 cmph/bmz8_structs.h create mode 100644 cmph/bmz_structs.h create mode 100755 cmph/brz.c create mode 100644 cmph/brz.h create mode 100755 cmph/brz_structs.h create mode 100644 cmph/buffer_entry.c create mode 100644 cmph/buffer_entry.h create mode 100644 cmph/buffer_manage.c create mode 100644 cmph/buffer_manage.h create mode 100644 cmph/buffer_manager.c create mode 100644 cmph/buffer_manager.h create mode 100644 cmph/chd.c create mode 100644 cmph/chd.h create mode 100644 cmph/chd_ph.c create mode 100644 cmph/chd_ph.h create mode 100644 cmph/chd_structs.h create mode 100644 cmph/chd_structs_ph.h create mode 100644 cmph/chm.c create mode 100644 cmph/chm.h create mode 100644 cmph/chm_structs.h create mode 100644 cmph/cmph.c create mode 100644 cmph/cmph.h create mode 100644 cmph/cmph_structs.c create mode 100644 cmph/cmph_structs.h create mode 100644 cmph/cmph_time.h create mode 100644 cmph/cmph_types.h create mode 100644 cmph/compressed_rank.c create mode 100644 cmph/compressed_rank.h create mode 100644 cmph/compressed_seq.c create mode 100644 cmph/compressed_seq.h create mode 100644 cmph/debug.h create mode 100644 cmph/djb2_hash.c create mode 100644 cmph/djb2_hash.h create mode 100644 cmph/fch.c create mode 100644 cmph/fch.h create mode 100644 cmph/fch_buckets.c create mode 100644 cmph/fch_buckets.h create mode 100755 cmph/fch_structs.h create mode 100644 cmph/fnv_hash.c create mode 100644 cmph/fnv_hash.h create mode 100644 cmph/graph.c create mode 100644 cmph/graph.h create mode 100644 cmph/hash.c create mode 100644 cmph/hash.h create mode 100644 cmph/hash_state.h create mode 100644 cmph/hashtree.c create mode 100644 cmph/hashtree.h create mode 100644 cmph/hashtree_structs.h create mode 100644 cmph/jenkins_hash.c create mode 100644 cmph/jenkins_hash.h create mode 100644 cmph/main.c create mode 100644 cmph/miller_rabin.c create mode 100644 cmph/miller_rabin.h create mode 100644 cmph/sdbm_hash.c create mode 100644 cmph/sdbm_hash.h create mode 100644 cmph/select.c create mode 100644 cmph/select.h create mode 100644 cmph/select_lookup_tables.h create mode 100644 cmph/vqueue.c create mode 100644 cmph/vqueue.h create mode 100644 cmph/vstack.c create mode 100644 cmph/vstack.h create mode 100644 cmph/wingetopt.c create mode 100644 cmph/wingetopt.h diff --git a/cmph/README-CMPH-IMPORT.txt b/cmph/README-CMPH-IMPORT.txt new file mode 100644 index 000000000..a1c23c246 --- /dev/null +++ b/cmph/README-CMPH-IMPORT.txt @@ -0,0 +1,5 @@ +This import of CMPH was made from revision bfdcc3a3a18dfb9 of +git://cmph.git.sourceforge.net/gitroot/cmph/cmph + +Only the following files were taken, and everything else deleted: +COPYING src/*.[ch] diff --git a/cmph/bdz.c b/cmph/bdz.c new file mode 100755 index 000000000..f422c8f91 --- /dev/null +++ b/cmph/bdz.c @@ -0,0 +1,703 @@ +#include "bdz.h" +#include "cmph_structs.h" +#include "bdz_structs.h" +#include "hash.h" +#include "bitbool.h" + +#include +#include +#include +#include +#include +//#define DEBUG +#include "debug.h" +#define UNASSIGNED 3U +#define NULL_EDGE 0xffffffff + +//cmph_uint32 ngrafos = 0; +//cmph_uint32 ngrafos_aciclicos = 0; +// table used for looking up the number of assigned vertices a 8-bit integer +const cmph_uint8 bdz_lookup_table[] = +{ +4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2, +4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2, +4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2, +3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 1, +4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2, +4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2, +4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2, +3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 1, +4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2, +4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2, +4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2, +3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 1, +3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 1, +3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 1, +3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 1, +2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 1, 0 +}; + +typedef struct +{ + cmph_uint32 vertices[3]; + cmph_uint32 next_edges[3]; +}bdz_edge_t; + +typedef cmph_uint32 * bdz_queue_t; + +static void bdz_alloc_queue(bdz_queue_t * queuep, cmph_uint32 nedges) +{ + (*queuep)=malloc(nedges*sizeof(cmph_uint32)); +}; +static void bdz_free_queue(bdz_queue_t * queue) +{ + free(*queue); +}; + +typedef struct +{ + cmph_uint32 nedges; + bdz_edge_t * edges; + cmph_uint32 * first_edge; + cmph_uint8 * vert_degree; +}bdz_graph3_t; + + +static void bdz_alloc_graph3(bdz_graph3_t * graph3, cmph_uint32 nedges, cmph_uint32 nvertices) +{ + graph3->edges=malloc(nedges*sizeof(bdz_edge_t)); + graph3->first_edge=malloc(nvertices*sizeof(cmph_uint32)); + graph3->vert_degree=malloc((size_t)nvertices); +}; +static void bdz_init_graph3(bdz_graph3_t * graph3, cmph_uint32 nedges, cmph_uint32 nvertices) +{ + memset(graph3->first_edge,0xff,nvertices*sizeof(cmph_uint32)); + memset(graph3->vert_degree,0,(size_t)nvertices); + graph3->nedges=0; +}; +static void bdz_free_graph3(bdz_graph3_t *graph3) +{ + free(graph3->edges); + free(graph3->first_edge); + free(graph3->vert_degree); +}; + +static void bdz_partial_free_graph3(bdz_graph3_t *graph3) +{ + free(graph3->first_edge); + free(graph3->vert_degree); + graph3->first_edge = NULL; + graph3->vert_degree = NULL; +}; + +static void bdz_add_edge(bdz_graph3_t * graph3, cmph_uint32 v0, cmph_uint32 v1, cmph_uint32 v2) +{ + graph3->edges[graph3->nedges].vertices[0]=v0; + graph3->edges[graph3->nedges].vertices[1]=v1; + graph3->edges[graph3->nedges].vertices[2]=v2; + graph3->edges[graph3->nedges].next_edges[0]=graph3->first_edge[v0]; + graph3->edges[graph3->nedges].next_edges[1]=graph3->first_edge[v1]; + graph3->edges[graph3->nedges].next_edges[2]=graph3->first_edge[v2]; + graph3->first_edge[v0]=graph3->first_edge[v1]=graph3->first_edge[v2]=graph3->nedges; + graph3->vert_degree[v0]++; + graph3->vert_degree[v1]++; + graph3->vert_degree[v2]++; + graph3->nedges++; +}; + +static void bdz_dump_graph(bdz_graph3_t* graph3, cmph_uint32 nedges, cmph_uint32 nvertices) +{ + int i; + for(i=0;iedges[i].vertices[0], + graph3->edges[i].vertices[1],graph3->edges[i].vertices[2]); + printf(" nexts %d %d %d",graph3->edges[i].next_edges[0], + graph3->edges[i].next_edges[1],graph3->edges[i].next_edges[2]); + }; + + for(i=0;ifirst_edge[i]); + + }; +}; + +static void bdz_remove_edge(bdz_graph3_t * graph3, cmph_uint32 curr_edge) +{ + cmph_uint32 i,j=0,vert,edge1,edge2; + for(i=0;i<3;i++){ + vert=graph3->edges[curr_edge].vertices[i]; + edge1=graph3->first_edge[vert]; + edge2=NULL_EDGE; + while(edge1!=curr_edge&&edge1!=NULL_EDGE){ + edge2=edge1; + if(graph3->edges[edge1].vertices[0]==vert){ + j=0; + } else if(graph3->edges[edge1].vertices[1]==vert){ + j=1; + } else + j=2; + edge1=graph3->edges[edge1].next_edges[j]; + }; + if(edge1==NULL_EDGE){ + printf("\nerror remove edge %d dump graph",curr_edge); + bdz_dump_graph(graph3,graph3->nedges,graph3->nedges+graph3->nedges/4); + exit(-1); + }; + + if(edge2!=NULL_EDGE){ + graph3->edges[edge2].next_edges[j] = + graph3->edges[edge1].next_edges[i]; + } else + graph3->first_edge[vert]= + graph3->edges[edge1].next_edges[i]; + graph3->vert_degree[vert]--; + }; + +}; + +static int bdz_generate_queue(cmph_uint32 nedges, cmph_uint32 nvertices, bdz_queue_t queue, bdz_graph3_t* graph3) +{ + cmph_uint32 i,v0,v1,v2; + cmph_uint32 queue_head=0,queue_tail=0; + cmph_uint32 curr_edge; + cmph_uint32 tmp_edge; + cmph_uint8 * marked_edge =malloc((size_t)(nedges >> 3) + 1); + memset(marked_edge, 0, (size_t)(nedges >> 3) + 1); + + for(i=0;iedges[i].vertices[0]; + v1=graph3->edges[i].vertices[1]; + v2=graph3->edges[i].vertices[2]; + if(graph3->vert_degree[v0]==1 || + graph3->vert_degree[v1]==1 || + graph3->vert_degree[v2]==1){ + if(!GETBIT(marked_edge,i)) { + queue[queue_head++]=i; + SETBIT(marked_edge,i); + } + }; + }; + while(queue_tail!=queue_head){ + curr_edge=queue[queue_tail++]; + bdz_remove_edge(graph3,curr_edge); + v0=graph3->edges[curr_edge].vertices[0]; + v1=graph3->edges[curr_edge].vertices[1]; + v2=graph3->edges[curr_edge].vertices[2]; + if(graph3->vert_degree[v0]==1 ) { + tmp_edge=graph3->first_edge[v0]; + if(!GETBIT(marked_edge,tmp_edge)) { + queue[queue_head++]=tmp_edge; + SETBIT(marked_edge,tmp_edge); + }; + + }; + if(graph3->vert_degree[v1]==1) { + tmp_edge=graph3->first_edge[v1]; + if(!GETBIT(marked_edge,tmp_edge)){ + queue[queue_head++]=tmp_edge; + SETBIT(marked_edge,tmp_edge); + }; + + }; + if(graph3->vert_degree[v2]==1){ + tmp_edge=graph3->first_edge[v2]; + if(!GETBIT(marked_edge,tmp_edge)){ + queue[queue_head++]=tmp_edge; + SETBIT(marked_edge,tmp_edge); + }; + }; + }; + free(marked_edge); + return (int)(queue_head-nedges);/* returns 0 if successful otherwies return negative number*/ +}; + +static int bdz_mapping(cmph_config_t *mph, bdz_graph3_t* graph3, bdz_queue_t queue); +static void assigning(bdz_config_data_t *bdz, bdz_graph3_t* graph3, bdz_queue_t queue); +static void ranking(bdz_config_data_t *bdz); +static cmph_uint32 rank(cmph_uint32 b, cmph_uint32 * ranktable, cmph_uint8 * g, cmph_uint32 vertex); + +bdz_config_data_t *bdz_config_new() +{ + bdz_config_data_t *bdz; + bdz = (bdz_config_data_t *)malloc(sizeof(bdz_config_data_t)); + assert(bdz); + memset(bdz, 0, sizeof(bdz_config_data_t)); + bdz->hashfunc = CMPH_HASH_JENKINS; + bdz->g = NULL; + bdz->hl = NULL; + bdz->k = 0; //kth index in ranktable, $k = log_2(n=3r)/\varepsilon$ + bdz->b = 7; // number of bits of k + bdz->ranktablesize = 0; //number of entries in ranktable, $n/k +1$ + bdz->ranktable = NULL; // rank table + return bdz; +} + +void bdz_config_destroy(cmph_config_t *mph) +{ + bdz_config_data_t *data = (bdz_config_data_t *)mph->data; + DEBUGP("Destroying algorithm dependent data\n"); + free(data); +} + +void bdz_config_set_b(cmph_config_t *mph, cmph_uint32 b) +{ + bdz_config_data_t *bdz = (bdz_config_data_t *)mph->data; + if (b <= 2 || b > 10) b = 7; // validating restrictions over parameter b. + bdz->b = (cmph_uint8)b; + DEBUGP("b: %u\n", b); + +} + +void bdz_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs) +{ + bdz_config_data_t *bdz = (bdz_config_data_t *)mph->data; + CMPH_HASH *hashptr = hashfuncs; + cmph_uint32 i = 0; + while(*hashptr != CMPH_HASH_COUNT) + { + if (i >= 1) break; //bdz only uses one linear hash function + bdz->hashfunc = *hashptr; + ++i, ++hashptr; + } +} + +cmph_t *bdz_new(cmph_config_t *mph, double c) +{ + cmph_t *mphf = NULL; + bdz_data_t *bdzf = NULL; + cmph_uint32 iterations; + bdz_queue_t edges; + bdz_graph3_t graph3; + bdz_config_data_t *bdz = (bdz_config_data_t *)mph->data; + #ifdef CMPH_TIMING + double construction_time_begin = 0.0; + double construction_time = 0.0; + ELAPSED_TIME_IN_SECONDS(&construction_time_begin); + #endif + + + if (c == 0) c = 1.23; // validating restrictions over parameter c. + DEBUGP("c: %f\n", c); + bdz->m = mph->key_source->nkeys; + bdz->r = (cmph_uint32)ceil((c * mph->key_source->nkeys)/3); + if ((bdz->r % 2) == 0) bdz->r+=1; + bdz->n = 3*bdz->r; + + bdz->k = (1U << bdz->b); + DEBUGP("b: %u -- k: %u\n", bdz->b, bdz->k); + + bdz->ranktablesize = (cmph_uint32)ceil(bdz->n/(double)bdz->k); + DEBUGP("ranktablesize: %u\n", bdz->ranktablesize); + + + bdz_alloc_graph3(&graph3, bdz->m, bdz->n); + bdz_alloc_queue(&edges,bdz->m); + DEBUGP("Created hypergraph\n"); + + DEBUGP("m (edges): %u n (vertices): %u r: %u c: %f \n", bdz->m, bdz->n, bdz->r, c); + + // Mapping step + iterations = 1000; + if (mph->verbosity) + { + fprintf(stderr, "Entering mapping step for mph creation of %u keys with graph sized %u\n", bdz->m, bdz->n); + } + while(1) + { + int ok; + DEBUGP("linear hash function \n"); + bdz->hl = hash_state_new(bdz->hashfunc, 15); + + ok = bdz_mapping(mph, &graph3, edges); + //ok = 0; + if (!ok) + { + --iterations; + hash_state_destroy(bdz->hl); + bdz->hl = NULL; + DEBUGP("%u iterations remaining\n", iterations); + if (mph->verbosity) + { + fprintf(stderr, "acyclic graph creation failure - %u iterations remaining\n", iterations); + } + if (iterations == 0) break; + } + else break; + } + + if (iterations == 0) + { + bdz_free_queue(&edges); + bdz_free_graph3(&graph3); + return NULL; + } + bdz_partial_free_graph3(&graph3); + // Assigning step + if (mph->verbosity) + { + fprintf(stderr, "Entering assigning step for mph creation of %u keys with graph sized %u\n", bdz->m, bdz->n); + } + assigning(bdz, &graph3, edges); + + bdz_free_queue(&edges); + bdz_free_graph3(&graph3); + if (mph->verbosity) + { + fprintf(stderr, "Entering ranking step for mph creation of %u keys with graph sized %u\n", bdz->m, bdz->n); + } + ranking(bdz); + #ifdef CMPH_TIMING + ELAPSED_TIME_IN_SECONDS(&construction_time); + #endif + mphf = (cmph_t *)malloc(sizeof(cmph_t)); + mphf->algo = mph->algo; + bdzf = (bdz_data_t *)malloc(sizeof(bdz_data_t)); + bdzf->g = bdz->g; + bdz->g = NULL; //transfer memory ownership + bdzf->hl = bdz->hl; + bdz->hl = NULL; //transfer memory ownership + bdzf->ranktable = bdz->ranktable; + bdz->ranktable = NULL; //transfer memory ownership + bdzf->ranktablesize = bdz->ranktablesize; + bdzf->k = bdz->k; + bdzf->b = bdz->b; + bdzf->n = bdz->n; + bdzf->m = bdz->m; + bdzf->r = bdz->r; + mphf->data = bdzf; + mphf->size = bdz->m; + + DEBUGP("Successfully generated minimal perfect hash\n"); + if (mph->verbosity) + { + fprintf(stderr, "Successfully generated minimal perfect hash function\n"); + } + + + #ifdef CMPH_TIMING + register cmph_uint32 space_usage = bdz_packed_size(mphf)*8; + register cmph_uint32 keys_per_bucket = 1; + construction_time = construction_time - construction_time_begin; + fprintf(stdout, "%u\t%.2f\t%u\t%.4f\t%.4f\n", bdz->m, bdz->m/(double)bdz->n, keys_per_bucket, construction_time, space_usage/(double)bdz->m); + #endif + + return mphf; +} + + +static int bdz_mapping(cmph_config_t *mph, bdz_graph3_t* graph3, bdz_queue_t queue) +{ + cmph_uint32 e; + int cycles = 0; + cmph_uint32 hl[3]; + bdz_config_data_t *bdz = (bdz_config_data_t *)mph->data; + bdz_init_graph3(graph3, bdz->m, bdz->n); + mph->key_source->rewind(mph->key_source->data); + for (e = 0; e < mph->key_source->nkeys; ++e) + { + cmph_uint32 h0, h1, h2; + cmph_uint32 keylen; + char *key = NULL; + mph->key_source->read(mph->key_source->data, &key, &keylen); + hash_vector(bdz->hl, key, keylen,hl); + h0 = hl[0] % bdz->r; + h1 = hl[1] % bdz->r + bdz->r; + h2 = hl[2] % bdz->r + (bdz->r << 1); + mph->key_source->dispose(mph->key_source->data, key, keylen); + bdz_add_edge(graph3,h0,h1,h2); + } + cycles = bdz_generate_queue(bdz->m, bdz->n, queue, graph3); + return (cycles == 0); +} + +static void assigning(bdz_config_data_t *bdz, bdz_graph3_t* graph3, bdz_queue_t queue) +{ + cmph_uint32 i; + cmph_uint32 nedges=graph3->nedges; + cmph_uint32 curr_edge; + cmph_uint32 v0,v1,v2; + cmph_uint8 * marked_vertices =malloc((size_t)(bdz->n >> 3) + 1); + cmph_uint32 sizeg = (cmph_uint32)ceil(bdz->n/4.0); + bdz->g = (cmph_uint8 *)calloc((size_t)(sizeg), sizeof(cmph_uint8)); + memset(marked_vertices, 0, (size_t)(bdz->n >> 3) + 1); + memset(bdz->g, 0xff, (size_t)(sizeg)); + + for(i=nedges-1;i+1>=1;i--){ + curr_edge=queue[i]; + v0=graph3->edges[curr_edge].vertices[0]; + v1=graph3->edges[curr_edge].vertices[1]; + v2=graph3->edges[curr_edge].vertices[2]; + DEBUGP("B:%u %u %u -- %u %u %u\n", v0, v1, v2, GETVALUE(bdz->g, v0), GETVALUE(bdz->g, v1), GETVALUE(bdz->g, v2)); + if(!GETBIT(marked_vertices, v0)){ + if(!GETBIT(marked_vertices,v1)) + { + SETVALUE1(bdz->g, v1, UNASSIGNED); + SETBIT(marked_vertices, v1); + } + if(!GETBIT(marked_vertices,v2)) + { + SETVALUE1(bdz->g, v2, UNASSIGNED); + SETBIT(marked_vertices, v2); + } + SETVALUE1(bdz->g, v0, (6-(GETVALUE(bdz->g, v1) + GETVALUE(bdz->g,v2)))%3); + SETBIT(marked_vertices, v0); + } else if(!GETBIT(marked_vertices, v1)) { + if(!GETBIT(marked_vertices, v2)) + { + SETVALUE1(bdz->g, v2, UNASSIGNED); + SETBIT(marked_vertices, v2); + } + SETVALUE1(bdz->g, v1, (7-(GETVALUE(bdz->g, v0)+GETVALUE(bdz->g, v2)))%3); + SETBIT(marked_vertices, v1); + }else { + SETVALUE1(bdz->g, v2, (8-(GETVALUE(bdz->g,v0)+GETVALUE(bdz->g, v1)))%3); + SETBIT(marked_vertices, v2); + } + DEBUGP("A:%u %u %u -- %u %u %u\n", v0, v1, v2, GETVALUE(bdz->g, v0), GETVALUE(bdz->g, v1), GETVALUE(bdz->g, v2)); + }; + free(marked_vertices); +} + + +static void ranking(bdz_config_data_t *bdz) +{ + cmph_uint32 i, j, offset = 0U, count = 0U, size = (bdz->k >> 2U), nbytes_total = (cmph_uint32)ceil(bdz->n/4.0), nbytes; + bdz->ranktable = (cmph_uint32 *)calloc((size_t)bdz->ranktablesize, sizeof(cmph_uint32)); + // ranktable computation + bdz->ranktable[0] = 0; + i = 1; + while(1) + { + if(i == bdz->ranktablesize) break; + nbytes = size < nbytes_total? size : nbytes_total; + for(j = 0; j < nbytes; j++) + { + count += bdz_lookup_table[*(bdz->g + offset + j)]; + } + bdz->ranktable[i] = count; + offset += nbytes; + nbytes_total -= size; + i++; + } +} + + +int bdz_dump(cmph_t *mphf, FILE *fd) +{ + char *buf = NULL; + cmph_uint32 buflen; + register size_t nbytes; + bdz_data_t *data = (bdz_data_t *)mphf->data; + __cmph_dump(mphf, fd); + + hash_state_dump(data->hl, &buf, &buflen); + DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); + nbytes = fwrite(&buflen, sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(buf, (size_t)buflen, (size_t)1, fd); + free(buf); + + nbytes = fwrite(&(data->n), sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(&(data->m), sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(&(data->r), sizeof(cmph_uint32), (size_t)1, fd); + + cmph_uint32 sizeg = (cmph_uint32)ceil(data->n/4.0); + nbytes = fwrite(data->g, sizeof(cmph_uint8)*sizeg, (size_t)1, fd); + + nbytes = fwrite(&(data->k), sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(&(data->b), sizeof(cmph_uint8), (size_t)1, fd); + nbytes = fwrite(&(data->ranktablesize), sizeof(cmph_uint32), (size_t)1, fd); + + nbytes = fwrite(data->ranktable, sizeof(cmph_uint32)*(data->ranktablesize), (size_t)1, fd); + #ifdef DEBUG + cmph_uint32 i; + fprintf(stderr, "G: "); + for (i = 0; i < data->n; ++i) fprintf(stderr, "%u ", GETVALUE(data->g, i)); + fprintf(stderr, "\n"); + #endif + return 1; +} + +void bdz_load(FILE *f, cmph_t *mphf) +{ + char *buf = NULL; + cmph_uint32 buflen, sizeg; + register size_t nbytes; + bdz_data_t *bdz = (bdz_data_t *)malloc(sizeof(bdz_data_t)); + + DEBUGP("Loading bdz mphf\n"); + mphf->data = bdz; + + nbytes = fread(&buflen, sizeof(cmph_uint32), (size_t)1, f); + DEBUGP("Hash state has %u bytes\n", buflen); + buf = (char *)malloc((size_t)buflen); + nbytes = fread(buf, (size_t)buflen, (size_t)1, f); + bdz->hl = hash_state_load(buf, buflen); + free(buf); + + + DEBUGP("Reading m and n\n"); + nbytes = fread(&(bdz->n), sizeof(cmph_uint32), (size_t)1, f); + nbytes = fread(&(bdz->m), sizeof(cmph_uint32), (size_t)1, f); + nbytes = fread(&(bdz->r), sizeof(cmph_uint32), (size_t)1, f); + sizeg = (cmph_uint32)ceil(bdz->n/4.0); + bdz->g = (cmph_uint8 *)calloc((size_t)(sizeg), sizeof(cmph_uint8)); + nbytes = fread(bdz->g, sizeg*sizeof(cmph_uint8), (size_t)1, f); + + nbytes = fread(&(bdz->k), sizeof(cmph_uint32), (size_t)1, f); + nbytes = fread(&(bdz->b), sizeof(cmph_uint8), (size_t)1, f); + nbytes = fread(&(bdz->ranktablesize), sizeof(cmph_uint32), (size_t)1, f); + + bdz->ranktable = (cmph_uint32 *)calloc((size_t)bdz->ranktablesize, sizeof(cmph_uint32)); + nbytes = fread(bdz->ranktable, sizeof(cmph_uint32)*(bdz->ranktablesize), (size_t)1, f); + + #ifdef DEBUG + cmph_uint32 i = 0; + fprintf(stderr, "G: "); + for (i = 0; i < bdz->n; ++i) fprintf(stderr, "%u ", GETVALUE(bdz->g,i)); + fprintf(stderr, "\n"); + #endif + return; +} + + +cmph_uint32 bdz_search_ph(cmph_t *mphf, const char *key, cmph_uint32 keylen) +{ + bdz_data_t *bdz = mphf->data; + cmph_uint32 hl[3]; + hash_vector(bdz->hl, key, keylen, hl); + cmph_uint32 vertex; + hl[0] = hl[0] % bdz->r; + hl[1] = hl[1] % bdz->r + bdz->r; + hl[2] = hl[2] % bdz->r + (bdz->r << 1); + vertex = hl[(GETVALUE(bdz->g, hl[0]) + GETVALUE(bdz->g, hl[1]) + GETVALUE(bdz->g, hl[2])) % 3]; + return vertex; +} + +static inline cmph_uint32 rank(cmph_uint32 b, cmph_uint32 * ranktable, cmph_uint8 * g, cmph_uint32 vertex) +{ + register cmph_uint32 index = vertex >> b; + register cmph_uint32 base_rank = ranktable[index]; + register cmph_uint32 beg_idx_v = index << b; + register cmph_uint32 beg_idx_b = beg_idx_v >> 2; + register cmph_uint32 end_idx_b = vertex >> 2; + while(beg_idx_b < end_idx_b) + { + base_rank += bdz_lookup_table[*(g + beg_idx_b++)]; + + } + beg_idx_v = beg_idx_b << 2; + while(beg_idx_v < vertex) + { + if(GETVALUE(g, beg_idx_v) != UNASSIGNED) base_rank++; + beg_idx_v++; + } + + return base_rank; +} + +cmph_uint32 bdz_search(cmph_t *mphf, const char *key, cmph_uint32 keylen) +{ + register cmph_uint32 vertex; + register bdz_data_t *bdz = mphf->data; + cmph_uint32 hl[3]; + hash_vector(bdz->hl, key, keylen, hl); + hl[0] = hl[0] % bdz->r; + hl[1] = hl[1] % bdz->r + bdz->r; + hl[2] = hl[2] % bdz->r + (bdz->r << 1); + vertex = hl[(GETVALUE(bdz->g, hl[0]) + GETVALUE(bdz->g, hl[1]) + GETVALUE(bdz->g, hl[2])) % 3]; + return rank(bdz->b, bdz->ranktable, bdz->g, vertex); +} + + +void bdz_destroy(cmph_t *mphf) +{ + bdz_data_t *data = (bdz_data_t *)mphf->data; + free(data->g); + hash_state_destroy(data->hl); + free(data->ranktable); + free(data); + free(mphf); +} + +/** \fn void bdz_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void bdz_pack(cmph_t *mphf, void *packed_mphf) +{ + bdz_data_t *data = (bdz_data_t *)mphf->data; + cmph_uint8 * ptr = packed_mphf; + + // packing hl type + CMPH_HASH hl_type = hash_get_type(data->hl); + *((cmph_uint32 *) ptr) = hl_type; + ptr += sizeof(cmph_uint32); + + // packing hl + hash_state_pack(data->hl, ptr); + ptr += hash_state_packed_size(hl_type); + + // packing r + *((cmph_uint32 *) ptr) = data->r; + ptr += sizeof(data->r); + + // packing ranktablesize + *((cmph_uint32 *) ptr) = data->ranktablesize; + ptr += sizeof(data->ranktablesize); + + // packing ranktable + memcpy(ptr, data->ranktable, sizeof(cmph_uint32)*(data->ranktablesize)); + ptr += sizeof(cmph_uint32)*(data->ranktablesize); + + // packing b + *ptr++ = data->b; + + // packing g + cmph_uint32 sizeg = (cmph_uint32)ceil(data->n/4.0); + memcpy(ptr, data->g, sizeof(cmph_uint8)*sizeg); +} + +/** \fn cmph_uint32 bdz_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 bdz_packed_size(cmph_t *mphf) +{ + bdz_data_t *data = (bdz_data_t *)mphf->data; + + CMPH_HASH hl_type = hash_get_type(data->hl); + + return (cmph_uint32)(sizeof(CMPH_ALGO) + hash_state_packed_size(hl_type) + 3*sizeof(cmph_uint32) + sizeof(cmph_uint32)*(data->ranktablesize) + sizeof(cmph_uint8) + sizeof(cmph_uint8)* (cmph_uint32)(ceil(data->n/4.0))); +} + +/** cmph_uint32 bdz_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint32 bdz_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen) +{ + + register cmph_uint32 vertex; + register CMPH_HASH hl_type = *(cmph_uint32 *)packed_mphf; + register cmph_uint8 *hl_ptr = (cmph_uint8 *)(packed_mphf) + 4; + + register cmph_uint32 *ranktable = (cmph_uint32*)(hl_ptr + hash_state_packed_size(hl_type)); + + register cmph_uint32 r = *ranktable++; + register cmph_uint32 ranktablesize = *ranktable++; + register cmph_uint8 * g = (cmph_uint8 *)(ranktable + ranktablesize); + register cmph_uint8 b = *g++; + + cmph_uint32 hl[3]; + hash_vector_packed(hl_ptr, hl_type, key, keylen, hl); + hl[0] = hl[0] % r; + hl[1] = hl[1] % r + r; + hl[2] = hl[2] % r + (r << 1); + vertex = hl[(GETVALUE(g, hl[0]) + GETVALUE(g, hl[1]) + GETVALUE(g, hl[2])) % 3]; + return rank(b, ranktable, g, vertex); +} diff --git a/cmph/bdz.h b/cmph/bdz.h new file mode 100755 index 000000000..f2b7b89c2 --- /dev/null +++ b/cmph/bdz.h @@ -0,0 +1,43 @@ +#ifndef __CMPH_BDZ_H__ +#define __CMPH_BDZ_H__ + +#include "cmph.h" + +typedef struct __bdz_data_t bdz_data_t; +typedef struct __bdz_config_data_t bdz_config_data_t; + +bdz_config_data_t *bdz_config_new(); +void bdz_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); +void bdz_config_destroy(cmph_config_t *mph); +void bdz_config_set_b(cmph_config_t *mph, cmph_uint32 b); +cmph_t *bdz_new(cmph_config_t *mph, double c); + +void bdz_load(FILE *f, cmph_t *mphf); +int bdz_dump(cmph_t *mphf, FILE *f); +void bdz_destroy(cmph_t *mphf); +cmph_uint32 bdz_search(cmph_t *mphf, const char *key, cmph_uint32 keylen); + +/** \fn void bdz_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void bdz_pack(cmph_t *mphf, void *packed_mphf); + +/** \fn cmph_uint32 bdz_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 bdz_packed_size(cmph_t *mphf); + +/** cmph_uint32 bdz_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint32 bdz_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen); + +#endif diff --git a/cmph/bdz_gen_lookup_table.c b/cmph/bdz_gen_lookup_table.c new file mode 100755 index 000000000..b8f66068d --- /dev/null +++ b/cmph/bdz_gen_lookup_table.c @@ -0,0 +1,33 @@ +#include +#include +#include +void help(char * prname) +{ + fprintf(stderr, "USE: %s \n", prname); + exit(1); +} + +int main(int argc, char ** argv) +{ + if(argc != 3) help(argv[0]); + int n = atoi(argv[1]); + int wordsize = (atoi(argv[2]) >> 1); + int i, j, n_assigned; + for(i = 0; i < n; i++) + { + int num = i; + n_assigned = 0; + for(j = 0; j < wordsize; j++) + { + if ((num & 0x0003) != 3) + { + n_assigned++; + //fprintf(stderr, "num:%d\n", num); + } + num = num >> 2; + } + if(i%16 == 0) fprintf(stderr, "\n"); + fprintf(stderr, "%d, ", n_assigned); + } + fprintf(stderr, "\n"); +} diff --git a/cmph/bdz_ph.c b/cmph/bdz_ph.c new file mode 100755 index 000000000..49cf56463 --- /dev/null +++ b/cmph/bdz_ph.c @@ -0,0 +1,621 @@ +#include "bdz_ph.h" +#include "cmph_structs.h" +#include "bdz_structs_ph.h" +#include "hash.h" +#include "bitbool.h" + +#include +#include +#include +#include +#include +//#define DEBUG +#include "debug.h" +#define UNASSIGNED 3 +#define NULL_EDGE 0xffffffff + + +static cmph_uint8 pow3_table[5] = {1,3,9,27,81}; +static cmph_uint8 lookup_table[5][256] = { + {0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0}, + {0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1, 1, 1, 2, 2, 2, 0, 0, 0, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +}; + +typedef struct +{ + cmph_uint32 vertices[3]; + cmph_uint32 next_edges[3]; +}bdz_ph_edge_t; + +typedef cmph_uint32 * bdz_ph_queue_t; + +static void bdz_ph_alloc_queue(bdz_ph_queue_t * queuep, cmph_uint32 nedges) +{ + (*queuep)=malloc(nedges*sizeof(cmph_uint32)); +}; +static void bdz_ph_free_queue(bdz_ph_queue_t * queue) +{ + free(*queue); +}; + +typedef struct +{ + cmph_uint32 nedges; + bdz_ph_edge_t * edges; + cmph_uint32 * first_edge; + cmph_uint8 * vert_degree; +}bdz_ph_graph3_t; + + +static void bdz_ph_alloc_graph3(bdz_ph_graph3_t * graph3, cmph_uint32 nedges, cmph_uint32 nvertices) +{ + graph3->edges=malloc(nedges*sizeof(bdz_ph_edge_t)); + graph3->first_edge=malloc(nvertices*sizeof(cmph_uint32)); + graph3->vert_degree=malloc((size_t)nvertices); +}; +static void bdz_ph_init_graph3(bdz_ph_graph3_t * graph3, cmph_uint32 nedges, cmph_uint32 nvertices) +{ + memset(graph3->first_edge,0xff,nvertices*sizeof(cmph_uint32)); + memset(graph3->vert_degree,0,(size_t)nvertices); + graph3->nedges=0; +}; +static void bdz_ph_free_graph3(bdz_ph_graph3_t *graph3) +{ + free(graph3->edges); + free(graph3->first_edge); + free(graph3->vert_degree); +}; + +static void bdz_ph_partial_free_graph3(bdz_ph_graph3_t *graph3) +{ + free(graph3->first_edge); + free(graph3->vert_degree); + graph3->first_edge = NULL; + graph3->vert_degree = NULL; +}; + +static void bdz_ph_add_edge(bdz_ph_graph3_t * graph3, cmph_uint32 v0, cmph_uint32 v1, cmph_uint32 v2) +{ + graph3->edges[graph3->nedges].vertices[0]=v0; + graph3->edges[graph3->nedges].vertices[1]=v1; + graph3->edges[graph3->nedges].vertices[2]=v2; + graph3->edges[graph3->nedges].next_edges[0]=graph3->first_edge[v0]; + graph3->edges[graph3->nedges].next_edges[1]=graph3->first_edge[v1]; + graph3->edges[graph3->nedges].next_edges[2]=graph3->first_edge[v2]; + graph3->first_edge[v0]=graph3->first_edge[v1]=graph3->first_edge[v2]=graph3->nedges; + graph3->vert_degree[v0]++; + graph3->vert_degree[v1]++; + graph3->vert_degree[v2]++; + graph3->nedges++; +}; + +static void bdz_ph_dump_graph(bdz_ph_graph3_t* graph3, cmph_uint32 nedges, cmph_uint32 nvertices) +{ + int i; + for(i=0;iedges[i].vertices[0], + graph3->edges[i].vertices[1],graph3->edges[i].vertices[2]); + printf(" nexts %d %d %d",graph3->edges[i].next_edges[0], + graph3->edges[i].next_edges[1],graph3->edges[i].next_edges[2]); + }; + + for(i=0;ifirst_edge[i]); + + }; +}; + +static void bdz_ph_remove_edge(bdz_ph_graph3_t * graph3, cmph_uint32 curr_edge) +{ + cmph_uint32 i,j=0,vert,edge1,edge2; + for(i=0;i<3;i++){ + vert=graph3->edges[curr_edge].vertices[i]; + edge1=graph3->first_edge[vert]; + edge2=NULL_EDGE; + while(edge1!=curr_edge&&edge1!=NULL_EDGE){ + edge2=edge1; + if(graph3->edges[edge1].vertices[0]==vert){ + j=0; + } else if(graph3->edges[edge1].vertices[1]==vert){ + j=1; + } else + j=2; + edge1=graph3->edges[edge1].next_edges[j]; + }; + if(edge1==NULL_EDGE){ + printf("\nerror remove edge %d dump graph",curr_edge); + bdz_ph_dump_graph(graph3,graph3->nedges,graph3->nedges+graph3->nedges/4); + exit(-1); + }; + + if(edge2!=NULL_EDGE){ + graph3->edges[edge2].next_edges[j] = + graph3->edges[edge1].next_edges[i]; + } else + graph3->first_edge[vert]= + graph3->edges[edge1].next_edges[i]; + graph3->vert_degree[vert]--; + }; + +}; + +static int bdz_ph_generate_queue(cmph_uint32 nedges, cmph_uint32 nvertices, bdz_ph_queue_t queue, bdz_ph_graph3_t* graph3) +{ + cmph_uint32 i,v0,v1,v2; + cmph_uint32 queue_head=0,queue_tail=0; + cmph_uint32 curr_edge; + cmph_uint32 tmp_edge; + cmph_uint8 * marked_edge =malloc((size_t)(nedges >> 3) + 1); + memset(marked_edge, 0, (size_t)(nedges >> 3) + 1); + + for(i=0;iedges[i].vertices[0]; + v1=graph3->edges[i].vertices[1]; + v2=graph3->edges[i].vertices[2]; + if(graph3->vert_degree[v0]==1 || + graph3->vert_degree[v1]==1 || + graph3->vert_degree[v2]==1){ + if(!GETBIT(marked_edge,i)) { + queue[queue_head++]=i; + SETBIT(marked_edge,i); + } + }; + }; + while(queue_tail!=queue_head){ + curr_edge=queue[queue_tail++]; + bdz_ph_remove_edge(graph3,curr_edge); + v0=graph3->edges[curr_edge].vertices[0]; + v1=graph3->edges[curr_edge].vertices[1]; + v2=graph3->edges[curr_edge].vertices[2]; + if(graph3->vert_degree[v0]==1 ) { + tmp_edge=graph3->first_edge[v0]; + if(!GETBIT(marked_edge,tmp_edge)) { + queue[queue_head++]=tmp_edge; + SETBIT(marked_edge,tmp_edge); + }; + + }; + if(graph3->vert_degree[v1]==1) { + tmp_edge=graph3->first_edge[v1]; + if(!GETBIT(marked_edge,tmp_edge)){ + queue[queue_head++]=tmp_edge; + SETBIT(marked_edge,tmp_edge); + }; + + }; + if(graph3->vert_degree[v2]==1){ + tmp_edge=graph3->first_edge[v2]; + if(!GETBIT(marked_edge,tmp_edge)){ + queue[queue_head++]=tmp_edge; + SETBIT(marked_edge,tmp_edge); + }; + }; + }; + free(marked_edge); + return (int)queue_head - (int)nedges;/* returns 0 if successful otherwies return negative number*/ +}; + +static int bdz_ph_mapping(cmph_config_t *mph, bdz_ph_graph3_t* graph3, bdz_ph_queue_t queue); +static void assigning(bdz_ph_config_data_t *bdz_ph, bdz_ph_graph3_t* graph3, bdz_ph_queue_t queue); +static void bdz_ph_optimization(bdz_ph_config_data_t *bdz_ph); + +bdz_ph_config_data_t *bdz_ph_config_new() +{ + bdz_ph_config_data_t *bdz_ph; + bdz_ph = (bdz_ph_config_data_t *)malloc(sizeof(bdz_ph_config_data_t)); + assert(bdz_ph); + memset(bdz_ph, 0, sizeof(bdz_ph_config_data_t)); + bdz_ph->hashfunc = CMPH_HASH_JENKINS; + bdz_ph->g = NULL; + bdz_ph->hl = NULL; + return bdz_ph; +} + +void bdz_ph_config_destroy(cmph_config_t *mph) +{ + bdz_ph_config_data_t *data = (bdz_ph_config_data_t *)mph->data; + DEBUGP("Destroying algorithm dependent data\n"); + free(data); +} + +void bdz_ph_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs) +{ + bdz_ph_config_data_t *bdz_ph = (bdz_ph_config_data_t *)mph->data; + CMPH_HASH *hashptr = hashfuncs; + cmph_uint32 i = 0; + while(*hashptr != CMPH_HASH_COUNT) + { + if (i >= 1) break; //bdz_ph only uses one linear hash function + bdz_ph->hashfunc = *hashptr; + ++i, ++hashptr; + } +} + +cmph_t *bdz_ph_new(cmph_config_t *mph, double c) +{ + cmph_t *mphf = NULL; + bdz_ph_data_t *bdz_phf = NULL; + cmph_uint32 iterations; + bdz_ph_queue_t edges; + bdz_ph_graph3_t graph3; + bdz_ph_config_data_t *bdz_ph = (bdz_ph_config_data_t *)mph->data; + #ifdef CMPH_TIMING + double construction_time_begin = 0.0; + double construction_time = 0.0; + ELAPSED_TIME_IN_SECONDS(&construction_time_begin); + #endif + + + if (c == 0) c = 1.23; // validating restrictions over parameter c. + DEBUGP("c: %f\n", c); + bdz_ph->m = mph->key_source->nkeys; + bdz_ph->r = (cmph_uint32)ceil((c * mph->key_source->nkeys)/3); + if ((bdz_ph->r % 2) == 0) bdz_ph->r += 1; + bdz_ph->n = 3*bdz_ph->r; + + + bdz_ph_alloc_graph3(&graph3, bdz_ph->m, bdz_ph->n); + bdz_ph_alloc_queue(&edges,bdz_ph->m); + DEBUGP("Created hypergraph\n"); + + DEBUGP("m (edges): %u n (vertices): %u r: %u c: %f \n", bdz_ph->m, bdz_ph->n, bdz_ph->r, c); + + // Mapping step + iterations = 100; + if (mph->verbosity) + { + fprintf(stderr, "Entering mapping step for mph creation of %u keys with graph sized %u\n", bdz_ph->m, bdz_ph->n); + } + while(1) + { + int ok; + DEBUGP("linear hash function \n"); + bdz_ph->hl = hash_state_new(bdz_ph->hashfunc, 15); + + ok = bdz_ph_mapping(mph, &graph3, edges); + if (!ok) + { + --iterations; + hash_state_destroy(bdz_ph->hl); + bdz_ph->hl = NULL; + DEBUGP("%u iterations remaining\n", iterations); + if (mph->verbosity) + { + fprintf(stderr, "acyclic graph creation failure - %u iterations remaining\n", iterations); + } + if (iterations == 0) break; + } + else break; + } + + if (iterations == 0) + { +// free(bdz_ph->g); + bdz_ph_free_queue(&edges); + bdz_ph_free_graph3(&graph3); + return NULL; + } + bdz_ph_partial_free_graph3(&graph3); + // Assigning step + if (mph->verbosity) + { + fprintf(stderr, "Entering assigning step for mph creation of %u keys with graph sized %u\n", bdz_ph->m, bdz_ph->n); + } + assigning(bdz_ph, &graph3, edges); + + bdz_ph_free_queue(&edges); + bdz_ph_free_graph3(&graph3); + + if (mph->verbosity) + { + fprintf(stderr, "Starting optimization step\n"); + } + + bdz_ph_optimization(bdz_ph); + + #ifdef CMPH_TIMING + ELAPSED_TIME_IN_SECONDS(&construction_time); + #endif + mphf = (cmph_t *)malloc(sizeof(cmph_t)); + mphf->algo = mph->algo; + bdz_phf = (bdz_ph_data_t *)malloc(sizeof(bdz_ph_data_t)); + bdz_phf->g = bdz_ph->g; + bdz_ph->g = NULL; //transfer memory ownership + bdz_phf->hl = bdz_ph->hl; + bdz_ph->hl = NULL; //transfer memory ownership + bdz_phf->n = bdz_ph->n; + bdz_phf->m = bdz_ph->m; + bdz_phf->r = bdz_ph->r; + mphf->data = bdz_phf; + mphf->size = bdz_ph->n; + + DEBUGP("Successfully generated minimal perfect hash\n"); + if (mph->verbosity) + { + fprintf(stderr, "Successfully generated minimal perfect hash function\n"); + } + + #ifdef CMPH_TIMING + register cmph_uint32 space_usage = bdz_ph_packed_size(mphf)*8; + register cmph_uint32 keys_per_bucket = 1; + construction_time = construction_time - construction_time_begin; + fprintf(stdout, "%u\t%.2f\t%u\t%.4f\t%.4f\n", bdz_ph->m, bdz_ph->m/(double)bdz_ph->n, keys_per_bucket, construction_time, space_usage/(double)bdz_ph->m); + #endif + + return mphf; +} + + +static int bdz_ph_mapping(cmph_config_t *mph, bdz_ph_graph3_t* graph3, bdz_ph_queue_t queue) +{ + cmph_uint32 e; + int cycles = 0; + cmph_uint32 hl[3]; + + bdz_ph_config_data_t *bdz_ph = (bdz_ph_config_data_t *)mph->data; + bdz_ph_init_graph3(graph3, bdz_ph->m, bdz_ph->n); + mph->key_source->rewind(mph->key_source->data); + for (e = 0; e < mph->key_source->nkeys; ++e) + { + cmph_uint32 h0, h1, h2; + cmph_uint32 keylen; + char *key = NULL; + mph->key_source->read(mph->key_source->data, &key, &keylen); + hash_vector(bdz_ph->hl, key, keylen, hl); + h0 = hl[0] % bdz_ph->r; + h1 = hl[1] % bdz_ph->r + bdz_ph->r; + h2 = hl[2] % bdz_ph->r + (bdz_ph->r << 1); + mph->key_source->dispose(mph->key_source->data, key, keylen); + bdz_ph_add_edge(graph3,h0,h1,h2); + } + cycles = bdz_ph_generate_queue(bdz_ph->m, bdz_ph->n, queue, graph3); + return (cycles == 0); +} + +static void assigning(bdz_ph_config_data_t *bdz_ph, bdz_ph_graph3_t* graph3, bdz_ph_queue_t queue) +{ + cmph_uint32 i; + cmph_uint32 nedges=graph3->nedges; + cmph_uint32 curr_edge; + cmph_uint32 v0,v1,v2; + cmph_uint8 * marked_vertices =malloc((size_t)(bdz_ph->n >> 3) + 1); + cmph_uint32 sizeg = (cmph_uint32)ceil(bdz_ph->n/4.0); + bdz_ph->g = (cmph_uint8 *)calloc((size_t)sizeg, sizeof(cmph_uint8)); + memset(marked_vertices, 0, (size_t)(bdz_ph->n >> 3) + 1); + //memset(bdz_ph->g, 0xff, sizeg); + + for(i=nedges-1;i+1>=1;i--){ + curr_edge=queue[i]; + v0=graph3->edges[curr_edge].vertices[0]; + v1=graph3->edges[curr_edge].vertices[1]; + v2=graph3->edges[curr_edge].vertices[2]; + DEBUGP("B:%u %u %u -- %u %u %u\n", v0, v1, v2, GETVALUE(bdz_ph->g, v0), GETVALUE(bdz_ph->g, v1), GETVALUE(bdz_ph->g, v2)); + if(!GETBIT(marked_vertices, v0)){ + if(!GETBIT(marked_vertices,v1)) + { + //SETVALUE(bdz_ph->g, v1, UNASSIGNED); + SETBIT(marked_vertices, v1); + } + if(!GETBIT(marked_vertices,v2)) + { + //SETVALUE(bdz_ph->g, v2, UNASSIGNED); + SETBIT(marked_vertices, v2); + } + SETVALUE0(bdz_ph->g, v0, (6-(GETVALUE(bdz_ph->g, v1) + GETVALUE(bdz_ph->g,v2)))%3); + SETBIT(marked_vertices, v0); + } else if(!GETBIT(marked_vertices, v1)) { + if(!GETBIT(marked_vertices, v2)) + { + //SETVALUE(bdz_ph->g, v2, UNASSIGNED); + SETBIT(marked_vertices, v2); + } + SETVALUE0(bdz_ph->g, v1, (7 - (GETVALUE(bdz_ph->g, v0)+GETVALUE(bdz_ph->g, v2)))%3); + SETBIT(marked_vertices, v1); + }else { + SETVALUE0(bdz_ph->g, v2, (8-(GETVALUE(bdz_ph->g,v0)+GETVALUE(bdz_ph->g, v1)))%3); + SETBIT(marked_vertices, v2); + } + DEBUGP("A:%u %u %u -- %u %u %u\n", v0, v1, v2, GETVALUE(bdz_ph->g, v0), GETVALUE(bdz_ph->g, v1), GETVALUE(bdz_ph->g, v2)); + }; + free(marked_vertices); +} + +static void bdz_ph_optimization(bdz_ph_config_data_t *bdz_ph) +{ + cmph_uint32 i; + cmph_uint8 byte = 0; + cmph_uint32 sizeg = (cmph_uint32)ceil(bdz_ph->n/5.0); + cmph_uint8 * new_g = (cmph_uint8 *)calloc((size_t)sizeg, sizeof(cmph_uint8)); + cmph_uint8 value; + cmph_uint32 idx; + for(i = 0; i < bdz_ph->n; i++) + { + idx = i/5; + byte = new_g[idx]; + value = GETVALUE(bdz_ph->g, i); + byte = (cmph_uint8) (byte + value*pow3_table[i%5U]); + new_g[idx] = byte; + } + free(bdz_ph->g); + bdz_ph->g = new_g; +} + + +int bdz_ph_dump(cmph_t *mphf, FILE *fd) +{ + char *buf = NULL; + cmph_uint32 buflen; + cmph_uint32 sizeg = 0; + register size_t nbytes; + bdz_ph_data_t *data = (bdz_ph_data_t *)mphf->data; + __cmph_dump(mphf, fd); + + hash_state_dump(data->hl, &buf, &buflen); + DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); + nbytes = fwrite(&buflen, sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(buf, (size_t)buflen, (size_t)1, fd); + free(buf); + + nbytes = fwrite(&(data->n), sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(&(data->m), sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(&(data->r), sizeof(cmph_uint32), (size_t)1, fd); + sizeg = (cmph_uint32)ceil(data->n/5.0); + nbytes = fwrite(data->g, sizeof(cmph_uint8)*sizeg, (size_t)1, fd); + + #ifdef DEBUG + cmph_uint32 i; + fprintf(stderr, "G: "); + for (i = 0; i < data->n; ++i) fprintf(stderr, "%u ", GETVALUE(data->g, i)); + fprintf(stderr, "\n"); + #endif + return 1; +} + +void bdz_ph_load(FILE *f, cmph_t *mphf) +{ + char *buf = NULL; + cmph_uint32 buflen; + cmph_uint32 sizeg = 0; + register size_t nbytes; + bdz_ph_data_t *bdz_ph = (bdz_ph_data_t *)malloc(sizeof(bdz_ph_data_t)); + + DEBUGP("Loading bdz_ph mphf\n"); + mphf->data = bdz_ph; + + nbytes = fread(&buflen, sizeof(cmph_uint32), (size_t)1, f); + DEBUGP("Hash state has %u bytes\n", buflen); + buf = (char *)malloc((size_t)buflen); + nbytes = fread(buf, (size_t)buflen, (size_t)1, f); + bdz_ph->hl = hash_state_load(buf, buflen); + free(buf); + + + DEBUGP("Reading m and n\n"); + nbytes = fread(&(bdz_ph->n), sizeof(cmph_uint32), (size_t)1, f); + nbytes = fread(&(bdz_ph->m), sizeof(cmph_uint32), (size_t)1, f); + nbytes = fread(&(bdz_ph->r), sizeof(cmph_uint32), (size_t)1, f); + sizeg = (cmph_uint32)ceil(bdz_ph->n/5.0); + bdz_ph->g = (cmph_uint8 *)calloc((size_t)sizeg, sizeof(cmph_uint8)); + nbytes = fread(bdz_ph->g, sizeg*sizeof(cmph_uint8), (size_t)1, f); + + return; +} + + +cmph_uint32 bdz_ph_search(cmph_t *mphf, const char *key, cmph_uint32 keylen) +{ + register bdz_ph_data_t *bdz_ph = mphf->data; + cmph_uint32 hl[3]; + register cmph_uint8 byte0, byte1, byte2; + register cmph_uint32 vertex; + + hash_vector(bdz_ph->hl, key, keylen,hl); + hl[0] = hl[0] % bdz_ph->r; + hl[1] = hl[1] % bdz_ph->r + bdz_ph->r; + hl[2] = hl[2] % bdz_ph->r + (bdz_ph->r << 1); + + byte0 = bdz_ph->g[hl[0]/5]; + byte1 = bdz_ph->g[hl[1]/5]; + byte2 = bdz_ph->g[hl[2]/5]; + + byte0 = lookup_table[hl[0]%5U][byte0]; + byte1 = lookup_table[hl[1]%5U][byte1]; + byte2 = lookup_table[hl[2]%5U][byte2]; + vertex = hl[(byte0 + byte1 + byte2)%3]; + + return vertex; +} + + +void bdz_ph_destroy(cmph_t *mphf) +{ + bdz_ph_data_t *data = (bdz_ph_data_t *)mphf->data; + free(data->g); + hash_state_destroy(data->hl); + free(data); + free(mphf); +} + +/** \fn void bdz_ph_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void bdz_ph_pack(cmph_t *mphf, void *packed_mphf) +{ + bdz_ph_data_t *data = (bdz_ph_data_t *)mphf->data; + cmph_uint8 * ptr = packed_mphf; + + // packing hl type + CMPH_HASH hl_type = hash_get_type(data->hl); + *((cmph_uint32 *) ptr) = hl_type; + ptr += sizeof(cmph_uint32); + + // packing hl + hash_state_pack(data->hl, ptr); + ptr += hash_state_packed_size(hl_type); + + // packing r + *((cmph_uint32 *) ptr) = data->r; + ptr += sizeof(data->r); + + // packing g + cmph_uint32 sizeg = (cmph_uint32)ceil(data->n/5.0); + memcpy(ptr, data->g, sizeof(cmph_uint8)*sizeg); +} + +/** \fn cmph_uint32 bdz_ph_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 bdz_ph_packed_size(cmph_t *mphf) +{ + bdz_ph_data_t *data = (bdz_ph_data_t *)mphf->data; + CMPH_HASH hl_type = hash_get_type(data->hl); + cmph_uint32 sizeg = (cmph_uint32)ceil(data->n/5.0); + return (cmph_uint32) (sizeof(CMPH_ALGO) + hash_state_packed_size(hl_type) + 2*sizeof(cmph_uint32) + sizeof(cmph_uint8)*sizeg); +} + +/** cmph_uint32 bdz_ph_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint32 bdz_ph_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen) +{ + + register CMPH_HASH hl_type = *(cmph_uint32 *)packed_mphf; + register cmph_uint8 *hl_ptr = (cmph_uint8 *)(packed_mphf) + 4; + + register cmph_uint8 * ptr = hl_ptr + hash_state_packed_size(hl_type); + + register cmph_uint32 r = *((cmph_uint32*) ptr); + register cmph_uint8 * g = ptr + 4; + + cmph_uint32 hl[3]; + register cmph_uint8 byte0, byte1, byte2; + register cmph_uint32 vertex; + + hash_vector_packed(hl_ptr, hl_type, key, keylen, hl); + + hl[0] = hl[0] % r; + hl[1] = hl[1] % r + r; + hl[2] = hl[2] % r + (r << 1); + + byte0 = g[hl[0]/5]; + byte1 = g[hl[1]/5]; + byte2 = g[hl[2]/5]; + + byte0 = lookup_table[hl[0]%5][byte0]; + byte1 = lookup_table[hl[1]%5][byte1]; + byte2 = lookup_table[hl[2]%5][byte2]; + vertex = hl[(byte0 + byte1 + byte2)%3]; + + return vertex; +} diff --git a/cmph/bdz_ph.h b/cmph/bdz_ph.h new file mode 100755 index 000000000..73cce2ed1 --- /dev/null +++ b/cmph/bdz_ph.h @@ -0,0 +1,42 @@ +#ifndef __CMPH_BDZ_PH_H__ +#define __CMPH_BDZ_PH_H__ + +#include "cmph.h" + +typedef struct __bdz_ph_data_t bdz_ph_data_t; +typedef struct __bdz_ph_config_data_t bdz_ph_config_data_t; + +bdz_ph_config_data_t *bdz_ph_config_new(); +void bdz_ph_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); +void bdz_ph_config_destroy(cmph_config_t *mph); +cmph_t *bdz_ph_new(cmph_config_t *mph, double c); + +void bdz_ph_load(FILE *f, cmph_t *mphf); +int bdz_ph_dump(cmph_t *mphf, FILE *f); +void bdz_ph_destroy(cmph_t *mphf); +cmph_uint32 bdz_ph_search(cmph_t *mphf, const char *key, cmph_uint32 keylen); + +/** \fn void bdz_ph_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void bdz_ph_pack(cmph_t *mphf, void *packed_mphf); + +/** \fn cmph_uint32 bdz_ph_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 bdz_ph_packed_size(cmph_t *mphf); + +/** cmph_uint32 bdz_ph_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint32 bdz_ph_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen); + +#endif diff --git a/cmph/bdz_structs.h b/cmph/bdz_structs.h new file mode 100755 index 000000000..ba7dc3c66 --- /dev/null +++ b/cmph/bdz_structs.h @@ -0,0 +1,36 @@ +#ifndef __CMPH_BDZ_STRUCTS_H__ +#define __CMPH_BDZ_STRUCTS_H__ + +#include "hash_state.h" + +struct __bdz_data_t +{ + cmph_uint32 m; //edges (words) count + cmph_uint32 n; //vertex count + cmph_uint32 r; //partition vertex count + cmph_uint8 *g; + hash_state_t *hl; // linear hashing + + cmph_uint32 k; //kth index in ranktable, $k = log_2(n=3r)/\varepsilon$ + cmph_uint8 b; // number of bits of k + cmph_uint32 ranktablesize; //number of entries in ranktable, $n/k +1$ + cmph_uint32 *ranktable; // rank table +}; + + +struct __bdz_config_data_t +{ + cmph_uint32 m; //edges (words) count + cmph_uint32 n; //vertex count + cmph_uint32 r; //partition vertex count + cmph_uint8 *g; + hash_state_t *hl; // linear hashing + + cmph_uint32 k; //kth index in ranktable, $k = log_2(n=3r)/\varepsilon$ + cmph_uint8 b; // number of bits of k + cmph_uint32 ranktablesize; //number of entries in ranktable, $n/k +1$ + cmph_uint32 *ranktable; // rank table + CMPH_HASH hashfunc; +}; + +#endif diff --git a/cmph/bdz_structs_ph.h b/cmph/bdz_structs_ph.h new file mode 100755 index 000000000..5874a26df --- /dev/null +++ b/cmph/bdz_structs_ph.h @@ -0,0 +1,26 @@ +#ifndef __CMPH_BDZ_STRUCTS_PH_H__ +#define __CMPH_BDZ_STRUCTS_PH_H__ + +#include "hash_state.h" + +struct __bdz_ph_data_t +{ + cmph_uint32 m; //edges (words) count + cmph_uint32 n; //vertex count + cmph_uint32 r; //partition vertex count + cmph_uint8 *g; + hash_state_t *hl; // linear hashing +}; + + +struct __bdz_ph_config_data_t +{ + CMPH_HASH hashfunc; + cmph_uint32 m; //edges (words) count + cmph_uint32 n; //vertex count + cmph_uint32 r; //partition vertex count + cmph_uint8 *g; + hash_state_t *hl; // linear hashing +}; + +#endif diff --git a/cmph/bitbool.h b/cmph/bitbool.h new file mode 100644 index 000000000..a3286c3c9 --- /dev/null +++ b/cmph/bitbool.h @@ -0,0 +1,179 @@ +#ifndef _CMPH_BITBOOL_H__ +#define _CMPH_BITBOOL_H__ +#include "cmph_types.h" + +static const cmph_uint8 bitmask[] = { 1, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7 }; + +static const cmph_uint32 bitmask32[] = { 1, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7, + 1 << 8, 1 << 9, 1 << 10, 1 << 11, 1 << 12, 1 << 13, 1 << 14, 1 << 15, + 1 << 16, 1 << 17, 1 << 18, 1 << 19, 1 << 20, 1 << 21, 1 << 22, 1 << 23, + 1 << 24, 1 << 25, 1 << 26, 1 << 27, 1 << 28, 1 << 29, 1 << 30, 1U << 31 + }; + +static const cmph_uint8 valuemask[] = { 0xfc, 0xf3, 0xcf, 0x3f}; + + +/** \def GETBIT(array, i) + * \brief get the value of an 1-bit integer stored in an array. + * \param array to get 1-bit integer values from + * \param i is the index in array to get the 1-bit integer value from + * + * GETBIT(array, i) is a macro that gets the value of an 1-bit integer stored in array. + */ +#define GETBIT(array, i) ((array[i >> 3] & bitmask[i & 0x00000007]) >> (i & 0x00000007)) + +/** \def SETBIT(array, i) + * \brief set 1 to an 1-bit integer stored in an array. + * \param array to store 1-bit integer values + * \param i is the index in array to set the the bit to 1 + * + * SETBIT(array, i) is a macro that sets 1 to an 1-bit integer stored in an array. + */ +#define SETBIT(array, i) (array[i >> 3] |= bitmask[i & 0x00000007]) + +/** \def UNSETBIT(array, i) + * \brief set 0 to an 1-bit integer stored in an array. + * \param array to store 1-bit integer values + * \param i is the index in array to set the the bit to 0 + * + * UNSETBIT(array, i) is a macro that sets 0 to an 1-bit integer stored in an array. + */ +#define UNSETBIT(array, i) (array[i >> 3] ^= ((bitmask[i & 0x00000007]))) + +//#define GETBIT(array, i) (array[(i) / 8] & bitmask[(i) % 8]) +//#define SETBIT(array, i) (array[(i) / 8] |= bitmask[(i) % 8]) +//#define UNSETBIT(array, i) (array[(i) / 8] ^= ((bitmask[(i) % 8]))) + + +/** \def SETVALUE1(array, i, v) + * \brief set a value for a 2-bit integer stored in an array initialized with 1s. + * \param array to store 2-bit integer values + * \param i is the index in array to set the value v + * \param v is the value to be set + * + * SETVALUE1(array, i, v) is a macro that set a value for a 2-bit integer stored in an array. + * The array should be initialized with all bits set to 1. For example: + * memset(array, 0xff, arraySize); + */ +#define SETVALUE1(array, i, v) (array[i >> 2] &= (cmph_uint8)((v << ((i & 0x00000003) << 1)) | valuemask[i & 0x00000003])) + +/** \def SETVALUE0(array, i, v) + * \brief set a value for a 2-bit integer stored in an array initialized with 0s. + * \param array to store 2-bit integer values + * \param i is the index in array to set the value v + * \param v is the value to be set + * + * SETVALUE0(array, i, v) is a macro that set a value for a 2-bit integer stored in an array. + * The array should be initialized with all bits set to 0. For example: + * memset(array, 0, arraySize); + */ +#define SETVALUE0(array, i, v) (array[i >> 2] |= (cmph_uint8)(v << ((i & 0x00000003) << 1))) + + +/** \def GETVALUE(array, i) + * \brief get a value for a 2-bit integer stored in an array. + * \param array to get 2-bit integer values from + * \param i is the index in array to get the value from + * + * GETVALUE(array, i) is a macro that get a value for a 2-bit integer stored in an array. + */ +#define GETVALUE(array, i) ((cmph_uint8)((array[i >> 2] >> ((i & 0x00000003U) << 1U)) & 0x00000003U)) + + + +/** \def SETBIT32(array, i) + * \brief set 1 to an 1-bit integer stored in an array of 32-bit words. + * \param array to store 1-bit integer values. The entries are 32-bit words. + * \param i is the index in array to set the the bit to 1 + * + * SETBIT32(array, i) is a macro that sets 1 to an 1-bit integer stored in an array of 32-bit words. + */ +#define SETBIT32(array, i) (array[i >> 5] |= bitmask32[i & 0x0000001f]) + +/** \def GETBIT32(array, i) + * \brief get the value of an 1-bit integer stored in an array of 32-bit words. + * \param array to get 1-bit integer values from. The entries are 32-bit words. + * \param i is the index in array to get the 1-bit integer value from + * + * GETBIT32(array, i) is a macro that gets the value of an 1-bit integer stored in an array of 32-bit words. + */ +#define GETBIT32(array, i) (array[i >> 5] & bitmask32[i & 0x0000001f]) + +/** \def UNSETBIT32(array, i) + * \brief set 0 to an 1-bit integer stored in an array of 32-bit words. + * \param array to store 1-bit integer values. The entries ar 32-bit words + * \param i is the index in array to set the the bit to 0 + * + * UNSETBIT32(array, i) is a macro that sets 0 to an 1-bit integer stored in an array of 32-bit words. + */ +#define UNSETBIT32(array, i) (array[i >> 5] ^= ((bitmask32[i & 0x0000001f]))) + +#define BITS_TABLE_SIZE(n, bits_length) ((n * bits_length + 31) >> 5) + +static inline void set_bits_value(cmph_uint32 * bits_table, cmph_uint32 index, cmph_uint32 bits_string, + cmph_uint32 string_length, cmph_uint32 string_mask) +{ + register cmph_uint32 bit_idx = index * string_length; + register cmph_uint32 word_idx = bit_idx >> 5; + register cmph_uint32 shift1 = bit_idx & 0x0000001f; + register cmph_uint32 shift2 = 32 - shift1; + + bits_table[word_idx] &= ~((string_mask) << shift1); + bits_table[word_idx] |= bits_string << shift1; + + if(shift2 < string_length) + { + bits_table[word_idx+1] &= ~((string_mask) >> shift2); + bits_table[word_idx+1] |= bits_string >> shift2; + }; +}; + +static inline cmph_uint32 get_bits_value(cmph_uint32 * bits_table,cmph_uint32 index, cmph_uint32 string_length, cmph_uint32 string_mask) +{ + register cmph_uint32 bit_idx = index * string_length; + register cmph_uint32 word_idx = bit_idx >> 5; + register cmph_uint32 shift1 = bit_idx & 0x0000001f; + register cmph_uint32 shift2 = 32-shift1; + register cmph_uint32 bits_string; + + bits_string = (bits_table[word_idx] >> shift1) & string_mask; + + if(shift2 < string_length) + bits_string |= (bits_table[word_idx+1] << shift2) & string_mask; + + return bits_string; +}; + +static inline void set_bits_at_pos(cmph_uint32 * bits_table, cmph_uint32 pos, cmph_uint32 bits_string, cmph_uint32 string_length) +{ + register cmph_uint32 word_idx = pos >> 5; + register cmph_uint32 shift1 = pos & 0x0000001f; + register cmph_uint32 shift2 = 32-shift1; + register cmph_uint32 string_mask = (1U << string_length) - 1; + + bits_table[word_idx] &= ~((string_mask) << shift1); + bits_table[word_idx] |= bits_string << shift1; + if(shift2 < string_length) + { + bits_table[word_idx+1] &= ~((string_mask) >> shift2); + bits_table[word_idx+1] |= bits_string >> shift2; + } +}; + +static inline cmph_uint32 get_bits_at_pos(cmph_uint32 * bits_table,cmph_uint32 pos,cmph_uint32 string_length) +{ + register cmph_uint32 word_idx = pos >> 5; + register cmph_uint32 shift1 = pos & 0x0000001f; + register cmph_uint32 shift2 = 32 - shift1; + register cmph_uint32 string_mask = (1U << string_length) - 1; + register cmph_uint32 bits_string; + + bits_string = (bits_table[word_idx] >> shift1) & string_mask; + + if(shift2 < string_length) + bits_string |= (bits_table[word_idx+1] << shift2) & string_mask; + return bits_string; +} + + +#endif diff --git a/cmph/bmz.c b/cmph/bmz.c new file mode 100644 index 000000000..51798a189 --- /dev/null +++ b/cmph/bmz.c @@ -0,0 +1,620 @@ +#include "graph.h" +#include "bmz.h" +#include "cmph_structs.h" +#include "bmz_structs.h" +#include "hash.h" +#include "vqueue.h" +#include "bitbool.h" + +#include +#include +#include +#include +#include + +//#define DEBUG +#include "debug.h" + +static int bmz_gen_edges(cmph_config_t *mph); +static cmph_uint8 bmz_traverse_critical_nodes(bmz_config_data_t *bmz, cmph_uint32 v, cmph_uint32 * biggest_g_value, cmph_uint32 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited); +static cmph_uint8 bmz_traverse_critical_nodes_heuristic(bmz_config_data_t *bmz, cmph_uint32 v, cmph_uint32 * biggest_g_value, cmph_uint32 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited); +static void bmz_traverse_non_critical_nodes(bmz_config_data_t *bmz, cmph_uint8 * used_edges, cmph_uint8 * visited); + +bmz_config_data_t *bmz_config_new() +{ + bmz_config_data_t *bmz = NULL; + bmz = (bmz_config_data_t *)malloc(sizeof(bmz_config_data_t)); + assert(bmz); + memset(bmz, 0, sizeof(bmz_config_data_t)); + bmz->hashfuncs[0] = CMPH_HASH_JENKINS; + bmz->hashfuncs[1] = CMPH_HASH_JENKINS; + bmz->g = NULL; + bmz->graph = NULL; + bmz->hashes = NULL; + return bmz; +} + +void bmz_config_destroy(cmph_config_t *mph) +{ + bmz_config_data_t *data = (bmz_config_data_t *)mph->data; + DEBUGP("Destroying algorithm dependent data\n"); + free(data); +} + +void bmz_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs) +{ + bmz_config_data_t *bmz = (bmz_config_data_t *)mph->data; + CMPH_HASH *hashptr = hashfuncs; + cmph_uint32 i = 0; + while(*hashptr != CMPH_HASH_COUNT) + { + if (i >= 2) break; //bmz only uses two hash functions + bmz->hashfuncs[i] = *hashptr; + ++i, ++hashptr; + } +} + +cmph_t *bmz_new(cmph_config_t *mph, double c) +{ + cmph_t *mphf = NULL; + bmz_data_t *bmzf = NULL; + cmph_uint32 i; + cmph_uint32 iterations; + cmph_uint32 iterations_map = 20; + cmph_uint8 *used_edges = NULL; + cmph_uint8 restart_mapping = 0; + cmph_uint8 * visited = NULL; + + bmz_config_data_t *bmz = (bmz_config_data_t *)mph->data; + if (c == 0) c = 1.15; // validating restrictions over parameter c. + DEBUGP("c: %f\n", c); + bmz->m = mph->key_source->nkeys; + bmz->n = (cmph_uint32)ceil(c * mph->key_source->nkeys); + DEBUGP("m (edges): %u n (vertices): %u c: %f\n", bmz->m, bmz->n, c); + bmz->graph = graph_new(bmz->n, bmz->m); + DEBUGP("Created graph\n"); + + bmz->hashes = (hash_state_t **)malloc(sizeof(hash_state_t *)*3); + for(i = 0; i < 3; ++i) bmz->hashes[i] = NULL; + + do + { + // Mapping step + cmph_uint32 biggest_g_value = 0; + cmph_uint32 biggest_edge_value = 1; + iterations = 100; + if (mph->verbosity) + { + fprintf(stderr, "Entering mapping step for mph creation of %u keys with graph sized %u\n", bmz->m, bmz->n); + } + while(1) + { + int ok; + DEBUGP("hash function 1\n"); + bmz->hashes[0] = hash_state_new(bmz->hashfuncs[0], bmz->n); + DEBUGP("hash function 2\n"); + bmz->hashes[1] = hash_state_new(bmz->hashfuncs[1], bmz->n); + DEBUGP("Generating edges\n"); + ok = bmz_gen_edges(mph); + if (!ok) + { + --iterations; + hash_state_destroy(bmz->hashes[0]); + bmz->hashes[0] = NULL; + hash_state_destroy(bmz->hashes[1]); + bmz->hashes[1] = NULL; + DEBUGP("%u iterations remaining\n", iterations); + if (mph->verbosity) + { + fprintf(stderr, "simple graph creation failure - %u iterations remaining\n", iterations); + } + if (iterations == 0) break; + } + else break; + } + if (iterations == 0) + { + graph_destroy(bmz->graph); + return NULL; + } + // Ordering step + if (mph->verbosity) + { + fprintf(stderr, "Starting ordering step\n"); + } + graph_obtain_critical_nodes(bmz->graph); + + // Searching step + if (mph->verbosity) + { + fprintf(stderr, "Starting Searching step.\n"); + fprintf(stderr, "\tTraversing critical vertices.\n"); + } + DEBUGP("Searching step\n"); + visited = (cmph_uint8 *)malloc((size_t)bmz->n/8 + 1); + memset(visited, 0, (size_t)bmz->n/8 + 1); + used_edges = (cmph_uint8 *)malloc((size_t)bmz->m/8 + 1); + memset(used_edges, 0, (size_t)bmz->m/8 + 1); + free(bmz->g); + bmz->g = (cmph_uint32 *)calloc((size_t)bmz->n, sizeof(cmph_uint32)); + assert(bmz->g); + for (i = 0; i < bmz->n; ++i) // critical nodes + { + if (graph_node_is_critical(bmz->graph, i) && (!GETBIT(visited,i))) + { + if(c > 1.14) restart_mapping = bmz_traverse_critical_nodes(bmz, i, &biggest_g_value, &biggest_edge_value, used_edges, visited); + else restart_mapping = bmz_traverse_critical_nodes_heuristic(bmz, i, &biggest_g_value, &biggest_edge_value, used_edges, visited); + if(restart_mapping) break; + } + } + if(!restart_mapping) + { + if (mph->verbosity) + { + fprintf(stderr, "\tTraversing non critical vertices.\n"); + } + bmz_traverse_non_critical_nodes(bmz, used_edges, visited); // non_critical_nodes + } + else + { + iterations_map--; + if (mph->verbosity) fprintf(stderr, "Restarting mapping step. %u iterations remaining.\n", iterations_map); + } + free(used_edges); + free(visited); + }while(restart_mapping && iterations_map > 0); + graph_destroy(bmz->graph); + bmz->graph = NULL; + if (iterations_map == 0) + { + return NULL; + } + mphf = (cmph_t *)malloc(sizeof(cmph_t)); + mphf->algo = mph->algo; + bmzf = (bmz_data_t *)malloc(sizeof(bmz_data_t)); + bmzf->g = bmz->g; + bmz->g = NULL; //transfer memory ownership + bmzf->hashes = bmz->hashes; + bmz->hashes = NULL; //transfer memory ownership + bmzf->n = bmz->n; + bmzf->m = bmz->m; + mphf->data = bmzf; + mphf->size = bmz->m; + + DEBUGP("Successfully generated minimal perfect hash\n"); + if (mph->verbosity) + { + fprintf(stderr, "Successfully generated minimal perfect hash function\n"); + } + return mphf; +} + +static cmph_uint8 bmz_traverse_critical_nodes(bmz_config_data_t *bmz, cmph_uint32 v, cmph_uint32 * biggest_g_value, cmph_uint32 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited) +{ + cmph_uint32 next_g; + cmph_uint32 u; /* Auxiliary vertex */ + cmph_uint32 lav; /* lookahead vertex */ + cmph_uint8 collision; + vqueue_t * q = vqueue_new((cmph_uint32)(graph_ncritical_nodes(bmz->graph)) + 1); + graph_iterator_t it, it1; + + DEBUGP("Labelling critical vertices\n"); + bmz->g[v] = (cmph_uint32)ceil ((double)(*biggest_edge_value)/2) - 1; + SETBIT(visited, v); + next_g = (cmph_uint32)floor((double)(*biggest_edge_value/2)); /* next_g is incremented in the do..while statement*/ + vqueue_insert(q, v); + while(!vqueue_is_empty(q)) + { + v = vqueue_remove(q); + it = graph_neighbors_it(bmz->graph, v); + while ((u = graph_next_neighbor(bmz->graph, &it)) != GRAPH_NO_NEIGHBOR) + { + if (graph_node_is_critical(bmz->graph, u) && (!GETBIT(visited,u))) + { + collision = 1; + while(collision) // lookahead to resolve collisions + { + next_g = *biggest_g_value + 1; + it1 = graph_neighbors_it(bmz->graph, u); + collision = 0; + while((lav = graph_next_neighbor(bmz->graph, &it1)) != GRAPH_NO_NEIGHBOR) + { + if (graph_node_is_critical(bmz->graph, lav) && GETBIT(visited,lav)) + { + if(next_g + bmz->g[lav] >= bmz->m) + { + vqueue_destroy(q); + return 1; // restart mapping step. + } + if (GETBIT(used_edges, (next_g + bmz->g[lav]))) + { + collision = 1; + break; + } + } + } + if (next_g > *biggest_g_value) *biggest_g_value = next_g; + } + // Marking used edges... + it1 = graph_neighbors_it(bmz->graph, u); + while((lav = graph_next_neighbor(bmz->graph, &it1)) != GRAPH_NO_NEIGHBOR) + { + if (graph_node_is_critical(bmz->graph, lav) && GETBIT(visited, lav)) + { + SETBIT(used_edges,(next_g + bmz->g[lav])); + if(next_g + bmz->g[lav] > *biggest_edge_value) *biggest_edge_value = next_g + bmz->g[lav]; + } + } + bmz->g[u] = next_g; // Labelling vertex u. + SETBIT(visited,u); + vqueue_insert(q, u); + } + } + + } + vqueue_destroy(q); + return 0; +} + +static cmph_uint8 bmz_traverse_critical_nodes_heuristic(bmz_config_data_t *bmz, cmph_uint32 v, cmph_uint32 * biggest_g_value, cmph_uint32 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited) +{ + cmph_uint32 next_g; + cmph_uint32 u; /* Auxiliary vertex */ + cmph_uint32 lav; /* lookahead vertex */ + cmph_uint8 collision; + cmph_uint32 * unused_g_values = NULL; + cmph_uint32 unused_g_values_capacity = 0; + cmph_uint32 nunused_g_values = 0; + vqueue_t * q = vqueue_new((cmph_uint32)(0.5*graph_ncritical_nodes(bmz->graph))+1); + graph_iterator_t it, it1; + + DEBUGP("Labelling critical vertices\n"); + bmz->g[v] = (cmph_uint32)ceil ((double)(*biggest_edge_value)/2) - 1; + SETBIT(visited, v); + next_g = (cmph_uint32)floor((double)(*biggest_edge_value/2)); /* next_g is incremented in the do..while statement*/ + vqueue_insert(q, v); + while(!vqueue_is_empty(q)) + { + v = vqueue_remove(q); + it = graph_neighbors_it(bmz->graph, v); + while ((u = graph_next_neighbor(bmz->graph, &it)) != GRAPH_NO_NEIGHBOR) + { + if (graph_node_is_critical(bmz->graph, u) && (!GETBIT(visited,u))) + { + cmph_uint32 next_g_index = 0; + collision = 1; + while(collision) // lookahead to resolve collisions + { + if (next_g_index < nunused_g_values) + { + next_g = unused_g_values[next_g_index++]; + } + else + { + next_g = *biggest_g_value + 1; + next_g_index = UINT_MAX; + } + it1 = graph_neighbors_it(bmz->graph, u); + collision = 0; + while((lav = graph_next_neighbor(bmz->graph, &it1)) != GRAPH_NO_NEIGHBOR) + { + if (graph_node_is_critical(bmz->graph, lav) && GETBIT(visited,lav)) + { + if(next_g + bmz->g[lav] >= bmz->m) + { + vqueue_destroy(q); + free(unused_g_values); + return 1; // restart mapping step. + } + if (GETBIT(used_edges, (next_g + bmz->g[lav]))) + { + collision = 1; + break; + } + } + } + if(collision && (next_g > *biggest_g_value)) // saving the current g value stored in next_g. + { + if(nunused_g_values == unused_g_values_capacity) + { + unused_g_values = (cmph_uint32 *)realloc(unused_g_values, (unused_g_values_capacity + BUFSIZ)*sizeof(cmph_uint32)); + unused_g_values_capacity += BUFSIZ; + } + unused_g_values[nunused_g_values++] = next_g; + + } + if (next_g > *biggest_g_value) *biggest_g_value = next_g; + } + next_g_index--; + if (next_g_index < nunused_g_values) unused_g_values[next_g_index] = unused_g_values[--nunused_g_values]; + + // Marking used edges... + it1 = graph_neighbors_it(bmz->graph, u); + while((lav = graph_next_neighbor(bmz->graph, &it1)) != GRAPH_NO_NEIGHBOR) + { + if (graph_node_is_critical(bmz->graph, lav) && GETBIT(visited, lav)) + { + SETBIT(used_edges,(next_g + bmz->g[lav])); + if(next_g + bmz->g[lav] > *biggest_edge_value) *biggest_edge_value = next_g + bmz->g[lav]; + } + } + bmz->g[u] = next_g; // Labelling vertex u. + SETBIT(visited, u); + vqueue_insert(q, u); + } + } + + } + vqueue_destroy(q); + free(unused_g_values); + return 0; +} + +static cmph_uint32 next_unused_edge(bmz_config_data_t *bmz, cmph_uint8 * used_edges, cmph_uint32 unused_edge_index) +{ + while(1) + { + assert(unused_edge_index < bmz->m); + if(GETBIT(used_edges, unused_edge_index)) unused_edge_index ++; + else break; + } + return unused_edge_index; +} + +static void bmz_traverse(bmz_config_data_t *bmz, cmph_uint8 * used_edges, cmph_uint32 v, cmph_uint32 * unused_edge_index, cmph_uint8 * visited) +{ + graph_iterator_t it = graph_neighbors_it(bmz->graph, v); + cmph_uint32 neighbor = 0; + while((neighbor = graph_next_neighbor(bmz->graph, &it)) != GRAPH_NO_NEIGHBOR) + { + if(GETBIT(visited,neighbor)) continue; + //DEBUGP("Visiting neighbor %u\n", neighbor); + *unused_edge_index = next_unused_edge(bmz, used_edges, *unused_edge_index); + bmz->g[neighbor] = *unused_edge_index - bmz->g[v]; + //if (bmz->g[neighbor] >= bmz->m) bmz->g[neighbor] += bmz->m; + SETBIT(visited, neighbor); + (*unused_edge_index)++; + bmz_traverse(bmz, used_edges, neighbor, unused_edge_index, visited); + + } +} + +static void bmz_traverse_non_critical_nodes(bmz_config_data_t *bmz, cmph_uint8 * used_edges, cmph_uint8 * visited) +{ + + cmph_uint32 i, v1, v2, unused_edge_index = 0; + DEBUGP("Labelling non critical vertices\n"); + for(i = 0; i < bmz->m; i++) + { + v1 = graph_vertex_id(bmz->graph, i, 0); + v2 = graph_vertex_id(bmz->graph, i, 1); + if((GETBIT(visited,v1) && GETBIT(visited,v2)) || (!GETBIT(visited,v1) && !GETBIT(visited,v2))) continue; + if(GETBIT(visited,v1)) bmz_traverse(bmz, used_edges, v1, &unused_edge_index, visited); + else bmz_traverse(bmz, used_edges, v2, &unused_edge_index, visited); + + } + + for(i = 0; i < bmz->n; i++) + { + if(!GETBIT(visited,i)) + { + bmz->g[i] = 0; + SETBIT(visited, i); + bmz_traverse(bmz, used_edges, i, &unused_edge_index, visited); + } + } + +} + +static int bmz_gen_edges(cmph_config_t *mph) +{ + cmph_uint32 e; + bmz_config_data_t *bmz = (bmz_config_data_t *)mph->data; + cmph_uint8 multiple_edges = 0; + DEBUGP("Generating edges for %u vertices\n", bmz->n); + graph_clear_edges(bmz->graph); + mph->key_source->rewind(mph->key_source->data); + for (e = 0; e < mph->key_source->nkeys; ++e) + { + cmph_uint32 h1, h2; + cmph_uint32 keylen; + char *key = NULL; + mph->key_source->read(mph->key_source->data, &key, &keylen); + +// if (key == NULL)fprintf(stderr, "key = %s -- read BMZ\n", key); + h1 = hash(bmz->hashes[0], key, keylen) % bmz->n; + h2 = hash(bmz->hashes[1], key, keylen) % bmz->n; + if (h1 == h2) if (++h2 >= bmz->n) h2 = 0; + if (h1 == h2) + { + if (mph->verbosity) fprintf(stderr, "Self loop for key %u\n", e); + mph->key_source->dispose(mph->key_source->data, key, keylen); + return 0; + } + //DEBUGP("Adding edge: %u -> %u for key %s\n", h1, h2, key); + mph->key_source->dispose(mph->key_source->data, key, keylen); +// fprintf(stderr, "key = %s -- dispose BMZ\n", key); + multiple_edges = graph_contains_edge(bmz->graph, h1, h2); + if (mph->verbosity && multiple_edges) fprintf(stderr, "A non simple graph was generated\n"); + if (multiple_edges) return 0; // checking multiple edge restriction. + graph_add_edge(bmz->graph, h1, h2); + } + return !multiple_edges; +} + +int bmz_dump(cmph_t *mphf, FILE *fd) +{ + char *buf = NULL; + cmph_uint32 buflen; + cmph_uint32 two = 2; //number of hash functions + bmz_data_t *data = (bmz_data_t *)mphf->data; + register size_t nbytes; + __cmph_dump(mphf, fd); + + nbytes = fwrite(&two, sizeof(cmph_uint32), (size_t)1, fd); + + hash_state_dump(data->hashes[0], &buf, &buflen); + DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); + nbytes = fwrite(&buflen, sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(buf, (size_t)buflen, (size_t)1, fd); + free(buf); + + hash_state_dump(data->hashes[1], &buf, &buflen); + DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); + nbytes = fwrite(&buflen, sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(buf, (size_t)buflen, (size_t)1, fd); + free(buf); + + nbytes = fwrite(&(data->n), sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(&(data->m), sizeof(cmph_uint32), (size_t)1, fd); + + nbytes = fwrite(data->g, sizeof(cmph_uint32)*(data->n), (size_t)1, fd); + #ifdef DEBUG + cmph_uint32 i; + fprintf(stderr, "G: "); + for (i = 0; i < data->n; ++i) fprintf(stderr, "%u ", data->g[i]); + fprintf(stderr, "\n"); + #endif + return 1; +} + +void bmz_load(FILE *f, cmph_t *mphf) +{ + cmph_uint32 nhashes; + char *buf = NULL; + cmph_uint32 buflen; + cmph_uint32 i; + bmz_data_t *bmz = (bmz_data_t *)malloc(sizeof(bmz_data_t)); + register size_t nbytes; + DEBUGP("Loading bmz mphf\n"); + mphf->data = bmz; + nbytes = fread(&nhashes, sizeof(cmph_uint32), (size_t)1, f); + bmz->hashes = (hash_state_t **)malloc(sizeof(hash_state_t *)*(nhashes + 1)); + bmz->hashes[nhashes] = NULL; + DEBUGP("Reading %u hashes\n", nhashes); + for (i = 0; i < nhashes; ++i) + { + hash_state_t *state = NULL; + nbytes = fread(&buflen, sizeof(cmph_uint32), (size_t)1, f); + DEBUGP("Hash state has %u bytes\n", buflen); + buf = (char *)malloc((size_t)buflen); + nbytes = fread(buf, (size_t)buflen, (size_t)1, f); + state = hash_state_load(buf, buflen); + bmz->hashes[i] = state; + free(buf); + } + + DEBUGP("Reading m and n\n"); + nbytes = fread(&(bmz->n), sizeof(cmph_uint32), (size_t)1, f); + nbytes = fread(&(bmz->m), sizeof(cmph_uint32), (size_t)1, f); + + bmz->g = (cmph_uint32 *)malloc(sizeof(cmph_uint32)*bmz->n); + nbytes = fread(bmz->g, bmz->n*sizeof(cmph_uint32), (size_t)1, f); + #ifdef DEBUG + fprintf(stderr, "G: "); + for (i = 0; i < bmz->n; ++i) fprintf(stderr, "%u ", bmz->g[i]); + fprintf(stderr, "\n"); + #endif + return; +} + + +cmph_uint32 bmz_search(cmph_t *mphf, const char *key, cmph_uint32 keylen) +{ + bmz_data_t *bmz = mphf->data; + cmph_uint32 h1 = hash(bmz->hashes[0], key, keylen) % bmz->n; + cmph_uint32 h2 = hash(bmz->hashes[1], key, keylen) % bmz->n; + DEBUGP("key: %s h1: %u h2: %u\n", key, h1, h2); + if (h1 == h2 && ++h2 > bmz->n) h2 = 0; + DEBUGP("key: %s g[h1]: %u g[h2]: %u edges: %u\n", key, bmz->g[h1], bmz->g[h2], bmz->m); + return bmz->g[h1] + bmz->g[h2]; +} +void bmz_destroy(cmph_t *mphf) +{ + bmz_data_t *data = (bmz_data_t *)mphf->data; + free(data->g); + hash_state_destroy(data->hashes[0]); + hash_state_destroy(data->hashes[1]); + free(data->hashes); + free(data); + free(mphf); +} + +/** \fn void bmz_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void bmz_pack(cmph_t *mphf, void *packed_mphf) +{ + + bmz_data_t *data = (bmz_data_t *)mphf->data; + cmph_uint8 * ptr = packed_mphf; + + // packing h1 type + CMPH_HASH h1_type = hash_get_type(data->hashes[0]); + *((cmph_uint32 *) ptr) = h1_type; + ptr += sizeof(cmph_uint32); + + // packing h1 + hash_state_pack(data->hashes[0], ptr); + ptr += hash_state_packed_size(h1_type); + + // packing h2 type + CMPH_HASH h2_type = hash_get_type(data->hashes[1]); + *((cmph_uint32 *) ptr) = h2_type; + ptr += sizeof(cmph_uint32); + + // packing h2 + hash_state_pack(data->hashes[1], ptr); + ptr += hash_state_packed_size(h2_type); + + // packing n + *((cmph_uint32 *) ptr) = data->n; + ptr += sizeof(data->n); + + // packing g + memcpy(ptr, data->g, sizeof(cmph_uint32)*data->n); +} + +/** \fn cmph_uint32 bmz_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 bmz_packed_size(cmph_t *mphf) +{ + bmz_data_t *data = (bmz_data_t *)mphf->data; + CMPH_HASH h1_type = hash_get_type(data->hashes[0]); + CMPH_HASH h2_type = hash_get_type(data->hashes[1]); + + return (cmph_uint32)(sizeof(CMPH_ALGO) + hash_state_packed_size(h1_type) + hash_state_packed_size(h2_type) + + 3*sizeof(cmph_uint32) + sizeof(cmph_uint32)*data->n); +} + +/** cmph_uint32 bmz_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint32 bmz_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen) +{ + register cmph_uint8 *h1_ptr = packed_mphf; + register CMPH_HASH h1_type = *((cmph_uint32 *)h1_ptr); + h1_ptr += 4; + + register cmph_uint8 *h2_ptr = h1_ptr + hash_state_packed_size(h1_type); + register CMPH_HASH h2_type = *((cmph_uint32 *)h2_ptr); + h2_ptr += 4; + + register cmph_uint32 *g_ptr = (cmph_uint32 *)(h2_ptr + hash_state_packed_size(h2_type)); + + register cmph_uint32 n = *g_ptr++; + + register cmph_uint32 h1 = hash_packed(h1_ptr, h1_type, key, keylen) % n; + register cmph_uint32 h2 = hash_packed(h2_ptr, h2_type, key, keylen) % n; + if (h1 == h2 && ++h2 > n) h2 = 0; + return (g_ptr[h1] + g_ptr[h2]); +} diff --git a/cmph/bmz.h b/cmph/bmz.h new file mode 100644 index 000000000..ee5f61dda --- /dev/null +++ b/cmph/bmz.h @@ -0,0 +1,42 @@ +#ifndef __CMPH_BMZ_H__ +#define __CMPH_BMZ_H__ + +#include "cmph.h" + +typedef struct __bmz_data_t bmz_data_t; +typedef struct __bmz_config_data_t bmz_config_data_t; + +bmz_config_data_t *bmz_config_new(); +void bmz_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); +void bmz_config_destroy(cmph_config_t *mph); +cmph_t *bmz_new(cmph_config_t *mph, double c); + +void bmz_load(FILE *f, cmph_t *mphf); +int bmz_dump(cmph_t *mphf, FILE *f); +void bmz_destroy(cmph_t *mphf); +cmph_uint32 bmz_search(cmph_t *mphf, const char *key, cmph_uint32 keylen); + +/** \fn void bmz_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void bmz_pack(cmph_t *mphf, void *packed_mphf); + +/** \fn cmph_uint32 bmz_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 bmz_packed_size(cmph_t *mphf); + +/** cmph_uint32 bmz_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint32 bmz_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen); + +#endif diff --git a/cmph/bmz8.c b/cmph/bmz8.c new file mode 100644 index 000000000..203f4fc19 --- /dev/null +++ b/cmph/bmz8.c @@ -0,0 +1,632 @@ +#include "graph.h" +#include "bmz8.h" +#include "cmph_structs.h" +#include "bmz8_structs.h" +#include "hash.h" +#include "vqueue.h" +#include "bitbool.h" +#include +#include +#include +#include +#include + +//#define DEBUG +#include "debug.h" + +static int bmz8_gen_edges(cmph_config_t *mph); +static cmph_uint8 bmz8_traverse_critical_nodes(bmz8_config_data_t *bmz8, cmph_uint32 v, cmph_uint8 * biggest_g_value, cmph_uint8 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited); +static cmph_uint8 bmz8_traverse_critical_nodes_heuristic(bmz8_config_data_t *bmz8, cmph_uint32 v, cmph_uint8 * biggest_g_value, cmph_uint8 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited); +static void bmz8_traverse_non_critical_nodes(bmz8_config_data_t *bmz8, cmph_uint8 * used_edges, cmph_uint8 * visited); + +bmz8_config_data_t *bmz8_config_new() +{ + bmz8_config_data_t *bmz8; + bmz8 = (bmz8_config_data_t *)malloc(sizeof(bmz8_config_data_t)); + assert(bmz8); + memset(bmz8, 0, sizeof(bmz8_config_data_t)); + bmz8->hashfuncs[0] = CMPH_HASH_JENKINS; + bmz8->hashfuncs[1] = CMPH_HASH_JENKINS; + bmz8->g = NULL; + bmz8->graph = NULL; + bmz8->hashes = NULL; + return bmz8; +} + +void bmz8_config_destroy(cmph_config_t *mph) +{ + bmz8_config_data_t *data = (bmz8_config_data_t *)mph->data; + DEBUGP("Destroying algorithm dependent data\n"); + free(data); +} + +void bmz8_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs) +{ + bmz8_config_data_t *bmz8 = (bmz8_config_data_t *)mph->data; + CMPH_HASH *hashptr = hashfuncs; + cmph_uint8 i = 0; + while(*hashptr != CMPH_HASH_COUNT) + { + if (i >= 2) break; //bmz8 only uses two hash functions + bmz8->hashfuncs[i] = *hashptr; + ++i, ++hashptr; + } +} + +cmph_t *bmz8_new(cmph_config_t *mph, double c) +{ + cmph_t *mphf = NULL; + bmz8_data_t *bmz8f = NULL; + cmph_uint8 i; + cmph_uint8 iterations; + cmph_uint8 iterations_map = 20; + cmph_uint8 *used_edges = NULL; + cmph_uint8 restart_mapping = 0; + cmph_uint8 * visited = NULL; + bmz8_config_data_t *bmz8 = (bmz8_config_data_t *)mph->data; + + if (mph->key_source->nkeys >= 256) + { + if (mph->verbosity) fprintf(stderr, "The number of keys in BMZ8 must be lower than 256.\n"); + return NULL; + } + if (c == 0) c = 1.15; // validating restrictions over parameter c. + DEBUGP("c: %f\n", c); + bmz8->m = (cmph_uint8) mph->key_source->nkeys; + bmz8->n = (cmph_uint8) ceil(c * mph->key_source->nkeys); + DEBUGP("m (edges): %u n (vertices): %u c: %f\n", bmz8->m, bmz8->n, c); + bmz8->graph = graph_new(bmz8->n, bmz8->m); + DEBUGP("Created graph\n"); + + bmz8->hashes = (hash_state_t **)malloc(sizeof(hash_state_t *)*3); + for(i = 0; i < 3; ++i) bmz8->hashes[i] = NULL; + + do + { + // Mapping step + cmph_uint8 biggest_g_value = 0; + cmph_uint8 biggest_edge_value = 1; + iterations = 100; + if (mph->verbosity) + { + fprintf(stderr, "Entering mapping step for mph creation of %u keys with graph sized %u\n", bmz8->m, bmz8->n); + } + while(1) + { + int ok; + DEBUGP("hash function 1\n"); + bmz8->hashes[0] = hash_state_new(bmz8->hashfuncs[0], bmz8->n); + DEBUGP("hash function 2\n"); + bmz8->hashes[1] = hash_state_new(bmz8->hashfuncs[1], bmz8->n); + DEBUGP("Generating edges\n"); + ok = bmz8_gen_edges(mph); + if (!ok) + { + --iterations; + hash_state_destroy(bmz8->hashes[0]); + bmz8->hashes[0] = NULL; + hash_state_destroy(bmz8->hashes[1]); + bmz8->hashes[1] = NULL; + DEBUGP("%u iterations remaining\n", iterations); + if (mph->verbosity) + { + fprintf(stderr, "simple graph creation failure - %u iterations remaining\n", iterations); + } + if (iterations == 0) break; + } + else break; + } + if (iterations == 0) + { + graph_destroy(bmz8->graph); + return NULL; + } + + // Ordering step + if (mph->verbosity) + { + fprintf(stderr, "Starting ordering step\n"); + } + + graph_obtain_critical_nodes(bmz8->graph); + + // Searching step + if (mph->verbosity) + { + fprintf(stderr, "Starting Searching step.\n"); + fprintf(stderr, "\tTraversing critical vertices.\n"); + } + DEBUGP("Searching step\n"); + visited = (cmph_uint8 *)malloc((size_t)bmz8->n/8 + 1); + memset(visited, 0, (size_t)bmz8->n/8 + 1); + used_edges = (cmph_uint8 *)malloc((size_t)bmz8->m/8 + 1); + memset(used_edges, 0, (size_t)bmz8->m/8 + 1); + free(bmz8->g); + bmz8->g = (cmph_uint8 *)calloc((size_t)bmz8->n, sizeof(cmph_uint8)); + assert(bmz8->g); + for (i = 0; i < bmz8->n; ++i) // critical nodes + { + if (graph_node_is_critical(bmz8->graph, i) && (!GETBIT(visited,i))) + { + if(c > 1.14) restart_mapping = bmz8_traverse_critical_nodes(bmz8, i, &biggest_g_value, &biggest_edge_value, used_edges, visited); + else restart_mapping = bmz8_traverse_critical_nodes_heuristic(bmz8, i, &biggest_g_value, &biggest_edge_value, used_edges, visited); + if(restart_mapping) break; + } + } + if(!restart_mapping) + { + if (mph->verbosity) + { + fprintf(stderr, "\tTraversing non critical vertices.\n"); + } + bmz8_traverse_non_critical_nodes(bmz8, used_edges, visited); // non_critical_nodes + } + else + { + iterations_map--; + if (mph->verbosity) fprintf(stderr, "Restarting mapping step. %u iterations remaining.\n", iterations_map); + } + + free(used_edges); + free(visited); + + }while(restart_mapping && iterations_map > 0); + graph_destroy(bmz8->graph); + bmz8->graph = NULL; + if (iterations_map == 0) + { + return NULL; + } + mphf = (cmph_t *)malloc(sizeof(cmph_t)); + mphf->algo = mph->algo; + bmz8f = (bmz8_data_t *)malloc(sizeof(bmz8_data_t)); + bmz8f->g = bmz8->g; + bmz8->g = NULL; //transfer memory ownership + bmz8f->hashes = bmz8->hashes; + bmz8->hashes = NULL; //transfer memory ownership + bmz8f->n = bmz8->n; + bmz8f->m = bmz8->m; + mphf->data = bmz8f; + mphf->size = bmz8->m; + DEBUGP("Successfully generated minimal perfect hash\n"); + if (mph->verbosity) + { + fprintf(stderr, "Successfully generated minimal perfect hash function\n"); + } + return mphf; +} + +static cmph_uint8 bmz8_traverse_critical_nodes(bmz8_config_data_t *bmz8, cmph_uint32 v, cmph_uint8 * biggest_g_value, cmph_uint8 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited) +{ + cmph_uint8 next_g; + cmph_uint32 u; /* Auxiliary vertex */ + cmph_uint32 lav; /* lookahead vertex */ + cmph_uint8 collision; + vqueue_t * q = vqueue_new((cmph_uint32)(graph_ncritical_nodes(bmz8->graph))); + graph_iterator_t it, it1; + + DEBUGP("Labelling critical vertices\n"); + bmz8->g[v] = (cmph_uint8)(ceil ((double)(*biggest_edge_value)/2) - 1); + SETBIT(visited, v); + next_g = (cmph_uint8)floor((double)(*biggest_edge_value/2)); /* next_g is incremented in the do..while statement*/ + vqueue_insert(q, v); + while(!vqueue_is_empty(q)) + { + v = vqueue_remove(q); + it = graph_neighbors_it(bmz8->graph, v); + while ((u = graph_next_neighbor(bmz8->graph, &it)) != GRAPH_NO_NEIGHBOR) + { + if (graph_node_is_critical(bmz8->graph, u) && (!GETBIT(visited,u))) + { + collision = 1; + while(collision) // lookahead to resolve collisions + { + next_g = (cmph_uint8)(*biggest_g_value + 1); + it1 = graph_neighbors_it(bmz8->graph, u); + collision = 0; + while((lav = graph_next_neighbor(bmz8->graph, &it1)) != GRAPH_NO_NEIGHBOR) + { + if (graph_node_is_critical(bmz8->graph, lav) && GETBIT(visited,lav)) + { + if(next_g + bmz8->g[lav] >= bmz8->m) + { + vqueue_destroy(q); + return 1; // restart mapping step. + } + if (GETBIT(used_edges, (next_g + bmz8->g[lav]))) + { + collision = 1; + break; + } + } + } + if (next_g > *biggest_g_value) *biggest_g_value = next_g; + } + // Marking used edges... + it1 = graph_neighbors_it(bmz8->graph, u); + while((lav = graph_next_neighbor(bmz8->graph, &it1)) != GRAPH_NO_NEIGHBOR) + { + if (graph_node_is_critical(bmz8->graph, lav) && GETBIT(visited, lav)) + { + SETBIT(used_edges,(next_g + bmz8->g[lav])); + + if(next_g + bmz8->g[lav] > *biggest_edge_value) + *biggest_edge_value = (cmph_uint8)(next_g + bmz8->g[lav]); + } + } + bmz8->g[u] = next_g; // Labelling vertex u. + SETBIT(visited,u); + vqueue_insert(q, u); + } + } + + } + vqueue_destroy(q); + return 0; +} + +static cmph_uint8 bmz8_traverse_critical_nodes_heuristic(bmz8_config_data_t *bmz8, cmph_uint32 v, cmph_uint8 * biggest_g_value, cmph_uint8 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited) +{ + cmph_uint8 next_g; + cmph_uint32 u; + cmph_uint32 lav; + cmph_uint8 collision; + cmph_uint8 * unused_g_values = NULL; + cmph_uint8 unused_g_values_capacity = 0; + cmph_uint8 nunused_g_values = 0; + vqueue_t * q = vqueue_new((cmph_uint32)(graph_ncritical_nodes(bmz8->graph))); + graph_iterator_t it, it1; + + DEBUGP("Labelling critical vertices\n"); + bmz8->g[v] = (cmph_uint8)(ceil ((double)(*biggest_edge_value)/2) - 1); + SETBIT(visited, v); + next_g = (cmph_uint8)floor((double)(*biggest_edge_value/2)); + vqueue_insert(q, v); + while(!vqueue_is_empty(q)) + { + v = vqueue_remove(q); + it = graph_neighbors_it(bmz8->graph, v); + while ((u = graph_next_neighbor(bmz8->graph, &it)) != GRAPH_NO_NEIGHBOR) + { + if (graph_node_is_critical(bmz8->graph, u) && (!GETBIT(visited,u))) + { + cmph_uint8 next_g_index = 0; + collision = 1; + while(collision) // lookahead to resolve collisions + { + if (next_g_index < nunused_g_values) + { + next_g = unused_g_values[next_g_index++]; + } + else + { + next_g = (cmph_uint8)(*biggest_g_value + 1); + next_g_index = 255;//UINT_MAX; + } + it1 = graph_neighbors_it(bmz8->graph, u); + collision = 0; + while((lav = graph_next_neighbor(bmz8->graph, &it1)) != GRAPH_NO_NEIGHBOR) + { + if (graph_node_is_critical(bmz8->graph, lav) && GETBIT(visited,lav)) + { + if(next_g + bmz8->g[lav] >= bmz8->m) + { + vqueue_destroy(q); + free(unused_g_values); + return 1; // restart mapping step. + } + if (GETBIT(used_edges, (next_g + bmz8->g[lav]))) + { + collision = 1; + break; + } + } + } + if(collision && (next_g > *biggest_g_value)) // saving the current g value stored in next_g. + { + if(nunused_g_values == unused_g_values_capacity) + { + unused_g_values = (cmph_uint8*)realloc(unused_g_values, ((size_t)(unused_g_values_capacity + BUFSIZ))*sizeof(cmph_uint8)); + unused_g_values_capacity += (cmph_uint8)BUFSIZ; + } + unused_g_values[nunused_g_values++] = next_g; + + } + if (next_g > *biggest_g_value) *biggest_g_value = next_g; + } + + next_g_index--; + if (next_g_index < nunused_g_values) unused_g_values[next_g_index] = unused_g_values[--nunused_g_values]; + + // Marking used edges... + it1 = graph_neighbors_it(bmz8->graph, u); + while((lav = graph_next_neighbor(bmz8->graph, &it1)) != GRAPH_NO_NEIGHBOR) + { + if (graph_node_is_critical(bmz8->graph, lav) && GETBIT(visited, lav)) + { + SETBIT(used_edges,(next_g + bmz8->g[lav])); + if(next_g + bmz8->g[lav] > *biggest_edge_value) + *biggest_edge_value = (cmph_uint8)(next_g + bmz8->g[lav]); + } + } + + bmz8->g[u] = next_g; // Labelling vertex u. + SETBIT(visited, u); + vqueue_insert(q, u); + + } + } + + } + vqueue_destroy(q); + free(unused_g_values); + return 0; +} + +static cmph_uint8 next_unused_edge(bmz8_config_data_t *bmz8, cmph_uint8 * used_edges, cmph_uint32 unused_edge_index) +{ + while(1) + { + assert(unused_edge_index < bmz8->m); + if(GETBIT(used_edges, unused_edge_index)) unused_edge_index ++; + else break; + } + return (cmph_uint8)unused_edge_index; +} + +static void bmz8_traverse(bmz8_config_data_t *bmz8, cmph_uint8 * used_edges, cmph_uint32 v, cmph_uint8 * unused_edge_index, cmph_uint8 * visited) +{ + graph_iterator_t it = graph_neighbors_it(bmz8->graph, v); + cmph_uint32 neighbor = 0; + while((neighbor = graph_next_neighbor(bmz8->graph, &it)) != GRAPH_NO_NEIGHBOR) + { + if(GETBIT(visited,neighbor)) continue; + //DEBUGP("Visiting neighbor %u\n", neighbor); + *unused_edge_index = next_unused_edge(bmz8, used_edges, *unused_edge_index); + bmz8->g[neighbor] = (cmph_uint8)(*unused_edge_index - bmz8->g[v]); + //if (bmz8->g[neighbor] >= bmz8->m) bmz8->g[neighbor] += bmz8->m; + SETBIT(visited, neighbor); + (*unused_edge_index)++; + bmz8_traverse(bmz8, used_edges, neighbor, unused_edge_index, visited); + + } +} + +static void bmz8_traverse_non_critical_nodes(bmz8_config_data_t *bmz8, cmph_uint8 * used_edges, cmph_uint8 * visited) +{ + + cmph_uint8 i, v1, v2, unused_edge_index = 0; + DEBUGP("Labelling non critical vertices\n"); + for(i = 0; i < bmz8->m; i++) + { + v1 = (cmph_uint8)graph_vertex_id(bmz8->graph, i, 0); + v2 = (cmph_uint8)graph_vertex_id(bmz8->graph, i, 1); + if((GETBIT(visited,v1) && GETBIT(visited,v2)) || (!GETBIT(visited,v1) && !GETBIT(visited,v2))) continue; + if(GETBIT(visited,v1)) bmz8_traverse(bmz8, used_edges, v1, &unused_edge_index, visited); + else bmz8_traverse(bmz8, used_edges, v2, &unused_edge_index, visited); + + } + + for(i = 0; i < bmz8->n; i++) + { + if(!GETBIT(visited,i)) + { + bmz8->g[i] = 0; + SETBIT(visited, i); + bmz8_traverse(bmz8, used_edges, i, &unused_edge_index, visited); + } + } + +} + +static int bmz8_gen_edges(cmph_config_t *mph) +{ + cmph_uint8 e; + bmz8_config_data_t *bmz8 = (bmz8_config_data_t *)mph->data; + cmph_uint8 multiple_edges = 0; + DEBUGP("Generating edges for %u vertices\n", bmz8->n); + graph_clear_edges(bmz8->graph); + mph->key_source->rewind(mph->key_source->data); + for (e = 0; e < mph->key_source->nkeys; ++e) + { + cmph_uint8 h1, h2; + cmph_uint32 keylen; + char *key = NULL; + mph->key_source->read(mph->key_source->data, &key, &keylen); + +// if (key == NULL)fprintf(stderr, "key = %s -- read BMZ\n", key); + h1 = (cmph_uint8)(hash(bmz8->hashes[0], key, keylen) % bmz8->n); + h2 = (cmph_uint8)(hash(bmz8->hashes[1], key, keylen) % bmz8->n); + if (h1 == h2) if (++h2 >= bmz8->n) h2 = 0; + if (h1 == h2) + { + if (mph->verbosity) fprintf(stderr, "Self loop for key %u\n", e); + mph->key_source->dispose(mph->key_source->data, key, keylen); + return 0; + } + //DEBUGP("Adding edge: %u -> %u for key %s\n", h1, h2, key); + mph->key_source->dispose(mph->key_source->data, key, keylen); +// fprintf(stderr, "key = %s -- dispose BMZ\n", key); + multiple_edges = graph_contains_edge(bmz8->graph, h1, h2); + if (mph->verbosity && multiple_edges) fprintf(stderr, "A non simple graph was generated\n"); + if (multiple_edges) return 0; // checking multiple edge restriction. + graph_add_edge(bmz8->graph, h1, h2); + } + return !multiple_edges; +} + +int bmz8_dump(cmph_t *mphf, FILE *fd) +{ + char *buf = NULL; + cmph_uint32 buflen; + cmph_uint8 two = 2; //number of hash functions + bmz8_data_t *data = (bmz8_data_t *)mphf->data; + register size_t nbytes; + __cmph_dump(mphf, fd); + + nbytes = fwrite(&two, sizeof(cmph_uint8), (size_t)1, fd); + + hash_state_dump(data->hashes[0], &buf, &buflen); + DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); + nbytes = fwrite(&buflen, sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(buf, (size_t)buflen, (size_t)1, fd); + free(buf); + + hash_state_dump(data->hashes[1], &buf, &buflen); + DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); + nbytes = fwrite(&buflen, sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(buf, (size_t)buflen, (size_t)1, fd); + free(buf); + + nbytes = fwrite(&(data->n), sizeof(cmph_uint8), (size_t)1, fd); + nbytes = fwrite(&(data->m), sizeof(cmph_uint8), (size_t)1, fd); + + nbytes = fwrite(data->g, sizeof(cmph_uint8)*(data->n), (size_t)1, fd); +/* #ifdef DEBUG + fprintf(stderr, "G: "); + for (i = 0; i < data->n; ++i) fprintf(stderr, "%u ", data->g[i]); + fprintf(stderr, "\n"); + #endif*/ + return 1; +} + +void bmz8_load(FILE *f, cmph_t *mphf) +{ + cmph_uint8 nhashes; + char *buf = NULL; + cmph_uint32 buflen; + cmph_uint8 i; + register size_t nbytes; + bmz8_data_t *bmz8 = (bmz8_data_t *)malloc(sizeof(bmz8_data_t)); + + DEBUGP("Loading bmz8 mphf\n"); + mphf->data = bmz8; + nbytes = fread(&nhashes, sizeof(cmph_uint8), (size_t)1, f); + bmz8->hashes = (hash_state_t **)malloc(sizeof(hash_state_t *)*(size_t)(nhashes + 1)); + bmz8->hashes[nhashes] = NULL; + DEBUGP("Reading %u hashes\n", nhashes); + for (i = 0; i < nhashes; ++i) + { + hash_state_t *state = NULL; + nbytes = fread(&buflen, sizeof(cmph_uint32), (size_t)1, f); + DEBUGP("Hash state has %u bytes\n", buflen); + buf = (char *)malloc((size_t)buflen); + nbytes = fread(buf, (size_t)buflen, (size_t)1, f); + state = hash_state_load(buf, buflen); + bmz8->hashes[i] = state; + free(buf); + } + + DEBUGP("Reading m and n\n"); + nbytes = fread(&(bmz8->n), sizeof(cmph_uint8), (size_t)1, f); + nbytes = fread(&(bmz8->m), sizeof(cmph_uint8), (size_t)1, f); + + bmz8->g = (cmph_uint8 *)malloc(sizeof(cmph_uint8)*bmz8->n); + nbytes = fread(bmz8->g, bmz8->n*sizeof(cmph_uint8), (size_t)1, f); + #ifdef DEBUG + fprintf(stderr, "G: "); + for (i = 0; i < bmz8->n; ++i) fprintf(stderr, "%u ", bmz8->g[i]); + fprintf(stderr, "\n"); + #endif + return; +} + + +cmph_uint8 bmz8_search(cmph_t *mphf, const char *key, cmph_uint32 keylen) +{ + bmz8_data_t *bmz8 = mphf->data; + cmph_uint8 h1 = (cmph_uint8)(hash(bmz8->hashes[0], key, keylen) % bmz8->n); + cmph_uint8 h2 = (cmph_uint8)(hash(bmz8->hashes[1], key, keylen) % bmz8->n); + DEBUGP("key: %s h1: %u h2: %u\n", key, h1, h2); + if (h1 == h2 && ++h2 > bmz8->n) h2 = 0; + DEBUGP("key: %s g[h1]: %u g[h2]: %u edges: %u\n", key, bmz8->g[h1], bmz8->g[h2], bmz8->m); + return (cmph_uint8)(bmz8->g[h1] + bmz8->g[h2]); +} +void bmz8_destroy(cmph_t *mphf) +{ + bmz8_data_t *data = (bmz8_data_t *)mphf->data; + free(data->g); + hash_state_destroy(data->hashes[0]); + hash_state_destroy(data->hashes[1]); + free(data->hashes); + free(data); + free(mphf); +} + +/** \fn void bmz8_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void bmz8_pack(cmph_t *mphf, void *packed_mphf) +{ + bmz8_data_t *data = (bmz8_data_t *)mphf->data; + cmph_uint8 * ptr = packed_mphf; + + // packing h1 type + CMPH_HASH h1_type = hash_get_type(data->hashes[0]); + *((cmph_uint32 *) ptr) = h1_type; + ptr += sizeof(cmph_uint32); + + // packing h1 + hash_state_pack(data->hashes[0], ptr); + ptr += hash_state_packed_size(h1_type); + + // packing h2 type + CMPH_HASH h2_type = hash_get_type(data->hashes[1]); + *((cmph_uint32 *) ptr) = h2_type; + ptr += sizeof(cmph_uint32); + + // packing h2 + hash_state_pack(data->hashes[1], ptr); + ptr += hash_state_packed_size(h2_type); + + // packing n + *ptr++ = data->n; + + // packing g + memcpy(ptr, data->g, sizeof(cmph_uint8)*data->n); +} + +/** \fn cmph_uint32 bmz8_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 bmz8_packed_size(cmph_t *mphf) +{ + bmz8_data_t *data = (bmz8_data_t *)mphf->data; + CMPH_HASH h1_type = hash_get_type(data->hashes[0]); + CMPH_HASH h2_type = hash_get_type(data->hashes[1]); + + return (cmph_uint32)(sizeof(CMPH_ALGO) + hash_state_packed_size(h1_type) + hash_state_packed_size(h2_type) + + 2*sizeof(cmph_uint32) + sizeof(cmph_uint8) + sizeof(cmph_uint8)*data->n); +} + +/** cmph_uint8 bmz8_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint8 bmz8_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen) +{ + register cmph_uint8 *h1_ptr = packed_mphf; + register CMPH_HASH h1_type = *((cmph_uint32 *)h1_ptr); + h1_ptr += 4; + + register cmph_uint8 *h2_ptr = h1_ptr + hash_state_packed_size(h1_type); + register CMPH_HASH h2_type = *((cmph_uint32 *)h2_ptr); + h2_ptr += 4; + + register cmph_uint8 *g_ptr = h2_ptr + hash_state_packed_size(h2_type); + + register cmph_uint8 n = *g_ptr++; + + register cmph_uint8 h1 = (cmph_uint8)(hash_packed(h1_ptr, h1_type, key, keylen) % n); + register cmph_uint8 h2 = (cmph_uint8)(hash_packed(h2_ptr, h2_type, key, keylen) % n); + DEBUGP("key: %s h1: %u h2: %u\n", key, h1, h2); + if (h1 == h2 && ++h2 > n) h2 = 0; + return (cmph_uint8)(g_ptr[h1] + g_ptr[h2]); +} diff --git a/cmph/bmz8.h b/cmph/bmz8.h new file mode 100644 index 000000000..5456759ef --- /dev/null +++ b/cmph/bmz8.h @@ -0,0 +1,42 @@ +#ifndef __CMPH_BMZ8_H__ +#define __CMPH_BMZ8_H__ + +#include "cmph.h" + +typedef struct __bmz8_data_t bmz8_data_t; +typedef struct __bmz8_config_data_t bmz8_config_data_t; + +bmz8_config_data_t *bmz8_config_new(); +void bmz8_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); +void bmz8_config_destroy(cmph_config_t *mph); +cmph_t *bmz8_new(cmph_config_t *mph, double c); + +void bmz8_load(FILE *f, cmph_t *mphf); +int bmz8_dump(cmph_t *mphf, FILE *f); +void bmz8_destroy(cmph_t *mphf); +cmph_uint8 bmz8_search(cmph_t *mphf, const char *key, cmph_uint32 keylen); + +/** \fn void bmz8_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void bmz8_pack(cmph_t *mphf, void *packed_mphf); + +/** \fn cmph_uint32 bmz8_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 bmz8_packed_size(cmph_t *mphf); + +/** cmph_uint8 bmz8_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint8 bmz8_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen); + +#endif diff --git a/cmph/bmz8_structs.h b/cmph/bmz8_structs.h new file mode 100644 index 000000000..408b52998 --- /dev/null +++ b/cmph/bmz8_structs.h @@ -0,0 +1,25 @@ +#ifndef __CMPH_BMZ8_STRUCTS_H__ +#define __CMPH_BMZ8_STRUCTS_H__ + +#include "hash_state.h" + +struct __bmz8_data_t +{ + cmph_uint8 m; //edges (words) count + cmph_uint8 n; //vertex count + cmph_uint8 *g; + hash_state_t **hashes; +}; + + +struct __bmz8_config_data_t +{ + CMPH_HASH hashfuncs[2]; + cmph_uint8 m; //edges (words) count + cmph_uint8 n; //vertex count + graph_t *graph; + cmph_uint8 *g; + hash_state_t **hashes; +}; + +#endif diff --git a/cmph/bmz_structs.h b/cmph/bmz_structs.h new file mode 100644 index 000000000..67065a005 --- /dev/null +++ b/cmph/bmz_structs.h @@ -0,0 +1,25 @@ +#ifndef __CMPH_BMZ_STRUCTS_H__ +#define __CMPH_BMZ_STRUCTS_H__ + +#include "hash_state.h" + +struct __bmz_data_t +{ + cmph_uint32 m; //edges (words) count + cmph_uint32 n; //vertex count + cmph_uint32 *g; + hash_state_t **hashes; +}; + + +struct __bmz_config_data_t +{ + CMPH_HASH hashfuncs[2]; + cmph_uint32 m; //edges (words) count + cmph_uint32 n; //vertex count + graph_t *graph; + cmph_uint32 *g; + hash_state_t **hashes; +}; + +#endif diff --git a/cmph/brz.c b/cmph/brz.c new file mode 100755 index 000000000..eb89ac06c --- /dev/null +++ b/cmph/brz.c @@ -0,0 +1,985 @@ +#include "graph.h" +#include "fch.h" +#include "fch_structs.h" +#include "bmz8.h" +#include "bmz8_structs.h" +#include "brz.h" +#include "cmph_structs.h" +#include "brz_structs.h" +#include "buffer_manager.h" +#include "cmph.h" +#include "hash.h" +#include "bitbool.h" +#include +#include +#include +#include +#include +#define MAX_BUCKET_SIZE 255 +//#define DEBUG +#include "debug.h" + +static int brz_gen_mphf(cmph_config_t *mph); +static cmph_uint32 brz_min_index(cmph_uint32 * vector, cmph_uint32 n); +static void brz_destroy_keys_vd(cmph_uint8 ** keys_vd, cmph_uint32 nkeys); +static char * brz_copy_partial_fch_mphf(brz_config_data_t *brz, fch_data_t * fchf, cmph_uint32 index, cmph_uint32 *buflen); +static char * brz_copy_partial_bmz8_mphf(brz_config_data_t *brz, bmz8_data_t * bmzf, cmph_uint32 index, cmph_uint32 *buflen); +brz_config_data_t *brz_config_new() +{ + brz_config_data_t *brz = NULL; + brz = (brz_config_data_t *)malloc(sizeof(brz_config_data_t)); + brz->algo = CMPH_FCH; + brz->b = 128; + brz->hashfuncs[0] = CMPH_HASH_JENKINS; + brz->hashfuncs[1] = CMPH_HASH_JENKINS; + brz->hashfuncs[2] = CMPH_HASH_JENKINS; + brz->size = NULL; + brz->offset = NULL; + brz->g = NULL; + brz->h1 = NULL; + brz->h2 = NULL; + brz->h0 = NULL; + brz->memory_availability = 1024*1024; + brz->tmp_dir = (cmph_uint8 *)calloc((size_t)10, sizeof(cmph_uint8)); + brz->mphf_fd = NULL; + strcpy((char *)(brz->tmp_dir), "/var/tmp/"); + assert(brz); + return brz; +} + +void brz_config_destroy(cmph_config_t *mph) +{ + brz_config_data_t *data = (brz_config_data_t *)mph->data; + free(data->tmp_dir); + DEBUGP("Destroying algorithm dependent data\n"); + free(data); +} + +void brz_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs) +{ + brz_config_data_t *brz = (brz_config_data_t *)mph->data; + CMPH_HASH *hashptr = hashfuncs; + cmph_uint32 i = 0; + while(*hashptr != CMPH_HASH_COUNT) + { + if (i >= 3) break; //brz only uses three hash functions + brz->hashfuncs[i] = *hashptr; + ++i, ++hashptr; + } +} + +void brz_config_set_memory_availability(cmph_config_t *mph, cmph_uint32 memory_availability) +{ + brz_config_data_t *brz = (brz_config_data_t *)mph->data; + if(memory_availability > 0) brz->memory_availability = memory_availability*1024*1024; +} + +void brz_config_set_tmp_dir(cmph_config_t *mph, cmph_uint8 *tmp_dir) +{ + brz_config_data_t *brz = (brz_config_data_t *)mph->data; + if(tmp_dir) + { + size_t len = strlen((char *)tmp_dir); + free(brz->tmp_dir); + if(tmp_dir[len-1] != '/') + { + brz->tmp_dir = (cmph_uint8 *)calloc((size_t)len+2, sizeof(cmph_uint8)); + sprintf((char *)(brz->tmp_dir), "%s/", (char *)tmp_dir); + } + else + { + brz->tmp_dir = (cmph_uint8 *)calloc((size_t)len+1, sizeof(cmph_uint8)); + sprintf((char *)(brz->tmp_dir), "%s", (char *)tmp_dir); + } + + } +} + +void brz_config_set_mphf_fd(cmph_config_t *mph, FILE *mphf_fd) +{ + brz_config_data_t *brz = (brz_config_data_t *)mph->data; + brz->mphf_fd = mphf_fd; + assert(brz->mphf_fd); +} + +void brz_config_set_b(cmph_config_t *mph, cmph_uint32 b) +{ + brz_config_data_t *brz = (brz_config_data_t *)mph->data; + if(b <= 64 || b >= 175) + { + b = 128; + } + brz->b = (cmph_uint8)b; +} + +void brz_config_set_algo(cmph_config_t *mph, CMPH_ALGO algo) +{ + if (algo == CMPH_BMZ8 || algo == CMPH_FCH) // supported algorithms + { + brz_config_data_t *brz = (brz_config_data_t *)mph->data; + brz->algo = algo; + } +} + +cmph_t *brz_new(cmph_config_t *mph, double c) +{ + cmph_t *mphf = NULL; + brz_data_t *brzf = NULL; + cmph_uint32 i; + cmph_uint32 iterations = 20; + + DEBUGP("c: %f\n", c); + brz_config_data_t *brz = (brz_config_data_t *)mph->data; + switch(brz->algo) // validating restrictions over parameter c. + { + case CMPH_BMZ8: + if (c == 0 || c >= 2.0) c = 1; + break; + case CMPH_FCH: + if (c <= 2.0) c = 2.6; + break; + default: + assert(0); + } + brz->c = c; + brz->m = mph->key_source->nkeys; + DEBUGP("m: %u\n", brz->m); + brz->k = (cmph_uint32)ceil(brz->m/((double)brz->b)); + DEBUGP("k: %u\n", brz->k); + brz->size = (cmph_uint8 *) calloc((size_t)brz->k, sizeof(cmph_uint8)); + + // Clustering the keys by graph id. + if (mph->verbosity) + { + fprintf(stderr, "Partioning the set of keys.\n"); + } + + while(1) + { + int ok; + DEBUGP("hash function 3\n"); + brz->h0 = hash_state_new(brz->hashfuncs[2], brz->k); + DEBUGP("Generating graphs\n"); + ok = brz_gen_mphf(mph); + if (!ok) + { + --iterations; + hash_state_destroy(brz->h0); + brz->h0 = NULL; + DEBUGP("%u iterations remaining to create the graphs in a external file\n", iterations); + if (mph->verbosity) + { + fprintf(stderr, "Failure: A graph with more than 255 keys was created - %u iterations remaining\n", iterations); + } + if (iterations == 0) break; + } + else break; + } + if (iterations == 0) + { + DEBUGP("Graphs with more than 255 keys were created in all 20 iterations\n"); + free(brz->size); + return NULL; + } + DEBUGP("Graphs generated\n"); + + brz->offset = (cmph_uint32 *)calloc((size_t)brz->k, sizeof(cmph_uint32)); + for (i = 1; i < brz->k; ++i) + { + brz->offset[i] = brz->size[i-1] + brz->offset[i-1]; + } + // Generating a mphf + mphf = (cmph_t *)malloc(sizeof(cmph_t)); + mphf->algo = mph->algo; + brzf = (brz_data_t *)malloc(sizeof(brz_data_t)); + brzf->g = brz->g; + brz->g = NULL; //transfer memory ownership + brzf->h1 = brz->h1; + brz->h1 = NULL; //transfer memory ownership + brzf->h2 = brz->h2; + brz->h2 = NULL; //transfer memory ownership + brzf->h0 = brz->h0; + brz->h0 = NULL; //transfer memory ownership + brzf->size = brz->size; + brz->size = NULL; //transfer memory ownership + brzf->offset = brz->offset; + brz->offset = NULL; //transfer memory ownership + brzf->k = brz->k; + brzf->c = brz->c; + brzf->m = brz->m; + brzf->algo = brz->algo; + mphf->data = brzf; + mphf->size = brz->m; + DEBUGP("Successfully generated minimal perfect hash\n"); + if (mph->verbosity) + { + fprintf(stderr, "Successfully generated minimal perfect hash function\n"); + } + return mphf; +} + +static int brz_gen_mphf(cmph_config_t *mph) +{ + cmph_uint32 i, e, error; + brz_config_data_t *brz = (brz_config_data_t *)mph->data; + cmph_uint32 memory_usage = 0; + cmph_uint32 nkeys_in_buffer = 0; + cmph_uint8 *buffer = (cmph_uint8 *)malloc((size_t)brz->memory_availability); + cmph_uint32 *buckets_size = (cmph_uint32 *)calloc((size_t)brz->k, sizeof(cmph_uint32)); + cmph_uint32 *keys_index = NULL; + cmph_uint8 **buffer_merge = NULL; + cmph_uint32 *buffer_h0 = NULL; + cmph_uint32 nflushes = 0; + cmph_uint32 h0; + register size_t nbytes; + FILE * tmp_fd = NULL; + buffer_manager_t * buff_manager = NULL; + char *filename = NULL; + char *key = NULL; + cmph_uint32 keylen; + cmph_uint32 cur_bucket = 0; + cmph_uint8 nkeys_vd = 0; + cmph_uint8 ** keys_vd = NULL; + + mph->key_source->rewind(mph->key_source->data); + DEBUGP("Generating graphs from %u keys\n", brz->m); + // Partitioning + for (e = 0; e < brz->m; ++e) + { + mph->key_source->read(mph->key_source->data, &key, &keylen); + + /* Buffers management */ + if (memory_usage + keylen + sizeof(keylen) > brz->memory_availability) // flush buffers + { + if(mph->verbosity) + { + fprintf(stderr, "Flushing %u\n", nkeys_in_buffer); + } + cmph_uint32 value = buckets_size[0]; + cmph_uint32 sum = 0; + cmph_uint32 keylen1 = 0; + buckets_size[0] = 0; + for(i = 1; i < brz->k; i++) + { + if(buckets_size[i] == 0) continue; + sum += value; + value = buckets_size[i]; + buckets_size[i] = sum; + + } + memory_usage = 0; + keys_index = (cmph_uint32 *)calloc((size_t)nkeys_in_buffer, sizeof(cmph_uint32)); + for(i = 0; i < nkeys_in_buffer; i++) + { + memcpy(&keylen1, buffer + memory_usage, sizeof(keylen1)); + h0 = hash(brz->h0, (char *)(buffer + memory_usage + sizeof(keylen1)), keylen1) % brz->k; + keys_index[buckets_size[h0]] = memory_usage; + buckets_size[h0]++; + memory_usage += keylen1 + (cmph_uint32)sizeof(keylen1); + } + filename = (char *)calloc(strlen((char *)(brz->tmp_dir)) + 11, sizeof(char)); + sprintf(filename, "%s%u.cmph",brz->tmp_dir, nflushes); + tmp_fd = fopen(filename, "wb"); + free(filename); + filename = NULL; + for(i = 0; i < nkeys_in_buffer; i++) + { + memcpy(&keylen1, buffer + keys_index[i], sizeof(keylen1)); + nbytes = fwrite(buffer + keys_index[i], (size_t)1, keylen1 + sizeof(keylen1), tmp_fd); + } + nkeys_in_buffer = 0; + memory_usage = 0; + memset((void *)buckets_size, 0, brz->k*sizeof(cmph_uint32)); + nflushes++; + free(keys_index); + fclose(tmp_fd); + } + memcpy(buffer + memory_usage, &keylen, sizeof(keylen)); + memcpy(buffer + memory_usage + sizeof(keylen), key, (size_t)keylen); + memory_usage += keylen + (cmph_uint32)sizeof(keylen); + h0 = hash(brz->h0, key, keylen) % brz->k; + + if ((brz->size[h0] == MAX_BUCKET_SIZE) || (brz->algo == CMPH_BMZ8 && ((brz->c >= 1.0) && (cmph_uint8)(brz->c * brz->size[h0]) < brz->size[h0]))) + { + free(buffer); + free(buckets_size); + return 0; + } + brz->size[h0] = (cmph_uint8)(brz->size[h0] + 1U); + buckets_size[h0] ++; + nkeys_in_buffer++; + mph->key_source->dispose(mph->key_source->data, key, keylen); + } + if (memory_usage != 0) // flush buffers + { + if(mph->verbosity) + { + fprintf(stderr, "Flushing %u\n", nkeys_in_buffer); + } + cmph_uint32 value = buckets_size[0]; + cmph_uint32 sum = 0; + cmph_uint32 keylen1 = 0; + buckets_size[0] = 0; + for(i = 1; i < brz->k; i++) + { + if(buckets_size[i] == 0) continue; + sum += value; + value = buckets_size[i]; + buckets_size[i] = sum; + } + memory_usage = 0; + keys_index = (cmph_uint32 *)calloc((size_t)nkeys_in_buffer, sizeof(cmph_uint32)); + for(i = 0; i < nkeys_in_buffer; i++) + { + memcpy(&keylen1, buffer + memory_usage, sizeof(keylen1)); + h0 = hash(brz->h0, (char *)(buffer + memory_usage + sizeof(keylen1)), keylen1) % brz->k; + keys_index[buckets_size[h0]] = memory_usage; + buckets_size[h0]++; + memory_usage += keylen1 + (cmph_uint32)sizeof(keylen1); + } + filename = (char *)calloc(strlen((char *)(brz->tmp_dir)) + 11, sizeof(char)); + sprintf(filename, "%s%u.cmph",brz->tmp_dir, nflushes); + tmp_fd = fopen(filename, "wb"); + free(filename); + filename = NULL; + for(i = 0; i < nkeys_in_buffer; i++) + { + memcpy(&keylen1, buffer + keys_index[i], sizeof(keylen1)); + nbytes = fwrite(buffer + keys_index[i], (size_t)1, keylen1 + sizeof(keylen1), tmp_fd); + } + nkeys_in_buffer = 0; + memory_usage = 0; + memset((void *)buckets_size, 0, brz->k*sizeof(cmph_uint32)); + nflushes++; + free(keys_index); + fclose(tmp_fd); + } + + free(buffer); + free(buckets_size); + if(nflushes > 1024) return 0; // Too many files generated. + // mphf generation + if(mph->verbosity) + { + fprintf(stderr, "\nMPHF generation \n"); + } + /* Starting to dump to disk the resultant MPHF: __cmph_dump function */ + nbytes = fwrite(cmph_names[CMPH_BRZ], (size_t)(strlen(cmph_names[CMPH_BRZ]) + 1), (size_t)1, brz->mphf_fd); + nbytes = fwrite(&(brz->m), sizeof(brz->m), (size_t)1, brz->mphf_fd); + nbytes = fwrite(&(brz->c), sizeof(double), (size_t)1, brz->mphf_fd); + nbytes = fwrite(&(brz->algo), sizeof(brz->algo), (size_t)1, brz->mphf_fd); + nbytes = fwrite(&(brz->k), sizeof(cmph_uint32), (size_t)1, brz->mphf_fd); // number of MPHFs + nbytes = fwrite(brz->size, sizeof(cmph_uint8)*(brz->k), (size_t)1, brz->mphf_fd); + + //tmp_fds = (FILE **)calloc(nflushes, sizeof(FILE *)); + buff_manager = buffer_manager_new(brz->memory_availability, nflushes); + buffer_merge = (cmph_uint8 **)calloc((size_t)nflushes, sizeof(cmph_uint8 *)); + buffer_h0 = (cmph_uint32 *)calloc((size_t)nflushes, sizeof(cmph_uint32)); + + memory_usage = 0; + for(i = 0; i < nflushes; i++) + { + filename = (char *)calloc(strlen((char *)(brz->tmp_dir)) + 11, sizeof(char)); + sprintf(filename, "%s%u.cmph",brz->tmp_dir, i); + buffer_manager_open(buff_manager, i, filename); + free(filename); + filename = NULL; + key = (char *)buffer_manager_read_key(buff_manager, i, &keylen); + h0 = hash(brz->h0, key+sizeof(keylen), keylen) % brz->k; + buffer_h0[i] = h0; + buffer_merge[i] = (cmph_uint8 *)key; + key = NULL; //transfer memory ownership + } + e = 0; + keys_vd = (cmph_uint8 **)calloc((size_t)MAX_BUCKET_SIZE, sizeof(cmph_uint8 *)); + nkeys_vd = 0; + error = 0; + while(e < brz->m) + { + i = brz_min_index(buffer_h0, nflushes); + cur_bucket = buffer_h0[i]; + key = (char *)buffer_manager_read_key(buff_manager, i, &keylen); + if(key) + { + while(key) + { + //keylen = strlen(key); + h0 = hash(brz->h0, key+sizeof(keylen), keylen) % brz->k; + if (h0 != buffer_h0[i]) break; + keys_vd[nkeys_vd++] = (cmph_uint8 *)key; + key = NULL; //transfer memory ownership + e++; + key = (char *)buffer_manager_read_key(buff_manager, i, &keylen); + } + if (key) + { + assert(nkeys_vd < brz->size[cur_bucket]); + keys_vd[nkeys_vd++] = buffer_merge[i]; + buffer_merge[i] = NULL; //transfer memory ownership + e++; + buffer_h0[i] = h0; + buffer_merge[i] = (cmph_uint8 *)key; + } + } + if(!key) + { + assert(nkeys_vd < brz->size[cur_bucket]); + keys_vd[nkeys_vd++] = buffer_merge[i]; + buffer_merge[i] = NULL; //transfer memory ownership + e++; + buffer_h0[i] = UINT_MAX; + } + + if(nkeys_vd == brz->size[cur_bucket]) // Generating mphf for each bucket. + { + cmph_io_adapter_t *source = NULL; + cmph_config_t *config = NULL; + cmph_t *mphf_tmp = NULL; + char *bufmphf = NULL; + cmph_uint32 buflenmphf = 0; + // Source of keys + source = cmph_io_byte_vector_adapter(keys_vd, (cmph_uint32)nkeys_vd); + config = cmph_config_new(source); + cmph_config_set_algo(config, brz->algo); + //cmph_config_set_algo(config, CMPH_BMZ8); + cmph_config_set_graphsize(config, brz->c); + mphf_tmp = cmph_new(config); + if (mphf_tmp == NULL) + { + if(mph->verbosity) fprintf(stderr, "ERROR: Can't generate MPHF for bucket %u out of %u\n", cur_bucket + 1, brz->k); + error = 1; + cmph_config_destroy(config); + brz_destroy_keys_vd(keys_vd, nkeys_vd); + cmph_io_byte_vector_adapter_destroy(source); + break; + } + if(mph->verbosity) + { + if (cur_bucket % 1000 == 0) + { + fprintf(stderr, "MPHF for bucket %u out of %u was generated.\n", cur_bucket + 1, brz->k); + } + } + switch(brz->algo) + { + case CMPH_FCH: + { + fch_data_t * fchf = NULL; + fchf = (fch_data_t *)mphf_tmp->data; + bufmphf = brz_copy_partial_fch_mphf(brz, fchf, cur_bucket, &buflenmphf); + } + break; + case CMPH_BMZ8: + { + bmz8_data_t * bmzf = NULL; + bmzf = (bmz8_data_t *)mphf_tmp->data; + bufmphf = brz_copy_partial_bmz8_mphf(brz, bmzf, cur_bucket, &buflenmphf); + } + break; + default: assert(0); + } + nbytes = fwrite(bufmphf, (size_t)buflenmphf, (size_t)1, brz->mphf_fd); + free(bufmphf); + bufmphf = NULL; + cmph_config_destroy(config); + brz_destroy_keys_vd(keys_vd, nkeys_vd); + cmph_destroy(mphf_tmp); + cmph_io_byte_vector_adapter_destroy(source); + nkeys_vd = 0; + } + } + buffer_manager_destroy(buff_manager); + free(keys_vd); + free(buffer_merge); + free(buffer_h0); + if (error) return 0; + return 1; +} + +static cmph_uint32 brz_min_index(cmph_uint32 * vector, cmph_uint32 n) +{ + cmph_uint32 i, min_index = 0; + for(i = 1; i < n; i++) + { + if(vector[i] < vector[min_index]) min_index = i; + } + return min_index; +} + +static void brz_destroy_keys_vd(cmph_uint8 ** keys_vd, cmph_uint32 nkeys) +{ + cmph_uint8 i; + for(i = 0; i < nkeys; i++) { free(keys_vd[i]); keys_vd[i] = NULL;} +} + +static char * brz_copy_partial_fch_mphf(brz_config_data_t *brz, fch_data_t * fchf, cmph_uint32 index, cmph_uint32 *buflen) +{ + cmph_uint32 i = 0; + cmph_uint32 buflenh1 = 0; + cmph_uint32 buflenh2 = 0; + char * bufh1 = NULL; + char * bufh2 = NULL; + char * buf = NULL; + cmph_uint32 n = fchf->b;//brz->size[index]; + hash_state_dump(fchf->h1, &bufh1, &buflenh1); + hash_state_dump(fchf->h2, &bufh2, &buflenh2); + *buflen = buflenh1 + buflenh2 + n + 2U * (cmph_uint32)sizeof(cmph_uint32); + buf = (char *)malloc((size_t)(*buflen)); + memcpy(buf, &buflenh1, sizeof(cmph_uint32)); + memcpy(buf+sizeof(cmph_uint32), bufh1, (size_t)buflenh1); + memcpy(buf+sizeof(cmph_uint32)+buflenh1, &buflenh2, sizeof(cmph_uint32)); + memcpy(buf+2*sizeof(cmph_uint32)+buflenh1, bufh2, (size_t)buflenh2); + for (i = 0; i < n; i++) memcpy(buf+2*sizeof(cmph_uint32)+buflenh1+buflenh2+i,(fchf->g + i), (size_t)1); + free(bufh1); + free(bufh2); + return buf; +} +static char * brz_copy_partial_bmz8_mphf(brz_config_data_t *brz, bmz8_data_t * bmzf, cmph_uint32 index, cmph_uint32 *buflen) +{ + cmph_uint32 buflenh1 = 0; + cmph_uint32 buflenh2 = 0; + char * bufh1 = NULL; + char * bufh2 = NULL; + char * buf = NULL; + cmph_uint32 n = (cmph_uint32)ceil(brz->c * brz->size[index]); + hash_state_dump(bmzf->hashes[0], &bufh1, &buflenh1); + hash_state_dump(bmzf->hashes[1], &bufh2, &buflenh2); + *buflen = buflenh1 + buflenh2 + n + 2U * (cmph_uint32)sizeof(cmph_uint32); + buf = (char *)malloc((size_t)(*buflen)); + memcpy(buf, &buflenh1, sizeof(cmph_uint32)); + memcpy(buf+sizeof(cmph_uint32), bufh1, (size_t)buflenh1); + memcpy(buf+sizeof(cmph_uint32)+buflenh1, &buflenh2, sizeof(cmph_uint32)); + memcpy(buf+2*sizeof(cmph_uint32)+buflenh1, bufh2, (size_t)buflenh2); + memcpy(buf+2*sizeof(cmph_uint32)+buflenh1+buflenh2,bmzf->g, (size_t)n); + free(bufh1); + free(bufh2); + return buf; +} + + +int brz_dump(cmph_t *mphf, FILE *fd) +{ + brz_data_t *data = (brz_data_t *)mphf->data; + char *buf = NULL; + cmph_uint32 buflen; + register size_t nbytes; + DEBUGP("Dumping brzf\n"); + // The initial part of the MPHF have already been dumped to disk during construction + // Dumping h0 + hash_state_dump(data->h0, &buf, &buflen); + DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); + nbytes = fwrite(&buflen, sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(buf, (size_t)buflen, (size_t)1, fd); + free(buf); + // Dumping m and the vector offset. + nbytes = fwrite(&(data->m), sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(data->offset, sizeof(cmph_uint32)*(data->k), (size_t)1, fd); + return 1; +} + +void brz_load(FILE *f, cmph_t *mphf) +{ + char *buf = NULL; + cmph_uint32 buflen; + register size_t nbytes; + cmph_uint32 i, n; + brz_data_t *brz = (brz_data_t *)malloc(sizeof(brz_data_t)); + + DEBUGP("Loading brz mphf\n"); + mphf->data = brz; + nbytes = fread(&(brz->c), sizeof(double), (size_t)1, f); + nbytes = fread(&(brz->algo), sizeof(brz->algo), (size_t)1, f); // Reading algo. + nbytes = fread(&(brz->k), sizeof(cmph_uint32), (size_t)1, f); + brz->size = (cmph_uint8 *) malloc(sizeof(cmph_uint8)*brz->k); + nbytes = fread(brz->size, sizeof(cmph_uint8)*(brz->k), (size_t)1, f); + brz->h1 = (hash_state_t **)malloc(sizeof(hash_state_t *)*brz->k); + brz->h2 = (hash_state_t **)malloc(sizeof(hash_state_t *)*brz->k); + brz->g = (cmph_uint8 **) calloc((size_t)brz->k, sizeof(cmph_uint8 *)); + DEBUGP("Reading c = %f k = %u algo = %u \n", brz->c, brz->k, brz->algo); + //loading h_i1, h_i2 and g_i. + for(i = 0; i < brz->k; i++) + { + // h1 + nbytes = fread(&buflen, sizeof(cmph_uint32), (size_t)1, f); + DEBUGP("Hash state 1 has %u bytes\n", buflen); + buf = (char *)malloc((size_t)buflen); + nbytes = fread(buf, (size_t)buflen, (size_t)1, f); + brz->h1[i] = hash_state_load(buf, buflen); + free(buf); + //h2 + nbytes = fread(&buflen, sizeof(cmph_uint32), (size_t)1, f); + DEBUGP("Hash state 2 has %u bytes\n", buflen); + buf = (char *)malloc((size_t)buflen); + nbytes = fread(buf, (size_t)buflen, (size_t)1, f); + brz->h2[i] = hash_state_load(buf, buflen); + free(buf); + switch(brz->algo) + { + case CMPH_FCH: + n = fch_calc_b(brz->c, brz->size[i]); + break; + case CMPH_BMZ8: + n = (cmph_uint32)ceil(brz->c * brz->size[i]); + break; + default: assert(0); + } + DEBUGP("g_i has %u bytes\n", n); + brz->g[i] = (cmph_uint8 *)calloc((size_t)n, sizeof(cmph_uint8)); + nbytes = fread(brz->g[i], sizeof(cmph_uint8)*n, (size_t)1, f); + } + //loading h0 + nbytes = fread(&buflen, sizeof(cmph_uint32), (size_t)1, f); + DEBUGP("Hash state has %u bytes\n", buflen); + buf = (char *)malloc((size_t)buflen); + nbytes = fread(buf, (size_t)buflen, (size_t)1, f); + brz->h0 = hash_state_load(buf, buflen); + free(buf); + + //loading c, m, and the vector offset. + nbytes = fread(&(brz->m), sizeof(cmph_uint32), (size_t)1, f); + brz->offset = (cmph_uint32 *)malloc(sizeof(cmph_uint32)*brz->k); + nbytes = fread(brz->offset, sizeof(cmph_uint32)*(brz->k), (size_t)1, f); + return; +} + +static cmph_uint32 brz_bmz8_search(brz_data_t *brz, const char *key, cmph_uint32 keylen, cmph_uint32 * fingerprint) +{ + register cmph_uint32 h0; + + hash_vector(brz->h0, key, keylen, fingerprint); + h0 = fingerprint[2] % brz->k; + + register cmph_uint32 m = brz->size[h0]; + register cmph_uint32 n = (cmph_uint32)ceil(brz->c * m); + register cmph_uint32 h1 = hash(brz->h1[h0], key, keylen) % n; + register cmph_uint32 h2 = hash(brz->h2[h0], key, keylen) % n; + register cmph_uint8 mphf_bucket; + + if (h1 == h2 && ++h2 >= n) h2 = 0; + mphf_bucket = (cmph_uint8)(brz->g[h0][h1] + brz->g[h0][h2]); + DEBUGP("key: %s h1: %u h2: %u h0: %u\n", key, h1, h2, h0); + DEBUGP("key: %s g[h1]: %u g[h2]: %u offset[h0]: %u edges: %u\n", key, brz->g[h0][h1], brz->g[h0][h2], brz->offset[h0], brz->m); + DEBUGP("Address: %u\n", mphf_bucket + brz->offset[h0]); + return (mphf_bucket + brz->offset[h0]); +} + +static cmph_uint32 brz_fch_search(brz_data_t *brz, const char *key, cmph_uint32 keylen, cmph_uint32 * fingerprint) +{ + register cmph_uint32 h0; + + hash_vector(brz->h0, key, keylen, fingerprint); + h0 = fingerprint[2] % brz->k; + + register cmph_uint32 m = brz->size[h0]; + register cmph_uint32 b = fch_calc_b(brz->c, m); + register double p1 = fch_calc_p1(m); + register double p2 = fch_calc_p2(b); + register cmph_uint32 h1 = hash(brz->h1[h0], key, keylen) % m; + register cmph_uint32 h2 = hash(brz->h2[h0], key, keylen) % m; + register cmph_uint8 mphf_bucket = 0; + h1 = mixh10h11h12(b, p1, p2, h1); + mphf_bucket = (cmph_uint8)((h2 + brz->g[h0][h1]) % m); + return (mphf_bucket + brz->offset[h0]); +} + +cmph_uint32 brz_search(cmph_t *mphf, const char *key, cmph_uint32 keylen) +{ + brz_data_t *brz = mphf->data; + cmph_uint32 fingerprint[3]; + switch(brz->algo) + { + case CMPH_FCH: + return brz_fch_search(brz, key, keylen, fingerprint); + case CMPH_BMZ8: + return brz_bmz8_search(brz, key, keylen, fingerprint); + default: assert(0); + } + return 0; +} +void brz_destroy(cmph_t *mphf) +{ + cmph_uint32 i; + brz_data_t *data = (brz_data_t *)mphf->data; + if(data->g) + { + for(i = 0; i < data->k; i++) + { + free(data->g[i]); + hash_state_destroy(data->h1[i]); + hash_state_destroy(data->h2[i]); + } + free(data->g); + free(data->h1); + free(data->h2); + } + hash_state_destroy(data->h0); + free(data->size); + free(data->offset); + free(data); + free(mphf); +} + +/** \fn void brz_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void brz_pack(cmph_t *mphf, void *packed_mphf) +{ + brz_data_t *data = (brz_data_t *)mphf->data; + cmph_uint8 * ptr = packed_mphf; + cmph_uint32 i,n; + + // packing internal algo type + memcpy(ptr, &(data->algo), sizeof(data->algo)); + ptr += sizeof(data->algo); + + // packing h0 type + CMPH_HASH h0_type = hash_get_type(data->h0); + memcpy(ptr, &h0_type, sizeof(h0_type)); + ptr += sizeof(h0_type); + + // packing h0 + hash_state_pack(data->h0, ptr); + ptr += hash_state_packed_size(h0_type); + + // packing k + memcpy(ptr, &(data->k), sizeof(data->k)); + ptr += sizeof(data->k); + + // packing c + *((cmph_uint64 *)ptr) = (cmph_uint64)data->c; + ptr += sizeof(data->c); + + // packing h1 type + CMPH_HASH h1_type = hash_get_type(data->h1[0]); + memcpy(ptr, &h1_type, sizeof(h1_type)); + ptr += sizeof(h1_type); + + // packing h2 type + CMPH_HASH h2_type = hash_get_type(data->h2[0]); + memcpy(ptr, &h2_type, sizeof(h2_type)); + ptr += sizeof(h2_type); + + // packing size + memcpy(ptr, data->size, sizeof(cmph_uint8)*data->k); + ptr += data->k; + + // packing offset + memcpy(ptr, data->offset, sizeof(cmph_uint32)*data->k); + ptr += sizeof(cmph_uint32)*data->k; + + #if defined (__ia64) || defined (__x86_64__) + cmph_uint64 * g_is_ptr = (cmph_uint64 *)ptr; + #else + cmph_uint32 * g_is_ptr = (cmph_uint32 *)ptr; + #endif + + cmph_uint8 * g_i = (cmph_uint8 *) (g_is_ptr + data->k); + + for(i = 0; i < data->k; i++) + { + #if defined (__ia64) || defined (__x86_64__) + *g_is_ptr++ = (cmph_uint64)g_i; + #else + *g_is_ptr++ = (cmph_uint32)g_i; + #endif + // packing h1[i] + hash_state_pack(data->h1[i], g_i); + g_i += hash_state_packed_size(h1_type); + + // packing h2[i] + hash_state_pack(data->h2[i], g_i); + g_i += hash_state_packed_size(h2_type); + + // packing g_i + switch(data->algo) + { + case CMPH_FCH: + n = fch_calc_b(data->c, data->size[i]); + break; + case CMPH_BMZ8: + n = (cmph_uint32)ceil(data->c * data->size[i]); + break; + default: assert(0); + } + memcpy(g_i, data->g[i], sizeof(cmph_uint8)*n); + g_i += n; + + } + +} + +/** \fn cmph_uint32 brz_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 brz_packed_size(cmph_t *mphf) +{ + cmph_uint32 i; + cmph_uint32 size = 0; + brz_data_t *data = (brz_data_t *)mphf->data; + CMPH_HASH h0_type = hash_get_type(data->h0); + CMPH_HASH h1_type = hash_get_type(data->h1[0]); + CMPH_HASH h2_type = hash_get_type(data->h2[0]); + size = (cmph_uint32)(2*sizeof(CMPH_ALGO) + 3*sizeof(CMPH_HASH) + hash_state_packed_size(h0_type) + sizeof(cmph_uint32) + + sizeof(double) + sizeof(cmph_uint8)*data->k + sizeof(cmph_uint32)*data->k); + // pointers to g_is + #if defined (__ia64) || defined (__x86_64__) + size += (cmph_uint32) sizeof(cmph_uint64)*data->k; + #else + size += (cmph_uint32) sizeof(cmph_uint32)*data->k; + #endif + + size += hash_state_packed_size(h1_type) * data->k; + size += hash_state_packed_size(h2_type) * data->k; + + cmph_uint32 n = 0; + for(i = 0; i < data->k; i++) + { + switch(data->algo) + { + case CMPH_FCH: + n = fch_calc_b(data->c, data->size[i]); + break; + case CMPH_BMZ8: + n = (cmph_uint32)ceil(data->c * data->size[i]); + break; + default: assert(0); + } + size += n; + } + return size; +} + + + +static cmph_uint32 brz_bmz8_search_packed(cmph_uint32 *packed_mphf, const char *key, cmph_uint32 keylen, cmph_uint32 * fingerprint) +{ + register CMPH_HASH h0_type = *packed_mphf++; + register cmph_uint32 *h0_ptr = packed_mphf; + packed_mphf = (cmph_uint32 *)(((cmph_uint8 *)packed_mphf) + hash_state_packed_size(h0_type)); + + register cmph_uint32 k = *packed_mphf++; + + register double c = (double)(*((cmph_uint64*)packed_mphf)); + packed_mphf += 2; + + register CMPH_HASH h1_type = *packed_mphf++; + + register CMPH_HASH h2_type = *packed_mphf++; + + register cmph_uint8 * size = (cmph_uint8 *) packed_mphf; + packed_mphf = (cmph_uint32 *)(size + k); + + register cmph_uint32 * offset = packed_mphf; + packed_mphf += k; + + register cmph_uint32 h0; + + hash_vector_packed(h0_ptr, h0_type, key, keylen, fingerprint); + h0 = fingerprint[2] % k; + + register cmph_uint32 m = size[h0]; + register cmph_uint32 n = (cmph_uint32)ceil(c * m); + + #if defined (__ia64) || defined (__x86_64__) + register cmph_uint64 * g_is_ptr = (cmph_uint64 *)packed_mphf; + #else + register cmph_uint32 * g_is_ptr = packed_mphf; + #endif + + register cmph_uint8 * h1_ptr = (cmph_uint8 *) g_is_ptr[h0]; + + register cmph_uint8 * h2_ptr = h1_ptr + hash_state_packed_size(h1_type); + + register cmph_uint8 * g = h2_ptr + hash_state_packed_size(h2_type); + + register cmph_uint32 h1 = hash_packed(h1_ptr, h1_type, key, keylen) % n; + register cmph_uint32 h2 = hash_packed(h2_ptr, h2_type, key, keylen) % n; + + register cmph_uint8 mphf_bucket; + + if (h1 == h2 && ++h2 >= n) h2 = 0; + mphf_bucket = (cmph_uint8)(g[h1] + g[h2]); + DEBUGP("key: %s h1: %u h2: %u h0: %u\n", key, h1, h2, h0); + DEBUGP("Address: %u\n", mphf_bucket + offset[h0]); + return (mphf_bucket + offset[h0]); +} + +static cmph_uint32 brz_fch_search_packed(cmph_uint32 *packed_mphf, const char *key, cmph_uint32 keylen, cmph_uint32 * fingerprint) +{ + register CMPH_HASH h0_type = *packed_mphf++; + + register cmph_uint32 *h0_ptr = packed_mphf; + packed_mphf = (cmph_uint32 *)(((cmph_uint8 *)packed_mphf) + hash_state_packed_size(h0_type)); + + register cmph_uint32 k = *packed_mphf++; + + register double c = (double)(*((cmph_uint64*)packed_mphf)); + packed_mphf += 2; + + register CMPH_HASH h1_type = *packed_mphf++; + + register CMPH_HASH h2_type = *packed_mphf++; + + register cmph_uint8 * size = (cmph_uint8 *) packed_mphf; + packed_mphf = (cmph_uint32 *)(size + k); + + register cmph_uint32 * offset = packed_mphf; + packed_mphf += k; + + register cmph_uint32 h0; + + hash_vector_packed(h0_ptr, h0_type, key, keylen, fingerprint); + h0 = fingerprint[2] % k; + + register cmph_uint32 m = size[h0]; + register cmph_uint32 b = fch_calc_b(c, m); + register double p1 = fch_calc_p1(m); + register double p2 = fch_calc_p2(b); + + #if defined (__ia64) || defined (__x86_64__) + register cmph_uint64 * g_is_ptr = (cmph_uint64 *)packed_mphf; + #else + register cmph_uint32 * g_is_ptr = packed_mphf; + #endif + + register cmph_uint8 * h1_ptr = (cmph_uint8 *) g_is_ptr[h0]; + + register cmph_uint8 * h2_ptr = h1_ptr + hash_state_packed_size(h1_type); + + register cmph_uint8 * g = h2_ptr + hash_state_packed_size(h2_type); + + register cmph_uint32 h1 = hash_packed(h1_ptr, h1_type, key, keylen) % m; + register cmph_uint32 h2 = hash_packed(h2_ptr, h2_type, key, keylen) % m; + + register cmph_uint8 mphf_bucket = 0; + h1 = mixh10h11h12(b, p1, p2, h1); + mphf_bucket = (cmph_uint8)((h2 + g[h1]) % m); + return (mphf_bucket + offset[h0]); +} + +/** cmph_uint32 brz_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint32 brz_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen) +{ + register cmph_uint32 *ptr = (cmph_uint32 *)packed_mphf; + register CMPH_ALGO algo = *ptr++; + cmph_uint32 fingerprint[3]; + switch(algo) + { + case CMPH_FCH: + return brz_fch_search_packed(ptr, key, keylen, fingerprint); + case CMPH_BMZ8: + return brz_bmz8_search_packed(ptr, key, keylen, fingerprint); + default: assert(0); + } +} + diff --git a/cmph/brz.h b/cmph/brz.h new file mode 100644 index 000000000..ac07ed762 --- /dev/null +++ b/cmph/brz.h @@ -0,0 +1,47 @@ +#ifndef __CMPH_BRZ_H__ +#define __CMPH_BRZ_H__ + +#include "cmph.h" + +typedef struct __brz_data_t brz_data_t; +typedef struct __brz_config_data_t brz_config_data_t; + +brz_config_data_t *brz_config_new(); +void brz_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); +void brz_config_set_tmp_dir(cmph_config_t *mph, cmph_uint8 *tmp_dir); +void brz_config_set_mphf_fd(cmph_config_t *mph, FILE *mphf_fd); +void brz_config_set_b(cmph_config_t *mph, cmph_uint32 b); +void brz_config_set_algo(cmph_config_t *mph, CMPH_ALGO algo); +void brz_config_set_memory_availability(cmph_config_t *mph, cmph_uint32 memory_availability); +void brz_config_destroy(cmph_config_t *mph); +cmph_t *brz_new(cmph_config_t *mph, double c); + +void brz_load(FILE *f, cmph_t *mphf); +int brz_dump(cmph_t *mphf, FILE *f); +void brz_destroy(cmph_t *mphf); +cmph_uint32 brz_search(cmph_t *mphf, const char *key, cmph_uint32 keylen); + +/** \fn void brz_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void brz_pack(cmph_t *mphf, void *packed_mphf); + +/** \fn cmph_uint32 brz_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 brz_packed_size(cmph_t *mphf); + +/** cmph_uint32 brz_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint32 brz_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen); + +#endif diff --git a/cmph/brz_structs.h b/cmph/brz_structs.h new file mode 100755 index 000000000..b781107f9 --- /dev/null +++ b/cmph/brz_structs.h @@ -0,0 +1,39 @@ +#ifndef __CMPH_BRZ_STRUCTS_H__ +#define __CMPH_BRZ_STRUCTS_H__ + +#include "hash_state.h" + +struct __brz_data_t +{ + CMPH_ALGO algo; // CMPH algo for generating the MPHFs for the buckets (Just CMPH_FCH and CMPH_BMZ8) + cmph_uint32 m; // edges (words) count + double c; // constant c + cmph_uint8 *size; // size[i] stores the number of edges represented by g[i][...]. + cmph_uint32 *offset; // offset[i] stores the sum: size[0] + size[1] + ... size[i-1]. + cmph_uint8 **g; // g function. + cmph_uint32 k; // number of components + hash_state_t **h1; + hash_state_t **h2; + hash_state_t * h0; +}; + +struct __brz_config_data_t +{ + CMPH_HASH hashfuncs[3]; + CMPH_ALGO algo; // CMPH algo for generating the MPHFs for the buckets (Just CMPH_FCH and CMPH_BMZ8) + double c; // constant c + cmph_uint32 m; // edges (words) count + cmph_uint8 *size; // size[i] stores the number of edges represented by g[i][...]. + cmph_uint32 *offset; // offset[i] stores the sum: size[0] + size[1] + ... size[i-1]. + cmph_uint8 **g; // g function. + cmph_uint8 b; // parameter b. + cmph_uint32 k; // number of components + hash_state_t **h1; + hash_state_t **h2; + hash_state_t * h0; + cmph_uint32 memory_availability; + cmph_uint8 * tmp_dir; // temporary directory + FILE * mphf_fd; // mphf file +}; + +#endif diff --git a/cmph/buffer_entry.c b/cmph/buffer_entry.c new file mode 100644 index 000000000..7f82aae13 --- /dev/null +++ b/cmph/buffer_entry.c @@ -0,0 +1,103 @@ +#include "buffer_entry.h" +#include +#include +#include +#include + +struct __buffer_entry_t +{ + FILE *fd; + cmph_uint8 * buff; + cmph_uint32 capacity, // buffer entry capacity + nbytes, // buffer entry used bytes + pos; // current read position in buffer entry + cmph_uint8 eof; // flag to indicate end of file +}; + +buffer_entry_t * buffer_entry_new(cmph_uint32 capacity) +{ + buffer_entry_t *buff_entry = (buffer_entry_t *)malloc(sizeof(buffer_entry_t)); + assert(buff_entry); + buff_entry->fd = NULL; + buff_entry->buff = NULL; + buff_entry->capacity = capacity; + buff_entry->nbytes = capacity; + buff_entry->pos = capacity; + buff_entry->eof = 0; + return buff_entry; +} + +void buffer_entry_open(buffer_entry_t * buffer_entry, char * filename) +{ + buffer_entry->fd = fopen(filename, "rb"); +} + +void buffer_entry_set_capacity(buffer_entry_t * buffer_entry, cmph_uint32 capacity) +{ + buffer_entry->capacity = capacity; +} + + +cmph_uint32 buffer_entry_get_capacity(buffer_entry_t * buffer_entry) +{ + return buffer_entry->capacity; +} + +void buffer_entry_load(buffer_entry_t * buffer_entry) +{ + free(buffer_entry->buff); + buffer_entry->buff = (cmph_uint8 *)calloc((size_t)buffer_entry->capacity, sizeof(cmph_uint8)); + buffer_entry->nbytes = (cmph_uint32)fread(buffer_entry->buff, (size_t)1, (size_t)buffer_entry->capacity, buffer_entry->fd); + if (buffer_entry->nbytes != buffer_entry->capacity) buffer_entry->eof = 1; + buffer_entry->pos = 0; +} + +cmph_uint8 * buffer_entry_read_key(buffer_entry_t * buffer_entry, cmph_uint32 * keylen) +{ + cmph_uint8 * buf = NULL; + cmph_uint32 lacked_bytes = sizeof(*keylen); + cmph_uint32 copied_bytes = 0; + if(buffer_entry->eof && (buffer_entry->pos == buffer_entry->nbytes)) // end + { + free(buf); + return NULL; + } + if((buffer_entry->pos + lacked_bytes) > buffer_entry->nbytes) + { + copied_bytes = buffer_entry->nbytes - buffer_entry->pos; + lacked_bytes = (buffer_entry->pos + lacked_bytes) - buffer_entry->nbytes; + if (copied_bytes != 0) memcpy(keylen, buffer_entry->buff + buffer_entry->pos, (size_t)copied_bytes); + buffer_entry_load(buffer_entry); + } + memcpy(keylen + copied_bytes, buffer_entry->buff + buffer_entry->pos, (size_t)lacked_bytes); + buffer_entry->pos += lacked_bytes; + + lacked_bytes = *keylen; + copied_bytes = 0; + buf = (cmph_uint8 *)malloc(*keylen + sizeof(*keylen)); + memcpy(buf, keylen, sizeof(*keylen)); + if((buffer_entry->pos + lacked_bytes) > buffer_entry->nbytes) { + copied_bytes = buffer_entry->nbytes - buffer_entry->pos; + lacked_bytes = (buffer_entry->pos + lacked_bytes) - buffer_entry->nbytes; + if (copied_bytes != 0) { + memcpy(buf + sizeof(*keylen), buffer_entry->buff + buffer_entry->pos, (size_t)copied_bytes); + } + buffer_entry_load(buffer_entry); + } + memcpy(buf+sizeof(*keylen)+copied_bytes, buffer_entry->buff + buffer_entry->pos, (size_t)lacked_bytes); + buffer_entry->pos += lacked_bytes; + return buf; +} + +void buffer_entry_destroy(buffer_entry_t * buffer_entry) +{ + fclose(buffer_entry->fd); + buffer_entry->fd = NULL; + free(buffer_entry->buff); + buffer_entry->buff = NULL; + buffer_entry->capacity = 0; + buffer_entry->nbytes = 0; + buffer_entry->pos = 0; + buffer_entry->eof = 0; + free(buffer_entry); +} diff --git a/cmph/buffer_entry.h b/cmph/buffer_entry.h new file mode 100644 index 000000000..62102baba --- /dev/null +++ b/cmph/buffer_entry.h @@ -0,0 +1,14 @@ +#ifndef __CMPH_BUFFER_ENTRY_H__ +#define __CMPH_BUFFER_ENTRY_H__ + +#include "cmph_types.h" +#include +typedef struct __buffer_entry_t buffer_entry_t; + +buffer_entry_t * buffer_entry_new(cmph_uint32 capacity); +void buffer_entry_set_capacity(buffer_entry_t * buffer_entry, cmph_uint32 capacity); +cmph_uint32 buffer_entry_get_capacity(buffer_entry_t * buffer_entry); +void buffer_entry_open(buffer_entry_t * buffer_entry, char * filename); +cmph_uint8 * buffer_entry_read_key(buffer_entry_t * buffer_entry, cmph_uint32 * keylen); +void buffer_entry_destroy(buffer_entry_t * buffer_entry); +#endif diff --git a/cmph/buffer_manage.c b/cmph/buffer_manage.c new file mode 100644 index 000000000..fdefc620d --- /dev/null +++ b/cmph/buffer_manage.c @@ -0,0 +1,66 @@ +#include "buffer_manage.h" +#include "buffer_entry.h" +#include +#include +#include +struct __buffer_manage_t +{ + cmph_uint32 memory_avail; // memory available + buffer_entry_t ** buffer_entries; // buffer entries to be managed + cmph_uint32 nentries; // number of entries to be managed + cmph_uint32 *memory_avail_list; // memory available list + int pos_avail_list; // current position in memory available list +}; + +buffer_manage_t * buffer_manage_new(cmph_uint32 memory_avail, cmph_uint32 nentries) +{ + cmph_uint32 memory_avail_entry, i; + buffer_manage_t *buff_manage = (buffer_manage_t *)malloc(sizeof(buffer_manage_t)); + assert(buff_manage); + buff_manage->memory_avail = memory_avail; + buff_manage->buffer_entries = (buffer_entry_t **)calloc((size_t)nentries, sizeof(buffer_entry_t *)); + buff_manage->memory_avail_list = (cmph_uint32 *)calloc((size_t)nentries, sizeof(cmph_uint32)); + buff_manage->pos_avail_list = -1; + buff_manage->nentries = nentries; + memory_avail_entry = buff_manage->memory_avail/buff_manage->nentries + 1; + for(i = 0; i < buff_manage->nentries; i++) + { + buff_manage->buffer_entries[i] = buffer_entry_new(memory_avail_entry); + } + return buff_manage; +} + +void buffer_manage_open(buffer_manage_t * buffer_manage, cmph_uint32 index, char * filename) +{ + buffer_entry_open(buffer_manage->buffer_entries[index], filename); +} + +cmph_uint8 * buffer_manage_read_key(buffer_manage_t * buffer_manage, cmph_uint32 index) +{ + cmph_uint8 * key = NULL; + if (buffer_manage->pos_avail_list >= 0 ) // recovering memory + { + cmph_uint32 new_capacity = buffer_entry_get_capacity(buffer_manage->buffer_entries[index]) + buffer_manage->memory_avail_list[(buffer_manage->pos_avail_list)--]; + buffer_entry_set_capacity(buffer_manage->buffer_entries[index], new_capacity); + //fprintf(stderr, "recovering memory\n"); + } + key = buffer_entry_read_key(buffer_manage->buffer_entries[index]); + if (key == NULL) // storing memory to be recovered + { + buffer_manage->memory_avail_list[++(buffer_manage->pos_avail_list)] = buffer_entry_get_capacity(buffer_manage->buffer_entries[index]); + //fprintf(stderr, "storing memory to be recovered\n"); + } + return key; +} + +void buffer_manage_destroy(buffer_manage_t * buffer_manage) +{ + cmph_uint32 i; + for(i = 0; i < buffer_manage->nentries; i++) + { + buffer_entry_destroy(buffer_manage->buffer_entries[i]); + } + free(buffer_manage->memory_avail_list); + free(buffer_manage->buffer_entries); + free(buffer_manage); +} diff --git a/cmph/buffer_manage.h b/cmph/buffer_manage.h new file mode 100644 index 000000000..8c66cffc1 --- /dev/null +++ b/cmph/buffer_manage.h @@ -0,0 +1,12 @@ +#ifndef __CMPH_BUFFER_MANAGE_H__ +#define __CMPH_BUFFER_MANAGE_H__ + +#include "cmph_types.h" +#include +typedef struct __buffer_manage_t buffer_manage_t; + +buffer_manage_t * buffer_manage_new(cmph_uint32 memory_avail, cmph_uint32 nentries); +void buffer_manage_open(buffer_manage_t * buffer_manage, cmph_uint32 index, char * filename); +cmph_uint8 * buffer_manage_read_key(buffer_manage_t * buffer_manage, cmph_uint32 index); +void buffer_manage_destroy(buffer_manage_t * buffer_manage); +#endif diff --git a/cmph/buffer_manager.c b/cmph/buffer_manager.c new file mode 100644 index 000000000..5a051e2f0 --- /dev/null +++ b/cmph/buffer_manager.c @@ -0,0 +1,64 @@ +#include "buffer_manager.h" +#include "buffer_entry.h" +#include +#include +#include +struct __buffer_manager_t +{ + cmph_uint32 memory_avail; // memory available + buffer_entry_t ** buffer_entries; // buffer entries to be managed + cmph_uint32 nentries; // number of entries to be managed + cmph_uint32 *memory_avail_list; // memory available list + int pos_avail_list; // current position in memory available list +}; + +buffer_manager_t * buffer_manager_new(cmph_uint32 memory_avail, cmph_uint32 nentries) +{ + cmph_uint32 memory_avail_entry, i; + buffer_manager_t *buff_manager = (buffer_manager_t *)malloc(sizeof(buffer_manager_t)); + assert(buff_manager); + buff_manager->memory_avail = memory_avail; + buff_manager->buffer_entries = (buffer_entry_t **)calloc((size_t)nentries, sizeof(buffer_entry_t *)); + buff_manager->memory_avail_list = (cmph_uint32 *)calloc((size_t)nentries, sizeof(cmph_uint32)); + buff_manager->pos_avail_list = -1; + buff_manager->nentries = nentries; + memory_avail_entry = buff_manager->memory_avail/buff_manager->nentries + 1; + for(i = 0; i < buff_manager->nentries; i++) + { + buff_manager->buffer_entries[i] = buffer_entry_new(memory_avail_entry); + } + return buff_manager; +} + +void buffer_manager_open(buffer_manager_t * buffer_manager, cmph_uint32 index, char * filename) +{ + buffer_entry_open(buffer_manager->buffer_entries[index], filename); +} + +cmph_uint8 * buffer_manager_read_key(buffer_manager_t * buffer_manager, cmph_uint32 index, cmph_uint32 * keylen) +{ + cmph_uint8 * key = NULL; + if (buffer_manager->pos_avail_list >= 0 ) // recovering memory + { + cmph_uint32 new_capacity = buffer_entry_get_capacity(buffer_manager->buffer_entries[index]) + buffer_manager->memory_avail_list[(buffer_manager->pos_avail_list)--]; + buffer_entry_set_capacity(buffer_manager->buffer_entries[index], new_capacity); + } + key = buffer_entry_read_key(buffer_manager->buffer_entries[index], keylen); + if (key == NULL) // storing memory to be recovered + { + buffer_manager->memory_avail_list[++(buffer_manager->pos_avail_list)] = buffer_entry_get_capacity(buffer_manager->buffer_entries[index]); + } + return key; +} + +void buffer_manager_destroy(buffer_manager_t * buffer_manager) +{ + cmph_uint32 i; + for(i = 0; i < buffer_manager->nentries; i++) + { + buffer_entry_destroy(buffer_manager->buffer_entries[i]); + } + free(buffer_manager->memory_avail_list); + free(buffer_manager->buffer_entries); + free(buffer_manager); +} diff --git a/cmph/buffer_manager.h b/cmph/buffer_manager.h new file mode 100644 index 000000000..af99c20f6 --- /dev/null +++ b/cmph/buffer_manager.h @@ -0,0 +1,12 @@ +#ifndef __CMPH_BUFFER_MANAGE_H__ +#define __CMPH_BUFFER_MANAGE_H__ + +#include "cmph_types.h" +#include +typedef struct __buffer_manager_t buffer_manager_t; + +buffer_manager_t * buffer_manager_new(cmph_uint32 memory_avail, cmph_uint32 nentries); +void buffer_manager_open(buffer_manager_t * buffer_manager, cmph_uint32 index, char * filename); +cmph_uint8 * buffer_manager_read_key(buffer_manager_t * buffer_manager, cmph_uint32 index, cmph_uint32 * keylen); +void buffer_manager_destroy(buffer_manager_t * buffer_manager); +#endif diff --git a/cmph/chd.c b/cmph/chd.c new file mode 100644 index 000000000..7fb3b8bb8 --- /dev/null +++ b/cmph/chd.c @@ -0,0 +1,271 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "cmph_structs.h" +#include "chd_structs.h" +#include "chd.h" +#include "bitbool.h" +//#define DEBUG +#include "debug.h" + +chd_config_data_t *chd_config_new(cmph_config_t *mph) +{ + cmph_io_adapter_t *key_source = mph->key_source; + chd_config_data_t *chd; + chd = (chd_config_data_t *)malloc(sizeof(chd_config_data_t)); + assert(chd); + memset(chd, 0, sizeof(chd_config_data_t)); + + chd->chd_ph = cmph_config_new(key_source); + cmph_config_set_algo(chd->chd_ph, CMPH_CHD_PH); + + return chd; +} + +void chd_config_destroy(cmph_config_t *mph) +{ + chd_config_data_t *data = (chd_config_data_t *) mph->data; + DEBUGP("Destroying algorithm dependent data\n"); + if(data->chd_ph) + { + cmph_config_destroy(data->chd_ph); + data->chd_ph = NULL; + } + free(data); +} + + +void chd_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs) +{ + chd_config_data_t *data = (chd_config_data_t *) mph->data; + cmph_config_set_hashfuncs(data->chd_ph, hashfuncs); +} + + +void chd_config_set_b(cmph_config_t *mph, cmph_uint32 keys_per_bucket) +{ + chd_config_data_t *data = (chd_config_data_t *) mph->data; + cmph_config_set_b(data->chd_ph, keys_per_bucket); +} + + +void chd_config_set_keys_per_bin(cmph_config_t *mph, cmph_uint32 keys_per_bin) +{ + chd_config_data_t *data = (chd_config_data_t *) mph->data; + cmph_config_set_keys_per_bin(data->chd_ph, keys_per_bin); +} + + +cmph_t *chd_new(cmph_config_t *mph, double c) +{ + cmph_t *mphf = NULL; + chd_data_t *chdf = NULL; + chd_config_data_t *chd = (chd_config_data_t *)mph->data; + chd_ph_config_data_t * chd_ph = (chd_ph_config_data_t *)chd->chd_ph->data; + compressed_rank_t cr; + + register cmph_t * chd_phf = NULL; + register cmph_uint32 packed_chd_phf_size = 0; + cmph_uint8 * packed_chd_phf = NULL; + + register cmph_uint32 packed_cr_size = 0; + cmph_uint8 * packed_cr = NULL; + + register cmph_uint32 i, idx, nkeys, nvals, nbins; + cmph_uint32 * vals_table = NULL; + register cmph_uint32 * occup_table = NULL; + #ifdef CMPH_TIMING + double construction_time_begin = 0.0; + double construction_time = 0.0; + ELAPSED_TIME_IN_SECONDS(&construction_time_begin); + #endif + + cmph_config_set_verbosity(chd->chd_ph, mph->verbosity); + cmph_config_set_graphsize(chd->chd_ph, c); + + if (mph->verbosity) + { + fprintf(stderr, "Generating a CHD_PH perfect hash function with a load factor equal to %.3f\n", c); + } + + chd_phf = cmph_new(chd->chd_ph); + + if(chd_phf == NULL) + { + return NULL; + } + + packed_chd_phf_size = cmph_packed_size(chd_phf); + DEBUGP("packed_chd_phf_size = %u\n", packed_chd_phf_size); + + /* Make sure that we have enough space to pack the mphf. */ + packed_chd_phf = calloc((size_t)packed_chd_phf_size,(size_t)1); + + /* Pack the mphf. */ + cmph_pack(chd_phf, packed_chd_phf); + + cmph_destroy(chd_phf); + + + if (mph->verbosity) + { + fprintf(stderr, "Compressing the range of the resulting CHD_PH perfect hash function\n"); + } + + compressed_rank_init(&cr); + nbins = chd_ph->n; + nkeys = chd_ph->m; + nvals = nbins - nkeys; + + vals_table = (cmph_uint32 *)calloc(nvals, sizeof(cmph_uint32)); + occup_table = (cmph_uint32 *)chd_ph->occup_table; + + for(i = 0, idx = 0; i < nbins; i++) + { + if(!GETBIT32(occup_table, i)) + { + vals_table[idx++] = i; + } + } + + compressed_rank_generate(&cr, vals_table, nvals); + free(vals_table); + + packed_cr_size = compressed_rank_packed_size(&cr); + packed_cr = (cmph_uint8 *) calloc(packed_cr_size, sizeof(cmph_uint8)); + compressed_rank_pack(&cr, packed_cr); + compressed_rank_destroy(&cr); + + mphf = (cmph_t *)malloc(sizeof(cmph_t)); + mphf->algo = mph->algo; + chdf = (chd_data_t *)malloc(sizeof(chd_data_t)); + + chdf->packed_cr = packed_cr; + packed_cr = NULL; //transfer memory ownership + + chdf->packed_chd_phf = packed_chd_phf; + packed_chd_phf = NULL; //transfer memory ownership + + chdf->packed_chd_phf_size = packed_chd_phf_size; + chdf->packed_cr_size = packed_cr_size; + + mphf->data = chdf; + mphf->size = nkeys; + + DEBUGP("Successfully generated minimal perfect hash\n"); + if (mph->verbosity) + { + fprintf(stderr, "Successfully generated minimal perfect hash function\n"); + } + #ifdef CMPH_TIMING + ELAPSED_TIME_IN_SECONDS(&construction_time); + register cmph_uint32 space_usage = chd_packed_size(mphf)*8; + construction_time = construction_time - construction_time_begin; + fprintf(stdout, "%u\t%.2f\t%u\t%.4f\t%.4f\n", nkeys, c, chd_ph->keys_per_bucket, construction_time, space_usage/(double)nkeys); + #endif + + return mphf; +} + +void chd_load(FILE *fd, cmph_t *mphf) +{ + register size_t nbytes; + chd_data_t *chd = (chd_data_t *)malloc(sizeof(chd_data_t)); + + DEBUGP("Loading chd mphf\n"); + mphf->data = chd; + + nbytes = fread(&chd->packed_chd_phf_size, sizeof(cmph_uint32), (size_t)1, fd); + DEBUGP("Loading CHD_PH perfect hash function with %u bytes to disk\n", chd->packed_chd_phf_size); + chd->packed_chd_phf = (cmph_uint8 *) calloc((size_t)chd->packed_chd_phf_size,(size_t)1); + nbytes = fread(chd->packed_chd_phf, chd->packed_chd_phf_size, (size_t)1, fd); + + nbytes = fread(&chd->packed_cr_size, sizeof(cmph_uint32), (size_t)1, fd); + DEBUGP("Loading Compressed rank structure, which has %u bytes\n", chd->packed_cr_size); + chd->packed_cr = (cmph_uint8 *) calloc((size_t)chd->packed_cr_size, (size_t)1); + nbytes = fread(chd->packed_cr, chd->packed_cr_size, (size_t)1, fd); +} + +int chd_dump(cmph_t *mphf, FILE *fd) +{ + register size_t nbytes; + chd_data_t *data = (chd_data_t *)mphf->data; + + __cmph_dump(mphf, fd); + // Dumping CHD_PH perfect hash function + + DEBUGP("Dumping CHD_PH perfect hash function with %u bytes to disk\n", data->packed_chd_phf_size); + nbytes = fwrite(&data->packed_chd_phf_size, sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(data->packed_chd_phf, data->packed_chd_phf_size, (size_t)1, fd); + + DEBUGP("Dumping compressed rank structure with %u bytes to disk\n", buflen); + nbytes = fwrite(&data->packed_cr_size, sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(data->packed_cr, data->packed_cr_size, (size_t)1, fd); + + return 1; +} + +void chd_destroy(cmph_t *mphf) +{ + chd_data_t *data = (chd_data_t *)mphf->data; + free(data->packed_chd_phf); + free(data->packed_cr); + free(data); + free(mphf); +} + +static inline cmph_uint32 _chd_search(void * packed_chd_phf, void * packed_cr, const char *key, cmph_uint32 keylen) +{ + register cmph_uint32 bin_idx = cmph_search_packed(packed_chd_phf, key, keylen); + register cmph_uint32 rank = compressed_rank_query_packed(packed_cr, bin_idx); + return bin_idx - rank; +} + +cmph_uint32 chd_search(cmph_t *mphf, const char *key, cmph_uint32 keylen) +{ + register chd_data_t * chd = mphf->data; + return _chd_search(chd->packed_chd_phf, chd->packed_cr, key, keylen); +} + +void chd_pack(cmph_t *mphf, void *packed_mphf) +{ + chd_data_t *data = (chd_data_t *)mphf->data; + cmph_uint32 * ptr = packed_mphf; + cmph_uint8 * ptr8; + + // packing packed_cr_size and packed_cr + *ptr = data->packed_cr_size; + ptr8 = (cmph_uint8 *) (ptr + 1); + + memcpy(ptr8, data->packed_cr, data->packed_cr_size); + ptr8 += data->packed_cr_size; + + ptr = (cmph_uint32 *) ptr8; + *ptr = data->packed_chd_phf_size; + + ptr8 = (cmph_uint8 *) (ptr + 1); + memcpy(ptr8, data->packed_chd_phf, data->packed_chd_phf_size); +} + +cmph_uint32 chd_packed_size(cmph_t *mphf) +{ + register chd_data_t *data = (chd_data_t *)mphf->data; + return (cmph_uint32)(sizeof(CMPH_ALGO) + 2*sizeof(cmph_uint32) + data->packed_cr_size + data->packed_chd_phf_size); + +} + +cmph_uint32 chd_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen) +{ + + register cmph_uint32 * ptr = packed_mphf; + register cmph_uint32 packed_cr_size = *ptr++; + register cmph_uint8 * packed_chd_phf = ((cmph_uint8 *) ptr) + packed_cr_size + sizeof(cmph_uint32); + return _chd_search(packed_chd_phf, ptr, key, keylen); +} + + diff --git a/cmph/chd.h b/cmph/chd.h new file mode 100644 index 000000000..e829df816 --- /dev/null +++ b/cmph/chd.h @@ -0,0 +1,59 @@ +#ifndef _CMPH_CHD_H__ +#define _CMPH_CHD_H__ + +#include "cmph.h" + +typedef struct __chd_data_t chd_data_t; +typedef struct __chd_config_data_t chd_config_data_t; + +/* Config API */ +chd_config_data_t *chd_config_new(cmph_config_t * mph); +void chd_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); + +/** \fn void chd_config_set_keys_per_bin(cmph_config_t *mph, cmph_uint32 keys_per_bin); + * \brief Allows to set the number of keys per bin. + * \param mph pointer to the configuration structure + * \param keys_per_bin value for the number of keys per bin + */ +void chd_config_set_keys_per_bin(cmph_config_t *mph, cmph_uint32 keys_per_bin); + +/** \fn void chd_config_set_b(cmph_config_t *mph, cmph_uint32 keys_per_bucket); + * \brief Allows to set the number of keys per bucket. + * \param mph pointer to the configuration structure + * \param keys_per_bucket value for the number of keys per bucket + */ +void chd_config_set_b(cmph_config_t *mph, cmph_uint32 keys_per_bucket); +void chd_config_destroy(cmph_config_t *mph); + + +/* Chd algorithm API */ +cmph_t *chd_new(cmph_config_t *mph, double c); +void chd_load(FILE *fd, cmph_t *mphf); +int chd_dump(cmph_t *mphf, FILE *fd); +void chd_destroy(cmph_t *mphf); +cmph_uint32 chd_search(cmph_t *mphf, const char *key, cmph_uint32 keylen); + +/** \fn void chd_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void chd_pack(cmph_t *mphf, void *packed_mphf); + +/** \fn cmph_uint32 chd_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 chd_packed_size(cmph_t *mphf); + +/** cmph_uint32 chd_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint32 chd_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen); + +#endif diff --git a/cmph/chd_ph.c b/cmph/chd_ph.c new file mode 100644 index 000000000..b34415b93 --- /dev/null +++ b/cmph/chd_ph.c @@ -0,0 +1,988 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "cmph_structs.h" +#include "chd_structs_ph.h" +#include "chd_ph.h" +#include"miller_rabin.h" +#include"bitbool.h" + + +//#define DEBUG +#include "debug.h" + +// NO_ELEMENT is equivalent to null pointer +#ifndef NO_ELEMENT +#define NO_ELEMENT UINT_MAX +#endif + +// struct used to represent items at mapping, ordering and searching phases +struct _chd_ph_item_t +{ + cmph_uint32 f; + cmph_uint32 h; +}; +typedef struct _chd_ph_item_t chd_ph_item_t; + +// struct to represent the items at mapping phase only. +struct _chd_ph_map_item_t +{ + cmph_uint32 f; + cmph_uint32 h; + cmph_uint32 bucket_num; +}; +typedef struct _chd_ph_map_item_t chd_ph_map_item_t; + +// struct to represent a bucket +struct _chd_ph_bucket_t +{ + cmph_uint32 items_list; // offset + union + { + cmph_uint32 size; + cmph_uint32 bucket_id; + }; +}; + +typedef struct _chd_ph_bucket_t chd_ph_bucket_t; + +struct _chd_ph_sorted_list_t +{ + cmph_uint32 buckets_list; + cmph_uint32 size; +}; + +typedef struct _chd_ph_sorted_list_t chd_ph_sorted_list_t; + + +static inline chd_ph_bucket_t * chd_ph_bucket_new(cmph_uint32 nbuckets); +static inline void chd_ph_bucket_clean(chd_ph_bucket_t * buckets, cmph_uint32 nbuckets); +static inline void chd_ph_bucket_destroy(chd_ph_bucket_t * buckets); + +chd_ph_bucket_t * chd_ph_bucket_new(cmph_uint32 nbuckets) +{ + chd_ph_bucket_t * buckets = (chd_ph_bucket_t *) calloc(nbuckets, sizeof(chd_ph_bucket_t)); + return buckets; +} + +void chd_ph_bucket_clean(chd_ph_bucket_t * buckets, cmph_uint32 nbuckets) +{ + register cmph_uint32 i = 0; + assert(buckets); + for(i = 0; i < nbuckets; i++) + buckets[i].size = 0; +} +cmph_uint8 chd_ph_bucket_insert(chd_ph_bucket_t * buckets,chd_ph_map_item_t * map_items, chd_ph_item_t * items, + cmph_uint32 nbuckets,cmph_uint32 item_idx) +{ + register cmph_uint32 i = 0; + register chd_ph_item_t * tmp_item; + register chd_ph_map_item_t * tmp_map_item = map_items + item_idx; + register chd_ph_bucket_t * bucket = buckets + tmp_map_item->bucket_num; + tmp_item = items + bucket->items_list; + + for(i = 0; i < bucket->size; i++) + { + if(tmp_item->f == tmp_map_item->f && tmp_item->h == tmp_map_item->h) + { + DEBUGP("Item not added\n"); + return 0; + }; + tmp_item++; + }; + tmp_item->f = tmp_map_item->f; + tmp_item->h = tmp_map_item->h; + bucket->size++; + return 1; +}; +void chd_ph_bucket_destroy(chd_ph_bucket_t * buckets) +{ + free(buckets); +} + +static inline cmph_uint8 chd_ph_mapping(cmph_config_t *mph, chd_ph_bucket_t * buckets, chd_ph_item_t * items, + cmph_uint32 *max_bucket_size); + +static chd_ph_sorted_list_t * chd_ph_ordering(chd_ph_bucket_t ** _buckets,chd_ph_item_t ** items, + cmph_uint32 nbuckets,cmph_uint32 nitems, cmph_uint32 max_bucket_size); + +static cmph_uint8 chd_ph_searching(chd_ph_config_data_t *chd_ph, chd_ph_bucket_t *buckets, chd_ph_item_t *items , + cmph_uint32 max_bucket_size, chd_ph_sorted_list_t *sorted_lists, cmph_uint32 max_probes, cmph_uint32 * disp_table); + +static inline double chd_ph_space_lower_bound(cmph_uint32 _n, cmph_uint32 _r) +{ + double r = _r, n = _n; + return (1 + (r/n - 1.0 + 1.0/(2.0*n))*log(1 - n/r))/log(2); +}; + +/* computes the entropy of non empty buckets.*/ +static inline double chd_ph_get_entropy(cmph_uint32 * disp_table, cmph_uint32 n, cmph_uint32 max_probes) +{ + register cmph_uint32 * probe_counts = (cmph_uint32 *) calloc(max_probes, sizeof(cmph_uint32)); + register cmph_uint32 i; + register double entropy = 0; + + for(i = 0; i < n; i++) + { + probe_counts[disp_table[i]]++; + }; + + for(i = 0; i < max_probes; i++) + { + if(probe_counts[i] > 0) + entropy -= probe_counts[i]*log((double)probe_counts[i]/(double)n)/log(2); + }; + free(probe_counts); + return entropy; +}; + +chd_ph_config_data_t *chd_ph_config_new() +{ + chd_ph_config_data_t *chd_ph; + chd_ph = (chd_ph_config_data_t *)malloc(sizeof(chd_ph_config_data_t)); + assert(chd_ph); + memset(chd_ph, 0, sizeof(chd_ph_config_data_t)); + + chd_ph->hashfunc = CMPH_HASH_JENKINS; + chd_ph->cs = NULL; + chd_ph->nbuckets = 0; + chd_ph->n = 0; + chd_ph->hl = NULL; + + chd_ph->m = 0; + chd_ph->use_h = 1; + chd_ph->keys_per_bin = 1; + chd_ph->keys_per_bucket = 4; + chd_ph->occup_table = 0; + + return chd_ph; +} + +void chd_ph_config_destroy(cmph_config_t *mph) +{ + chd_ph_config_data_t *data = (chd_ph_config_data_t *) mph->data; + DEBUGP("Destroying algorithm dependent data\n"); + if(data->occup_table) + { + free(data->occup_table); + data->occup_table = NULL; + } + free(data); +} + + +void chd_ph_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs) +{ + chd_ph_config_data_t *chd_ph = (chd_ph_config_data_t *)mph->data; + CMPH_HASH *hashptr = hashfuncs; + cmph_uint32 i = 0; + while(*hashptr != CMPH_HASH_COUNT) + { + if (i >= 1) break; //chd_ph only uses one linear hash function + chd_ph->hashfunc = *hashptr; + ++i, ++hashptr; + } +} + + +void chd_ph_config_set_b(cmph_config_t *mph, cmph_uint32 keys_per_bucket) +{ + assert(mph); + chd_ph_config_data_t *chd_ph = (chd_ph_config_data_t *)mph->data; + if(keys_per_bucket < 1 || keys_per_bucket >= 15) + { + keys_per_bucket = 4; + } + chd_ph->keys_per_bucket = keys_per_bucket; +} + + +void chd_ph_config_set_keys_per_bin(cmph_config_t *mph, cmph_uint32 keys_per_bin) +{ + assert(mph); + chd_ph_config_data_t *chd_ph = (chd_ph_config_data_t *)mph->data; + if(keys_per_bin <= 1 || keys_per_bin >= 128) + { + keys_per_bin = 1; + } + chd_ph->keys_per_bin = keys_per_bin; +} + +cmph_uint8 chd_ph_mapping(cmph_config_t *mph, chd_ph_bucket_t * buckets, chd_ph_item_t * items, cmph_uint32 *max_bucket_size) +{ + register cmph_uint32 i = 0, g = 0; + cmph_uint32 hl[3]; + chd_ph_config_data_t *chd_ph = (chd_ph_config_data_t *)mph->data; + char * key = NULL; + cmph_uint32 keylen = 0; + chd_ph_map_item_t * map_item; + chd_ph_map_item_t * map_items = malloc(chd_ph->m*sizeof(chd_ph_map_item_t)); + register cmph_uint32 mapping_iterations = 1000; + *max_bucket_size = 0; + while(1) + { + mapping_iterations--; + if (chd_ph->hl) hash_state_destroy(chd_ph->hl); + chd_ph->hl = hash_state_new(chd_ph->hashfunc, chd_ph->m); + + chd_ph_bucket_clean(buckets, chd_ph->nbuckets); + + mph->key_source->rewind(mph->key_source->data); + + for(i = 0; i < chd_ph->m; i++) + { + mph->key_source->read(mph->key_source->data, &key, &keylen); + hash_vector(chd_ph->hl, key, keylen, hl); + + map_item = (map_items + i); + + g = hl[0] % chd_ph->nbuckets; + map_item->f = hl[1] % chd_ph->n; + map_item->h = hl[2] % (chd_ph->n - 1) + 1; + map_item->bucket_num=g; + mph->key_source->dispose(mph->key_source->data, key, keylen); +// if(buckets[g].size == (chd_ph->keys_per_bucket << 2)) +// { +// DEBUGP("BUCKET = %u -- SIZE = %u -- MAXIMUM SIZE = %u\n", g, buckets[g].size, (chd_ph->keys_per_bucket << 2)); +// goto error; +// } + buckets[g].size++; + if(buckets[g].size > *max_bucket_size) + { + *max_bucket_size = buckets[g].size; + } + } + buckets[0].items_list = 0; + for(i = 1; i < chd_ph->nbuckets; i++) + { + buckets[i].items_list = buckets[i-1].items_list + buckets[i - 1].size; + buckets[i - 1].size = 0; + }; + buckets[i - 1].size = 0; + for(i = 0; i < chd_ph->m; i++) + { + map_item = (map_items + i); + if(!chd_ph_bucket_insert(buckets, map_items, items, chd_ph->nbuckets, i)) + break; + } + if(i == chd_ph->m) + { + free(map_items); + return 1; // SUCCESS + } + + if(mapping_iterations == 0) + { + goto error; + } + } +error: + free(map_items); + hash_state_destroy(chd_ph->hl); + chd_ph->hl = NULL; + return 0; // FAILURE +} + +chd_ph_sorted_list_t * chd_ph_ordering(chd_ph_bucket_t ** _buckets, chd_ph_item_t ** _items, + cmph_uint32 nbuckets, cmph_uint32 nitems, cmph_uint32 max_bucket_size) +{ + chd_ph_sorted_list_t * sorted_lists = (chd_ph_sorted_list_t *) calloc(max_bucket_size + 1, sizeof(chd_ph_sorted_list_t)); + + chd_ph_bucket_t * input_buckets = (*_buckets); + chd_ph_bucket_t * output_buckets; + chd_ph_item_t * input_items = (*_items); + chd_ph_item_t * output_items; + register cmph_uint32 i, j, bucket_size, position, position2; +// cmph_uint32 non_empty_buckets; + DEBUGP("MAX BUCKET SIZE = %u\n", max_bucket_size); + // Determine size of each list of buckets + for(i = 0; i < nbuckets; i++) + { + bucket_size = input_buckets[i].size; + if(bucket_size == 0) + continue; + sorted_lists[bucket_size].size++; + }; + sorted_lists[1].buckets_list = 0; + // Determine final position of list of buckets into the contiguous array that will store all the buckets + for(i = 2; i <= max_bucket_size; i++) + { + sorted_lists[i].buckets_list = sorted_lists[i-1].buckets_list + sorted_lists[i-1].size; + sorted_lists[i-1].size = 0; + }; + sorted_lists[i-1].size = 0; + // Store the buckets in a new array which is sorted by bucket sizes + output_buckets = calloc(nbuckets, sizeof(chd_ph_bucket_t)); // everything is initialized with zero +// non_empty_buckets = nbuckets; + + for(i = 0; i < nbuckets; i++) + { + bucket_size = input_buckets[i].size; + if(bucket_size == 0) + { +// non_empty_buckets--; + continue; + }; + position = sorted_lists[bucket_size].buckets_list + sorted_lists[bucket_size].size; + output_buckets[position].bucket_id = i; + output_buckets[position].items_list = input_buckets[i].items_list; + sorted_lists[bucket_size].size++; + }; +/* for(i = non_empty_buckets; i < nbuckets; i++) + output_buckets[i].size=0;*/ + // Return the buckets sorted in new order and free the old buckets sorted in old order + free(input_buckets); + (*_buckets) = output_buckets; + + + // Store the items according to the new order of buckets. + output_items = (chd_ph_item_t*)calloc(nitems, sizeof(chd_ph_item_t)); + position = 0; + i = 0; + for(bucket_size = 1; bucket_size <= max_bucket_size; bucket_size++) + { + for(i = sorted_lists[bucket_size].buckets_list; i < sorted_lists[bucket_size].size + sorted_lists[bucket_size].buckets_list; i++) + { + position2 = output_buckets[i].items_list; + output_buckets[i].items_list = position; + for(j = 0; j < bucket_size; j++) + { + output_items[position].f = input_items[position2].f; + output_items[position].h = input_items[position2].h; + position++; + position2++; + }; + }; + }; + //Return the items sorted in new order and free the old items sorted in old order + free(input_items); + (*_items) = output_items; + return sorted_lists; +}; + +static inline cmph_uint8 place_bucket_probe(chd_ph_config_data_t *chd_ph, chd_ph_bucket_t *buckets, + chd_ph_item_t *items, cmph_uint32 probe0_num, cmph_uint32 probe1_num, + cmph_uint32 bucket_num, cmph_uint32 size) +{ + register cmph_uint32 i; + register chd_ph_item_t * item; + register cmph_uint32 position; + + item = items + buckets[bucket_num].items_list; + // try place bucket with probe_num + if(chd_ph->keys_per_bin > 1) + { + for(i = 0; i < size; i++) // placement + { + position = (cmph_uint32)((item->f + ((cmph_uint64)item->h)*probe0_num + probe1_num) % chd_ph->n); + if(chd_ph->occup_table[position] >= chd_ph->keys_per_bin) + { + break; + } + (chd_ph->occup_table[position])++; + item++; + }; + } else + { + for(i = 0; i < size; i++) // placement + { + position = (cmph_uint32)((item->f + ((cmph_uint64)item->h)*probe0_num + probe1_num) % chd_ph->n); + if(GETBIT32(((cmph_uint32 *)chd_ph->occup_table), position)) + { + break; + } + SETBIT32(((cmph_uint32*)chd_ph->occup_table), position); + item++; + }; + }; + if(i != size) // Undo the placement + { + item = items + buckets[bucket_num].items_list; + if(chd_ph->keys_per_bin > 1) + { + while(1) + { + if(i == 0) + { + break; + } + position = (cmph_uint32)((item->f + ((cmph_uint64 )item->h) * probe0_num + probe1_num) % chd_ph->n); + (chd_ph->occup_table[position])--; + item++; + i--; + }; + } else + { + while(1) + { + if(i == 0) + { + break; + } + position = (cmph_uint32)((item->f + ((cmph_uint64 )item->h) * probe0_num + probe1_num) % chd_ph->n); + UNSETBIT32(((cmph_uint32*)chd_ph->occup_table), position); + +// ([position/32]^=(1<<(position%32)); + item++; + i--; + }; + }; + return 0; + } + return 1; +}; + +static inline cmph_uint8 place_bucket(chd_ph_config_data_t *chd_ph, chd_ph_bucket_t *buckets, chd_ph_item_t * items, cmph_uint32 max_probes, + cmph_uint32 * disp_table, cmph_uint32 bucket_num, cmph_uint32 size) + +{ + register cmph_uint32 probe0_num, probe1_num, probe_num; + probe0_num = 0; + probe1_num = 0; + probe_num = 0; + + while(1) + { + if(place_bucket_probe(chd_ph, buckets, items, probe0_num, probe1_num, bucket_num,size)) + { + disp_table[buckets[bucket_num].bucket_id] = probe0_num + probe1_num * chd_ph->n; + return 1; + } + probe0_num++; + if(probe0_num >= chd_ph->n) + { + probe0_num -= chd_ph->n; + probe1_num++; + }; + probe_num++; + if(probe_num >= max_probes || probe1_num >= chd_ph->n) + { + return 0; + }; + }; + return 0; +}; + +static inline cmph_uint8 place_buckets1(chd_ph_config_data_t *chd_ph, chd_ph_bucket_t * buckets, chd_ph_item_t *items, + cmph_uint32 max_bucket_size, chd_ph_sorted_list_t *sorted_lists, cmph_uint32 max_probes, + cmph_uint32 * disp_table) +{ + register cmph_uint32 i = 0; + register cmph_uint32 curr_bucket = 0; + + for(i = max_bucket_size; i > 0; i--) + { + curr_bucket = sorted_lists[i].buckets_list; + while(curr_bucket < sorted_lists[i].size + sorted_lists[i].buckets_list) + { + if(!place_bucket(chd_ph, buckets, items, max_probes, disp_table, curr_bucket, i)) + { + return 0; + } + curr_bucket++; + }; + }; + return 1; +}; + +static inline cmph_uint8 place_buckets2(chd_ph_config_data_t *chd_ph, chd_ph_bucket_t *buckets, chd_ph_item_t * items, + cmph_uint32 max_bucket_size, chd_ph_sorted_list_t *sorted_lists, cmph_uint32 max_probes, + cmph_uint32 * disp_table) +{ + register cmph_uint32 i,j, non_placed_bucket; + register cmph_uint32 curr_bucket; + register cmph_uint32 probe_num, probe0_num, probe1_num; + cmph_uint32 sorted_list_size; +#ifdef DEBUG + cmph_uint32 items_list; + cmph_uint32 bucket_id; +#endif + DEBUGP("USING HEURISTIC TO PLACE BUCKETS\n"); + for(i = max_bucket_size; i > 0; i--) + { + probe_num = 0; + probe0_num = 0; + probe1_num = 0; + sorted_list_size = sorted_lists[i].size; + while(sorted_lists[i].size != 0) + { + curr_bucket = sorted_lists[i].buckets_list; + for(j = 0, non_placed_bucket = 0; j < sorted_lists[i].size; j++) + { + // if bucket is successfully placed remove it from list + if(place_bucket_probe(chd_ph, buckets, items, probe0_num, probe1_num, curr_bucket, i)) + { + disp_table[buckets[curr_bucket].bucket_id] = probe0_num + probe1_num * chd_ph->n; +// DEBUGP("BUCKET %u PLACED --- DISPLACEMENT = %u\n", curr_bucket, disp_table[curr_bucket]); + } + else + { +// DEBUGP("BUCKET %u NOT PLACED\n", curr_bucket); +#ifdef DEBUG + items_list = buckets[non_placed_bucket + sorted_lists[i].buckets_list].items_list; + bucket_id = buckets[non_placed_bucket + sorted_lists[i].buckets_list].bucket_id; +#endif + buckets[non_placed_bucket + sorted_lists[i].buckets_list].items_list = buckets[curr_bucket].items_list; + buckets[non_placed_bucket + sorted_lists[i].buckets_list].bucket_id = buckets[curr_bucket].bucket_id; +#ifdef DEBUG + buckets[curr_bucket].items_list=items_list; + buckets[curr_bucket].bucket_id=bucket_id; +#endif + non_placed_bucket++; + } + curr_bucket++; + }; + sorted_lists[i].size = non_placed_bucket; + probe0_num++; + if(probe0_num >= chd_ph->n) + { + probe0_num -= chd_ph->n; + probe1_num++; + }; + probe_num++; + if(probe_num >= max_probes || probe1_num >= chd_ph->n) + { + sorted_lists[i].size = sorted_list_size; + return 0; + }; + }; + sorted_lists[i].size = sorted_list_size; + }; + return 1; +}; + +cmph_uint8 chd_ph_searching(chd_ph_config_data_t *chd_ph, chd_ph_bucket_t *buckets, chd_ph_item_t *items , + cmph_uint32 max_bucket_size, chd_ph_sorted_list_t *sorted_lists, cmph_uint32 max_probes, + cmph_uint32 * disp_table) +{ + if(chd_ph->use_h) + { + return place_buckets2(chd_ph, buckets, items, max_bucket_size, sorted_lists, max_probes, disp_table); + } + else + { + return place_buckets1(chd_ph, buckets, items, max_bucket_size, sorted_lists, max_probes, disp_table); + } + +} + +static inline cmph_uint8 chd_ph_check_bin_hashing(chd_ph_config_data_t *chd_ph, chd_ph_bucket_t *buckets, chd_ph_item_t *items, + cmph_uint32 * disp_table, chd_ph_sorted_list_t * sorted_lists,cmph_uint32 max_bucket_size) +{ + register cmph_uint32 bucket_size, i, j; + register cmph_uint32 position, probe0_num, probe1_num; + register cmph_uint32 m = 0; + register chd_ph_item_t * item; + if(chd_ph->keys_per_bin > 1) + memset(chd_ph->occup_table, 0, chd_ph->n); + else + memset(chd_ph->occup_table, 0, ((chd_ph->n + 31)/32) * sizeof(cmph_uint32)); + + for(bucket_size = 1; bucket_size <= max_bucket_size; bucket_size++) + for(i = sorted_lists[bucket_size].buckets_list; i < sorted_lists[bucket_size].size + + sorted_lists[bucket_size].buckets_list; i++) + { + j = bucket_size; + item = items + buckets[i].items_list; + probe0_num = disp_table[buckets[i].bucket_id] % chd_ph->n; + probe1_num = disp_table[buckets[i].bucket_id] / chd_ph->n; + for(; j > 0; j--) + { + m++; + position = (cmph_uint32)((item->f + ((cmph_uint64 )item->h) * probe0_num + probe1_num) % chd_ph->n); + if(chd_ph->keys_per_bin > 1) + { + if(chd_ph->occup_table[position] >= chd_ph->keys_per_bin) + { + return 0; + } + (chd_ph->occup_table[position])++; + } + else + { + if(GETBIT32(((cmph_uint32*)chd_ph->occup_table), position)) + { + return 0; + } + SETBIT32(((cmph_uint32*)chd_ph->occup_table), position); + }; + item++; + }; + }; + DEBUGP("We were able to place m = %u keys\n", m); + return 1; +}; + + +cmph_t *chd_ph_new(cmph_config_t *mph, double c) +{ + cmph_t *mphf = NULL; + chd_ph_data_t *chd_phf = NULL; + chd_ph_config_data_t *chd_ph = (chd_ph_config_data_t *)mph->data; + + register double load_factor = c; + register cmph_uint8 searching_success = 0; + register cmph_uint32 max_probes = 1 << 20; // default value for max_probes + register cmph_uint32 iterations = 100; + chd_ph_bucket_t * buckets = NULL; + chd_ph_item_t * items = NULL; + register cmph_uint8 failure = 0; + cmph_uint32 max_bucket_size = 0; + chd_ph_sorted_list_t * sorted_lists = NULL; + cmph_uint32 * disp_table = NULL; + register double space_lower_bound = 0; + #ifdef CMPH_TIMING + double construction_time_begin = 0.0; + double construction_time = 0.0; + ELAPSED_TIME_IN_SECONDS(&construction_time_begin); + #endif + + + chd_ph->m = mph->key_source->nkeys; + DEBUGP("m = %u\n", chd_ph->m); + + chd_ph->nbuckets = (cmph_uint32)(chd_ph->m/chd_ph->keys_per_bucket) + 1; + DEBUGP("nbuckets = %u\n", chd_ph->nbuckets); + + if(load_factor < 0.5 ) + { + load_factor = 0.5; + } + + if(load_factor >= 0.99) + { + load_factor = 0.99; + } + + DEBUGP("load_factor = %.3f\n", load_factor); + + chd_ph->n = (cmph_uint32)(chd_ph->m/(chd_ph->keys_per_bin * load_factor)) + 1; + + //Round the number of bins to the prime immediately above + if(chd_ph->n % 2 == 0) chd_ph->n++; + for(;;) + { + if(check_primality(chd_ph->n) == 1) + break; + chd_ph->n += 2; // just odd numbers can be primes for n > 2 + + }; + + DEBUGP("n = %u \n", chd_ph->n); + if(chd_ph->keys_per_bin == 1) + { + space_lower_bound = chd_ph_space_lower_bound(chd_ph->m, chd_ph->n); + } + + if(mph->verbosity) + { + fprintf(stderr, "space lower bound is %.3f bits per key\n", space_lower_bound); + } + + // We allocate the working tables + buckets = chd_ph_bucket_new(chd_ph->nbuckets); + items = (chd_ph_item_t *) calloc(chd_ph->m, sizeof(chd_ph_item_t)); + + max_probes = (cmph_uint32)(((log(chd_ph->m)/log(2))/20) * max_probes); + + if(chd_ph->keys_per_bin == 1) + chd_ph->occup_table = (cmph_uint8 *) calloc(((chd_ph->n + 31)/32), sizeof(cmph_uint32)); + else + chd_ph->occup_table = (cmph_uint8 *) calloc(chd_ph->n, sizeof(cmph_uint8)); + + disp_table = (cmph_uint32 *) calloc(chd_ph->nbuckets, sizeof(cmph_uint32)); +// +// init_genrand(time(0)); + + while(1) + { + iterations --; + if (mph->verbosity) + { + fprintf(stderr, "Starting mapping step for mph creation of %u keys with %u bins\n", chd_ph->m, chd_ph->n); + } + + if(!chd_ph_mapping(mph, buckets, items, &max_bucket_size)) + { + if (mph->verbosity) + { + fprintf(stderr, "Failure in mapping step\n"); + } + failure = 1; + goto cleanup; + } + + if (mph->verbosity) + { + fprintf(stderr, "Starting ordering step\n"); + } + if(sorted_lists) + { + free(sorted_lists); + } + + sorted_lists = chd_ph_ordering(&buckets, &items, chd_ph->nbuckets, chd_ph->m, max_bucket_size); + + if (mph->verbosity) + { + fprintf(stderr, "Starting searching step\n"); + } + + searching_success = chd_ph_searching(chd_ph, buckets, items, max_bucket_size, sorted_lists, max_probes, disp_table); + if(searching_success) break; + + // reset occup_table + if(chd_ph->keys_per_bin > 1) + memset(chd_ph->occup_table, 0, chd_ph->n); + else + memset(chd_ph->occup_table, 0, ((chd_ph->n + 31)/32) * sizeof(cmph_uint32)); + if(iterations == 0) + { + // Cleanup memory + if (mph->verbosity) + { + fprintf(stderr, "Failure because the max trials was exceeded\n"); + } + failure = 1; + goto cleanup; + }; + } + + #ifdef DEBUG + { + if(!chd_ph_check_bin_hashing(chd_ph, buckets, items, disp_table,sorted_lists,max_bucket_size)) + { + + DEBUGP("Error for bin packing generation"); + failure = 1; + goto cleanup; + } + } + #endif + + if (mph->verbosity) + { + fprintf(stderr, "Starting compressing step\n"); + } + + if(chd_ph->cs) + { + free(chd_ph->cs); + } + chd_ph->cs = (compressed_seq_t *) calloc(1, sizeof(compressed_seq_t)); + compressed_seq_init(chd_ph->cs); + compressed_seq_generate(chd_ph->cs, disp_table, chd_ph->nbuckets); + + #ifdef CMPH_TIMING + ELAPSED_TIME_IN_SECONDS(&construction_time); + register double entropy = chd_ph_get_entropy(disp_table, chd_ph->nbuckets, max_probes); + DEBUGP("Entropy = %.4f\n", entropy/chd_ph->m); + #endif + +cleanup: + chd_ph_bucket_destroy(buckets); + free(items); + free(sorted_lists); + free(disp_table); + if(failure) + { + if(chd_ph->hl) + { + hash_state_destroy(chd_ph->hl); + } + chd_ph->hl = NULL; + return NULL; + } + + mphf = (cmph_t *)malloc(sizeof(cmph_t)); + mphf->algo = mph->algo; + chd_phf = (chd_ph_data_t *)malloc(sizeof(chd_ph_data_t)); + + chd_phf->cs = chd_ph->cs; + chd_ph->cs = NULL; //transfer memory ownership + chd_phf->hl = chd_ph->hl; + chd_ph->hl = NULL; //transfer memory ownership + chd_phf->n = chd_ph->n; + chd_phf->nbuckets = chd_ph->nbuckets; + + mphf->data = chd_phf; + mphf->size = chd_ph->n; + + DEBUGP("Successfully generated minimal perfect hash\n"); + if (mph->verbosity) + { + fprintf(stderr, "Successfully generated minimal perfect hash function\n"); + } + + #ifdef CMPH_TIMING + register cmph_uint32 space_usage = chd_ph_packed_size(mphf)*8; + construction_time = construction_time - construction_time_begin; + fprintf(stdout, "%u\t%.2f\t%u\t%.4f\t%.4f\t%.4f\t%.4f\n", chd_ph->m, load_factor, chd_ph->keys_per_bucket, construction_time, space_usage/(double)chd_ph->m, space_lower_bound, entropy/chd_ph->m); + #endif + + return mphf; +} + + + +void chd_ph_load(FILE *fd, cmph_t *mphf) +{ + char *buf = NULL; + cmph_uint32 buflen; + register size_t nbytes; + chd_ph_data_t *chd_ph = (chd_ph_data_t *)malloc(sizeof(chd_ph_data_t)); + + DEBUGP("Loading chd_ph mphf\n"); + mphf->data = chd_ph; + + nbytes = fread(&buflen, sizeof(cmph_uint32), (size_t)1, fd); + DEBUGP("Hash state has %u bytes\n", buflen); + buf = (char *)malloc((size_t)buflen); + nbytes = fread(buf, (size_t)buflen, (size_t)1, fd); + chd_ph->hl = hash_state_load(buf, buflen); + free(buf); + + nbytes = fread(&buflen, sizeof(cmph_uint32), (size_t)1, fd); + DEBUGP("Compressed sequence structure has %u bytes\n", buflen); + buf = (char *)malloc((size_t)buflen); + nbytes = fread(buf, (size_t)buflen, (size_t)1, fd); + chd_ph->cs = (compressed_seq_t *) calloc(1, sizeof(compressed_seq_t)); + compressed_seq_load(chd_ph->cs, buf, buflen); + free(buf); + + // loading n and nbuckets + DEBUGP("Reading n and nbuckets\n"); + nbytes = fread(&(chd_ph->n), sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fread(&(chd_ph->nbuckets), sizeof(cmph_uint32), (size_t)1, fd); +} + +int chd_ph_dump(cmph_t *mphf, FILE *fd) +{ + char *buf = NULL; + cmph_uint32 buflen; + register size_t nbytes; + chd_ph_data_t *data = (chd_ph_data_t *)mphf->data; + + __cmph_dump(mphf, fd); + + hash_state_dump(data->hl, &buf, &buflen); + DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); + nbytes = fwrite(&buflen, sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(buf, (size_t)buflen, (size_t)1, fd); + free(buf); + + compressed_seq_dump(data->cs, &buf, &buflen); + DEBUGP("Dumping compressed sequence structure with %u bytes to disk\n", buflen); + nbytes = fwrite(&buflen, sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(buf, (size_t)buflen, (size_t)1, fd); + free(buf); + + // dumping n and nbuckets + nbytes = fwrite(&(data->n), sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(&(data->nbuckets), sizeof(cmph_uint32), (size_t)1, fd); + return 1; +} + +void chd_ph_destroy(cmph_t *mphf) +{ + chd_ph_data_t *data = (chd_ph_data_t *)mphf->data; + compressed_seq_destroy(data->cs); + free(data->cs); + hash_state_destroy(data->hl); + free(data); + free(mphf); + +} + +cmph_uint32 chd_ph_search(cmph_t *mphf, const char *key, cmph_uint32 keylen) +{ + register chd_ph_data_t * chd_ph = mphf->data; + cmph_uint32 hl[3]; + register cmph_uint32 disp,position; + register cmph_uint32 probe0_num,probe1_num; + register cmph_uint32 f,g,h; + hash_vector(chd_ph->hl, key, keylen, hl); + g = hl[0] % chd_ph->nbuckets; + f = hl[1] % chd_ph->n; + h = hl[2] % (chd_ph->n-1) + 1; + + disp = compressed_seq_query(chd_ph->cs, g); + probe0_num = disp % chd_ph->n; + probe1_num = disp/chd_ph->n; + position = (cmph_uint32)((f + ((cmph_uint64 )h)*probe0_num + probe1_num) % chd_ph->n); + return position; +} + +void chd_ph_pack(cmph_t *mphf, void *packed_mphf) +{ + chd_ph_data_t *data = (chd_ph_data_t *)mphf->data; + cmph_uint8 * ptr = packed_mphf; + + // packing hl type + CMPH_HASH hl_type = hash_get_type(data->hl); + *((cmph_uint32 *) ptr) = hl_type; + ptr += sizeof(cmph_uint32); + + // packing hl + hash_state_pack(data->hl, ptr); + ptr += hash_state_packed_size(hl_type); + + // packing n + *((cmph_uint32 *) ptr) = data->n; + ptr += sizeof(data->n); + + // packing nbuckets + *((cmph_uint32 *) ptr) = data->nbuckets; + ptr += sizeof(data->nbuckets); + + // packing cs + compressed_seq_pack(data->cs, ptr); + //ptr += compressed_seq_packed_size(data->cs); + +} + +cmph_uint32 chd_ph_packed_size(cmph_t *mphf) +{ + register chd_ph_data_t *data = (chd_ph_data_t *)mphf->data; + register CMPH_HASH hl_type = hash_get_type(data->hl); + register cmph_uint32 hash_state_pack_size = hash_state_packed_size(hl_type); + register cmph_uint32 cs_pack_size = compressed_seq_packed_size(data->cs); + + return (cmph_uint32)(sizeof(CMPH_ALGO) + hash_state_pack_size + cs_pack_size + 3*sizeof(cmph_uint32)); + +} + +cmph_uint32 chd_ph_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen) +{ + register CMPH_HASH hl_type = *(cmph_uint32 *)packed_mphf; + register cmph_uint8 *hl_ptr = (cmph_uint8 *)(packed_mphf) + 4; + + register cmph_uint32 * ptr = (cmph_uint32 *)(hl_ptr + hash_state_packed_size(hl_type)); + register cmph_uint32 n = *ptr++; + register cmph_uint32 nbuckets = *ptr++; + cmph_uint32 hl[3]; + + register cmph_uint32 disp,position; + register cmph_uint32 probe0_num,probe1_num; + register cmph_uint32 f,g,h; + + hash_vector_packed(hl_ptr, hl_type, key, keylen, hl); + + g = hl[0] % nbuckets; + f = hl[1] % n; + h = hl[2] % (n-1) + 1; + + disp = compressed_seq_query_packed(ptr, g); + probe0_num = disp % n; + probe1_num = disp/n; + position = (cmph_uint32)((f + ((cmph_uint64 )h)*probe0_num + probe1_num) % n); + return position; +} + + + diff --git a/cmph/chd_ph.h b/cmph/chd_ph.h new file mode 100644 index 000000000..d2bdb0286 --- /dev/null +++ b/cmph/chd_ph.h @@ -0,0 +1,59 @@ +#ifndef _CMPH_CHD_PH_H__ +#define _CMPH_CHD_PH_H__ + +#include "cmph.h" + +typedef struct __chd_ph_data_t chd_ph_data_t; +typedef struct __chd_ph_config_data_t chd_ph_config_data_t; + +/* Config API */ +chd_ph_config_data_t *chd_ph_config_new(); +void chd_ph_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); + +/** \fn void chd_ph_config_set_keys_per_bin(cmph_config_t *mph, cmph_uint32 keys_per_bin); + * \brief Allows to set the number of keys per bin. + * \param mph pointer to the configuration structure + * \param keys_per_bin value for the number of keys per bin + */ +void chd_ph_config_set_keys_per_bin(cmph_config_t *mph, cmph_uint32 keys_per_bin); + +/** \fn void chd_ph_config_set_b(cmph_config_t *mph, cmph_uint32 keys_per_bucket); + * \brief Allows to set the number of keys per bucket. + * \param mph pointer to the configuration structure + * \param keys_per_bucket value for the number of keys per bucket + */ +void chd_ph_config_set_b(cmph_config_t *mph, cmph_uint32 keys_per_bucket); +void chd_ph_config_destroy(cmph_config_t *mph); + + +/* Chd algorithm API */ +cmph_t *chd_ph_new(cmph_config_t *mph, double c); +void chd_ph_load(FILE *fd, cmph_t *mphf); +int chd_ph_dump(cmph_t *mphf, FILE *fd); +void chd_ph_destroy(cmph_t *mphf); +cmph_uint32 chd_ph_search(cmph_t *mphf, const char *key, cmph_uint32 keylen); + +/** \fn void chd_ph_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void chd_ph_pack(cmph_t *mphf, void *packed_mphf); + +/** \fn cmph_uint32 chd_ph_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 chd_ph_packed_size(cmph_t *mphf); + +/** cmph_uint32 chd_ph_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint32 chd_ph_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen); + +#endif diff --git a/cmph/chd_structs.h b/cmph/chd_structs.h new file mode 100644 index 000000000..d62f68268 --- /dev/null +++ b/cmph/chd_structs.h @@ -0,0 +1,21 @@ +#ifndef __CMPH_CHD_STRUCTS_H__ +#define __CMPH_CHD_STRUCTS_H__ + +#include "chd_structs_ph.h" +#include "chd_ph.h" +#include "compressed_rank.h" + +struct __chd_data_t +{ + cmph_uint32 packed_cr_size; + cmph_uint8 * packed_cr; // packed compressed rank structure to control the number of zeros in a bit vector + + cmph_uint32 packed_chd_phf_size; + cmph_uint8 * packed_chd_phf; +}; + +struct __chd_config_data_t +{ + cmph_config_t *chd_ph; // chd_ph algorithm must be used here +}; +#endif diff --git a/cmph/chd_structs_ph.h b/cmph/chd_structs_ph.h new file mode 100644 index 000000000..d86921822 --- /dev/null +++ b/cmph/chd_structs_ph.h @@ -0,0 +1,29 @@ +#ifndef __CMPH_CHD_PH_STRUCTS_H__ +#define __CMPH_CHD_PH_STRUCTS_H__ + +#include "hash_state.h" +#include "compressed_seq.h" + +struct __chd_ph_data_t +{ + compressed_seq_t * cs; // compressed displacement values + cmph_uint32 nbuckets; // number of buckets + cmph_uint32 n; // number of bins + hash_state_t *hl; // linear hash function +}; + +struct __chd_ph_config_data_t +{ + CMPH_HASH hashfunc; // linear hash function to be used + compressed_seq_t * cs; // compressed displacement values + cmph_uint32 nbuckets; // number of buckets + cmph_uint32 n; // number of bins + hash_state_t *hl; // linear hash function + + cmph_uint32 m; // number of keys + cmph_uint8 use_h; // flag to indicate the of use of a heuristic (use_h = 1) + cmph_uint32 keys_per_bin;//maximum number of keys per bin + cmph_uint32 keys_per_bucket; // average number of keys per bucket + cmph_uint8 *occup_table; // table that indicates occupied positions +}; +#endif diff --git a/cmph/chm.c b/cmph/chm.c new file mode 100644 index 000000000..e03cca80e --- /dev/null +++ b/cmph/chm.c @@ -0,0 +1,381 @@ +#include "graph.h" +#include "chm.h" +#include "cmph_structs.h" +#include "chm_structs.h" +#include "hash.h" +#include "bitbool.h" + +#include +#include +#include +#include +#include + +//#define DEBUG +#include "debug.h" + +static int chm_gen_edges(cmph_config_t *mph); +static void chm_traverse(chm_config_data_t *chm, cmph_uint8 *visited, cmph_uint32 v); + +chm_config_data_t *chm_config_new() +{ + chm_config_data_t *chm = NULL; + chm = (chm_config_data_t *)malloc(sizeof(chm_config_data_t)); + assert(chm); + memset(chm, 0, sizeof(chm_config_data_t)); + chm->hashfuncs[0] = CMPH_HASH_JENKINS; + chm->hashfuncs[1] = CMPH_HASH_JENKINS; + chm->g = NULL; + chm->graph = NULL; + chm->hashes = NULL; + return chm; +} +void chm_config_destroy(cmph_config_t *mph) +{ + chm_config_data_t *data = (chm_config_data_t *)mph->data; + DEBUGP("Destroying algorithm dependent data\n"); + free(data); +} + +void chm_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs) +{ + chm_config_data_t *chm = (chm_config_data_t *)mph->data; + CMPH_HASH *hashptr = hashfuncs; + cmph_uint32 i = 0; + while(*hashptr != CMPH_HASH_COUNT) + { + if (i >= 2) break; //chm only uses two hash functions + chm->hashfuncs[i] = *hashptr; + ++i, ++hashptr; + } +} + +cmph_t *chm_new(cmph_config_t *mph, double c) +{ + cmph_t *mphf = NULL; + chm_data_t *chmf = NULL; + + cmph_uint32 i; + cmph_uint32 iterations = 20; + cmph_uint8 *visited = NULL; + chm_config_data_t *chm = (chm_config_data_t *)mph->data; + chm->m = mph->key_source->nkeys; + if (c == 0) c = 2.09; + chm->n = (cmph_uint32)ceil(c * mph->key_source->nkeys); + DEBUGP("m (edges): %u n (vertices): %u c: %f\n", chm->m, chm->n, c); + chm->graph = graph_new(chm->n, chm->m); + DEBUGP("Created graph\n"); + + chm->hashes = (hash_state_t **)malloc(sizeof(hash_state_t *)*3); + for(i = 0; i < 3; ++i) chm->hashes[i] = NULL; + //Mapping step + if (mph->verbosity) + { + fprintf(stderr, "Entering mapping step for mph creation of %u keys with graph sized %u\n", chm->m, chm->n); + } + while(1) + { + int ok; + chm->hashes[0] = hash_state_new(chm->hashfuncs[0], chm->n); + chm->hashes[1] = hash_state_new(chm->hashfuncs[1], chm->n); + ok = chm_gen_edges(mph); + if (!ok) + { + --iterations; + hash_state_destroy(chm->hashes[0]); + chm->hashes[0] = NULL; + hash_state_destroy(chm->hashes[1]); + chm->hashes[1] = NULL; + DEBUGP("%u iterations remaining\n", iterations); + if (mph->verbosity) + { + fprintf(stderr, "Acyclic graph creation failure - %u iterations remaining\n", iterations); + } + if (iterations == 0) break; + } + else break; + } + if (iterations == 0) + { + graph_destroy(chm->graph); + return NULL; + } + + //Assignment step + if (mph->verbosity) + { + fprintf(stderr, "Starting assignment step\n"); + } + DEBUGP("Assignment step\n"); + visited = (cmph_uint8 *)malloc((size_t)(chm->n/8 + 1)); + memset(visited, 0, (size_t)(chm->n/8 + 1)); + free(chm->g); + chm->g = (cmph_uint32 *)malloc(chm->n * sizeof(cmph_uint32)); + assert(chm->g); + for (i = 0; i < chm->n; ++i) + { + if (!GETBIT(visited,i)) + { + chm->g[i] = 0; + chm_traverse(chm, visited, i); + } + } + graph_destroy(chm->graph); + free(visited); + chm->graph = NULL; + + mphf = (cmph_t *)malloc(sizeof(cmph_t)); + mphf->algo = mph->algo; + chmf = (chm_data_t *)malloc(sizeof(chm_data_t)); + chmf->g = chm->g; + chm->g = NULL; //transfer memory ownership + chmf->hashes = chm->hashes; + chm->hashes = NULL; //transfer memory ownership + chmf->n = chm->n; + chmf->m = chm->m; + mphf->data = chmf; + mphf->size = chm->m; + DEBUGP("Successfully generated minimal perfect hash\n"); + if (mph->verbosity) + { + fprintf(stderr, "Successfully generated minimal perfect hash function\n"); + } + return mphf; +} + +static void chm_traverse(chm_config_data_t *chm, cmph_uint8 *visited, cmph_uint32 v) +{ + + graph_iterator_t it = graph_neighbors_it(chm->graph, v); + cmph_uint32 neighbor = 0; + SETBIT(visited,v); + + DEBUGP("Visiting vertex %u\n", v); + while((neighbor = graph_next_neighbor(chm->graph, &it)) != GRAPH_NO_NEIGHBOR) + { + DEBUGP("Visiting neighbor %u\n", neighbor); + if(GETBIT(visited,neighbor)) continue; + DEBUGP("Visiting neighbor %u\n", neighbor); + DEBUGP("Visiting edge %u->%u with id %u\n", v, neighbor, graph_edge_id(chm->graph, v, neighbor)); + chm->g[neighbor] = graph_edge_id(chm->graph, v, neighbor) - chm->g[v]; + DEBUGP("g is %u (%u - %u mod %u)\n", chm->g[neighbor], graph_edge_id(chm->graph, v, neighbor), chm->g[v], chm->m); + chm_traverse(chm, visited, neighbor); + } +} + +static int chm_gen_edges(cmph_config_t *mph) +{ + cmph_uint32 e; + chm_config_data_t *chm = (chm_config_data_t *)mph->data; + int cycles = 0; + + DEBUGP("Generating edges for %u vertices with hash functions %s and %s\n", chm->n, cmph_hash_names[chm->hashfuncs[0]], cmph_hash_names[chm->hashfuncs[1]]); + graph_clear_edges(chm->graph); + mph->key_source->rewind(mph->key_source->data); + for (e = 0; e < mph->key_source->nkeys; ++e) + { + cmph_uint32 h1, h2; + cmph_uint32 keylen; + char *key; + mph->key_source->read(mph->key_source->data, &key, &keylen); + h1 = hash(chm->hashes[0], key, keylen) % chm->n; + h2 = hash(chm->hashes[1], key, keylen) % chm->n; + if (h1 == h2) if (++h2 >= chm->n) h2 = 0; + if (h1 == h2) + { + if (mph->verbosity) fprintf(stderr, "Self loop for key %u\n", e); + mph->key_source->dispose(mph->key_source->data, key, keylen); + return 0; + } + DEBUGP("Adding edge: %u -> %u for key %s\n", h1, h2, key); + mph->key_source->dispose(mph->key_source->data, key, keylen); + graph_add_edge(chm->graph, h1, h2); + } + cycles = graph_is_cyclic(chm->graph); + if (mph->verbosity && cycles) fprintf(stderr, "Cyclic graph generated\n"); + DEBUGP("Looking for cycles: %u\n", cycles); + + return ! cycles; +} + +int chm_dump(cmph_t *mphf, FILE *fd) +{ + char *buf = NULL; + cmph_uint32 buflen; + cmph_uint32 two = 2; //number of hash functions + chm_data_t *data = (chm_data_t *)mphf->data; + register size_t nbytes; + + __cmph_dump(mphf, fd); + + nbytes = fwrite(&two, sizeof(cmph_uint32), (size_t)1, fd); + hash_state_dump(data->hashes[0], &buf, &buflen); + DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); + nbytes = fwrite(&buflen, sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(buf, (size_t)buflen, (size_t)1, fd); + free(buf); + + hash_state_dump(data->hashes[1], &buf, &buflen); + DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); + nbytes = fwrite(&buflen, sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(buf, (size_t)buflen, (size_t)1, fd); + free(buf); + + nbytes = fwrite(&(data->n), sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(&(data->m), sizeof(cmph_uint32), (size_t)1, fd); + + nbytes = fwrite(data->g, sizeof(cmph_uint32)*data->n, (size_t)1, fd); +/* #ifdef DEBUG + fprintf(stderr, "G: "); + for (i = 0; i < data->n; ++i) fprintf(stderr, "%u ", data->g[i]); + fprintf(stderr, "\n"); + #endif*/ + return 1; +} + +void chm_load(FILE *f, cmph_t *mphf) +{ + cmph_uint32 nhashes; + char *buf = NULL; + cmph_uint32 buflen; + cmph_uint32 i; + chm_data_t *chm = (chm_data_t *)malloc(sizeof(chm_data_t)); + register size_t nbytes; + DEBUGP("Loading chm mphf\n"); + mphf->data = chm; + nbytes = fread(&nhashes, sizeof(cmph_uint32), (size_t)1, f); + chm->hashes = (hash_state_t **)malloc(sizeof(hash_state_t *)*(nhashes + 1)); + chm->hashes[nhashes] = NULL; + DEBUGP("Reading %u hashes\n", nhashes); + for (i = 0; i < nhashes; ++i) + { + hash_state_t *state = NULL; + nbytes = fread(&buflen, sizeof(cmph_uint32), (size_t)1, f); + DEBUGP("Hash state has %u bytes\n", buflen); + buf = (char *)malloc((size_t)buflen); + nbytes = fread(buf, (size_t)buflen, (size_t)1, f); + state = hash_state_load(buf, buflen); + chm->hashes[i] = state; + free(buf); + } + + DEBUGP("Reading m and n\n"); + nbytes = fread(&(chm->n), sizeof(cmph_uint32), (size_t)1, f); + nbytes = fread(&(chm->m), sizeof(cmph_uint32), (size_t)1, f); + + chm->g = (cmph_uint32 *)malloc(sizeof(cmph_uint32)*chm->n); + nbytes = fread(chm->g, chm->n*sizeof(cmph_uint32), (size_t)1, f); + #ifdef DEBUG + fprintf(stderr, "G: "); + for (i = 0; i < chm->n; ++i) fprintf(stderr, "%u ", chm->g[i]); + fprintf(stderr, "\n"); + #endif + return; +} + + +cmph_uint32 chm_search(cmph_t *mphf, const char *key, cmph_uint32 keylen) +{ + chm_data_t *chm = mphf->data; + cmph_uint32 h1 = hash(chm->hashes[0], key, keylen) % chm->n; + cmph_uint32 h2 = hash(chm->hashes[1], key, keylen) % chm->n; + DEBUGP("key: %s h1: %u h2: %u\n", key, h1, h2); + if (h1 == h2 && ++h2 >= chm->n) h2 = 0; + DEBUGP("key: %s g[h1]: %u g[h2]: %u edges: %u\n", key, chm->g[h1], chm->g[h2], chm->m); + return (chm->g[h1] + chm->g[h2]) % chm->m; +} +void chm_destroy(cmph_t *mphf) +{ + chm_data_t *data = (chm_data_t *)mphf->data; + free(data->g); + hash_state_destroy(data->hashes[0]); + hash_state_destroy(data->hashes[1]); + free(data->hashes); + free(data); + free(mphf); +} + +/** \fn void chm_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void chm_pack(cmph_t *mphf, void *packed_mphf) +{ + chm_data_t *data = (chm_data_t *)mphf->data; + cmph_uint8 * ptr = packed_mphf; + + // packing h1 type + CMPH_HASH h1_type = hash_get_type(data->hashes[0]); + *((cmph_uint32 *) ptr) = h1_type; + ptr += sizeof(cmph_uint32); + + // packing h1 + hash_state_pack(data->hashes[0], ptr); + ptr += hash_state_packed_size(h1_type); + + // packing h2 type + CMPH_HASH h2_type = hash_get_type(data->hashes[1]); + *((cmph_uint32 *) ptr) = h2_type; + ptr += sizeof(cmph_uint32); + + // packing h2 + hash_state_pack(data->hashes[1], ptr); + ptr += hash_state_packed_size(h2_type); + + // packing n + *((cmph_uint32 *) ptr) = data->n; + ptr += sizeof(data->n); + + // packing m + *((cmph_uint32 *) ptr) = data->m; + ptr += sizeof(data->m); + + // packing g + memcpy(ptr, data->g, sizeof(cmph_uint32)*data->n); +} + +/** \fn cmph_uint32 chm_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 chm_packed_size(cmph_t *mphf) +{ + chm_data_t *data = (chm_data_t *)mphf->data; + CMPH_HASH h1_type = hash_get_type(data->hashes[0]); + CMPH_HASH h2_type = hash_get_type(data->hashes[1]); + + return (cmph_uint32)(sizeof(CMPH_ALGO) + hash_state_packed_size(h1_type) + hash_state_packed_size(h2_type) + + 4*sizeof(cmph_uint32) + sizeof(cmph_uint32)*data->n); +} + +/** cmph_uint32 chm_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint32 chm_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen) +{ + register cmph_uint8 *h1_ptr = packed_mphf; + register CMPH_HASH h1_type = *((cmph_uint32 *)h1_ptr); + h1_ptr += 4; + + register cmph_uint8 *h2_ptr = h1_ptr + hash_state_packed_size(h1_type); + register CMPH_HASH h2_type = *((cmph_uint32 *)h2_ptr); + h2_ptr += 4; + + register cmph_uint32 *g_ptr = (cmph_uint32 *)(h2_ptr + hash_state_packed_size(h2_type)); + + register cmph_uint32 n = *g_ptr++; + register cmph_uint32 m = *g_ptr++; + + register cmph_uint32 h1 = hash_packed(h1_ptr, h1_type, key, keylen) % n; + register cmph_uint32 h2 = hash_packed(h2_ptr, h2_type, key, keylen) % n; + DEBUGP("key: %s h1: %u h2: %u\n", key, h1, h2); + if (h1 == h2 && ++h2 >= n) h2 = 0; + DEBUGP("key: %s g[h1]: %u g[h2]: %u edges: %u\n", key, g_ptr[h1], g_ptr[h2], m); + return (g_ptr[h1] + g_ptr[h2]) % m; +} diff --git a/cmph/chm.h b/cmph/chm.h new file mode 100644 index 000000000..341be29ea --- /dev/null +++ b/cmph/chm.h @@ -0,0 +1,42 @@ +#ifndef __CMPH_CHM_H__ +#define __CMPH_CHM_H__ + +#include "cmph.h" + +typedef struct __chm_data_t chm_data_t; +typedef struct __chm_config_data_t chm_config_data_t; + +chm_config_data_t *chm_config_new(); +void chm_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); +void chm_config_destroy(cmph_config_t *mph); +cmph_t *chm_new(cmph_config_t *mph, double c); + +void chm_load(FILE *f, cmph_t *mphf); +int chm_dump(cmph_t *mphf, FILE *f); +void chm_destroy(cmph_t *mphf); +cmph_uint32 chm_search(cmph_t *mphf, const char *key, cmph_uint32 keylen); + +/** \fn void chm_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void chm_pack(cmph_t *mphf, void *packed_mphf); + +/** \fn cmph_uint32 chm_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 chm_packed_size(cmph_t *mphf); + +/** cmph_uint32 chm_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint32 chm_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen); + +#endif diff --git a/cmph/chm_structs.h b/cmph/chm_structs.h new file mode 100644 index 000000000..fcad1bc3d --- /dev/null +++ b/cmph/chm_structs.h @@ -0,0 +1,24 @@ +#ifndef __CMPH_CHM_STRUCTS_H__ +#define __CMPH_CHM_STRUCTS_H__ + +#include "hash_state.h" + +struct __chm_data_t +{ + cmph_uint32 m; //edges (words) count + cmph_uint32 n; //vertex count + cmph_uint32 *g; + hash_state_t **hashes; +}; + +struct __chm_config_data_t +{ + CMPH_HASH hashfuncs[2]; + cmph_uint32 m; //edges (words) count + cmph_uint32 n; //vertex count + graph_t *graph; + cmph_uint32 *g; + hash_state_t **hashes; +}; + +#endif diff --git a/cmph/cmph.c b/cmph/cmph.c new file mode 100644 index 000000000..cba735f4f --- /dev/null +++ b/cmph/cmph.c @@ -0,0 +1,845 @@ +#include "cmph.h" +#include "cmph_structs.h" +#include "chm.h" +#include "bmz.h" +#include "bmz8.h" +#include "brz.h" +#include "fch.h" +#include "bdz.h" +#include "bdz_ph.h" +#include "chd_ph.h" +#include "chd.h" + +#include +#include +#include +//#define DEBUG +#include "debug.h" + +const char *cmph_names[] = {"bmz", "bmz8", "chm", "brz", "fch", "bdz", "bdz_ph", "chd_ph", "chd", NULL }; + +typedef struct +{ + void *vector; + cmph_uint32 position; // access position when data is a vector +} cmph_vector_t; + + + +/** + * Support a vector of struct as the source of keys. + * + * E.g. The keys could be the fieldB's in a vector of struct rec where + * struct rec is defined as: + * struct rec { + * fieldA; + * fieldB; + * fieldC; + * } + */ +typedef struct +{ + void *vector; /* Pointer to the vector of struct */ + cmph_uint32 position; /* current position */ + cmph_uint32 struct_size; /* The size of the struct */ + cmph_uint32 key_offset; /* The byte offset of the key in the struct */ + cmph_uint32 key_len; /* The length of the key */ +} cmph_struct_vector_t; + + +static cmph_io_adapter_t *cmph_io_vector_new(void * vector, cmph_uint32 nkeys); +static void cmph_io_vector_destroy(cmph_io_adapter_t * key_source); + +static cmph_io_adapter_t *cmph_io_struct_vector_new(void * vector, cmph_uint32 struct_size, cmph_uint32 key_offset, cmph_uint32 key_len, cmph_uint32 nkeys); +static void cmph_io_struct_vector_destroy(cmph_io_adapter_t * key_source); + +static int key_nlfile_read(void *data, char **key, cmph_uint32 *keylen) +{ + FILE *fd = (FILE *)data; + *key = NULL; + *keylen = 0; + while(1) + { + char buf[BUFSIZ]; + char *c = fgets(buf, BUFSIZ, fd); + if (c == NULL) return -1; + if (feof(fd)) return -1; + *key = (char *)realloc(*key, *keylen + strlen(buf) + 1); + memcpy(*key + *keylen, buf, strlen(buf)); + *keylen += (cmph_uint32)strlen(buf); + if (buf[strlen(buf) - 1] != '\n') continue; + break; + } + if ((*keylen) && (*key)[*keylen - 1] == '\n') + { + (*key)[(*keylen) - 1] = 0; + --(*keylen); + } + return (int)(*keylen); +} + +static int key_byte_vector_read(void *data, char **key, cmph_uint32 *keylen) +{ + cmph_vector_t *cmph_vector = (cmph_vector_t *)data; + cmph_uint8 **keys_vd = (cmph_uint8 **)cmph_vector->vector; + size_t size; + memcpy(keylen, keys_vd[cmph_vector->position], sizeof(*keylen)); + size = *keylen; + *key = (char *)malloc(size); + memcpy(*key, keys_vd[cmph_vector->position] + sizeof(*keylen), size); + cmph_vector->position = cmph_vector->position + 1; + return (int)(*keylen); + +} + +static int key_struct_vector_read(void *data, char **key, cmph_uint32 *keylen) +{ + cmph_struct_vector_t *cmph_struct_vector = (cmph_struct_vector_t *)data; + char *keys_vd = (char *)cmph_struct_vector->vector; + size_t size; + *keylen = cmph_struct_vector->key_len; + size = *keylen; + *key = (char *)malloc(size); + memcpy(*key, (keys_vd + (cmph_struct_vector->position * cmph_struct_vector->struct_size) + cmph_struct_vector->key_offset), size); + cmph_struct_vector->position = cmph_struct_vector->position + 1; + return (int)(*keylen); +} + +static int key_vector_read(void *data, char **key, cmph_uint32 *keylen) +{ + cmph_vector_t *cmph_vector = (cmph_vector_t *)data; + char **keys_vd = (char **)cmph_vector->vector; + size_t size; + *keylen = (cmph_uint32)strlen(keys_vd[cmph_vector->position]); + size = *keylen; + *key = (char *)malloc(size + 1); + strcpy(*key, keys_vd[cmph_vector->position]); + cmph_vector->position = cmph_vector->position + 1; + return (int)(*keylen); + +} + + +static void key_nlfile_dispose(void *data, char *key, cmph_uint32 keylen) +{ + free(key); +} + +static void key_vector_dispose(void *data, char *key, cmph_uint32 keylen) +{ + free(key); +} + +static void key_nlfile_rewind(void *data) +{ + FILE *fd = (FILE *)data; + rewind(fd); +} + +static void key_struct_vector_rewind(void *data) +{ + cmph_struct_vector_t *cmph_struct_vector = (cmph_struct_vector_t *)data; + cmph_struct_vector->position = 0; +} + +static void key_vector_rewind(void *data) +{ + cmph_vector_t *cmph_vector = (cmph_vector_t *)data; + cmph_vector->position = 0; +} + +static cmph_uint32 count_nlfile_keys(FILE *fd) +{ + cmph_uint32 count = 0; + register char * ptr; + rewind(fd); + while(1) + { + char buf[BUFSIZ]; + ptr = fgets(buf, BUFSIZ, fd); + if (feof(fd)) break; + if (buf[strlen(buf) - 1] != '\n') continue; + ++count; + } + rewind(fd); + return count; +} + +cmph_io_adapter_t *cmph_io_nlfile_adapter(FILE * keys_fd) +{ + cmph_io_adapter_t * key_source = (cmph_io_adapter_t *)malloc(sizeof(cmph_io_adapter_t)); + assert(key_source); + key_source->data = (void *)keys_fd; + key_source->nkeys = count_nlfile_keys(keys_fd); + key_source->read = key_nlfile_read; + key_source->dispose = key_nlfile_dispose; + key_source->rewind = key_nlfile_rewind; + return key_source; +} + +void cmph_io_nlfile_adapter_destroy(cmph_io_adapter_t * key_source) +{ + free(key_source); +} + +cmph_io_adapter_t *cmph_io_nlnkfile_adapter(FILE * keys_fd, cmph_uint32 nkeys) +{ + cmph_io_adapter_t * key_source = (cmph_io_adapter_t *)malloc(sizeof(cmph_io_adapter_t)); + assert(key_source); + key_source->data = (void *)keys_fd; + key_source->nkeys = nkeys; + key_source->read = key_nlfile_read; + key_source->dispose = key_nlfile_dispose; + key_source->rewind = key_nlfile_rewind; + return key_source; +} + +void cmph_io_nlnkfile_adapter_destroy(cmph_io_adapter_t * key_source) +{ + free(key_source); +} + + +static cmph_io_adapter_t *cmph_io_struct_vector_new(void * vector, cmph_uint32 struct_size, cmph_uint32 key_offset, cmph_uint32 key_len, cmph_uint32 nkeys) +{ + cmph_io_adapter_t * key_source = (cmph_io_adapter_t *)malloc(sizeof(cmph_io_adapter_t)); + cmph_struct_vector_t * cmph_struct_vector = (cmph_struct_vector_t *)malloc(sizeof(cmph_struct_vector_t)); + assert(key_source); + assert(cmph_struct_vector); + cmph_struct_vector->vector = vector; + cmph_struct_vector->position = 0; + cmph_struct_vector->struct_size = struct_size; + cmph_struct_vector->key_offset = key_offset; + cmph_struct_vector->key_len = key_len; + key_source->data = (void *)cmph_struct_vector; + key_source->nkeys = nkeys; + return key_source; +} + +static void cmph_io_struct_vector_destroy(cmph_io_adapter_t * key_source) +{ + cmph_struct_vector_t *cmph_struct_vector = (cmph_struct_vector_t *)key_source->data; + cmph_struct_vector->vector = NULL; + free(cmph_struct_vector); + free(key_source); +} + +static cmph_io_adapter_t *cmph_io_vector_new(void * vector, cmph_uint32 nkeys) +{ + cmph_io_adapter_t * key_source = (cmph_io_adapter_t *)malloc(sizeof(cmph_io_adapter_t)); + cmph_vector_t * cmph_vector = (cmph_vector_t *)malloc(sizeof(cmph_vector_t)); + assert(key_source); + assert(cmph_vector); + cmph_vector->vector = vector; + cmph_vector->position = 0; + key_source->data = (void *)cmph_vector; + key_source->nkeys = nkeys; + return key_source; +} + +static void cmph_io_vector_destroy(cmph_io_adapter_t * key_source) +{ + cmph_vector_t *cmph_vector = (cmph_vector_t *)key_source->data; + cmph_vector->vector = NULL; + free(cmph_vector); + free(key_source); +} + +cmph_io_adapter_t *cmph_io_byte_vector_adapter(cmph_uint8 ** vector, cmph_uint32 nkeys) +{ + cmph_io_adapter_t * key_source = cmph_io_vector_new(vector, nkeys); + key_source->read = key_byte_vector_read; + key_source->dispose = key_vector_dispose; + key_source->rewind = key_vector_rewind; + return key_source; +} +void cmph_io_byte_vector_adapter_destroy(cmph_io_adapter_t * key_source) +{ + cmph_io_vector_destroy(key_source); +} + +cmph_io_adapter_t *cmph_io_struct_vector_adapter(void * vector, cmph_uint32 struct_size, cmph_uint32 key_offset, cmph_uint32 key_len, cmph_uint32 nkeys) +{ + cmph_io_adapter_t * key_source = cmph_io_struct_vector_new(vector, struct_size, key_offset, key_len, nkeys); + key_source->read = key_struct_vector_read; + key_source->dispose = key_vector_dispose; + key_source->rewind = key_struct_vector_rewind; + return key_source; +} + +void cmph_io_struct_vector_adapter_destroy(cmph_io_adapter_t * key_source) +{ + cmph_io_struct_vector_destroy(key_source); +} + +cmph_io_adapter_t *cmph_io_vector_adapter(char ** vector, cmph_uint32 nkeys) +{ + cmph_io_adapter_t * key_source = cmph_io_vector_new(vector, nkeys); + key_source->read = key_vector_read; + key_source->dispose = key_vector_dispose; + key_source->rewind = key_vector_rewind; + return key_source; +} + +void cmph_io_vector_adapter_destroy(cmph_io_adapter_t * key_source) +{ + cmph_io_vector_destroy(key_source); +} + +cmph_config_t *cmph_config_new(cmph_io_adapter_t *key_source) +{ + cmph_config_t *mph = NULL; + mph = __config_new(key_source); + assert(mph); + mph->algo = CMPH_CHM; // default value + mph->data = chm_config_new(); + return mph; +} + +void cmph_config_set_algo(cmph_config_t *mph, CMPH_ALGO algo) +{ + if (algo != mph->algo) + { + switch (mph->algo) + { + case CMPH_CHM: + chm_config_destroy(mph); + break; + case CMPH_BMZ: + bmz_config_destroy(mph); + break; + case CMPH_BMZ8: + bmz8_config_destroy(mph); + break; + case CMPH_BRZ: + brz_config_destroy(mph); + break; + case CMPH_FCH: + fch_config_destroy(mph); + break; + case CMPH_BDZ: + bdz_config_destroy(mph); + break; + case CMPH_BDZ_PH: + bdz_ph_config_destroy(mph); + break; + case CMPH_CHD_PH: + chd_ph_config_destroy(mph); + break; + case CMPH_CHD: + chd_config_destroy(mph); + break; + default: + assert(0); + } + switch(algo) + { + case CMPH_CHM: + mph->data = chm_config_new(); + break; + case CMPH_BMZ: + mph->data = bmz_config_new(); + break; + case CMPH_BMZ8: + mph->data = bmz8_config_new(); + break; + case CMPH_BRZ: + mph->data = brz_config_new(); + break; + case CMPH_FCH: + mph->data = fch_config_new(); + break; + case CMPH_BDZ: + mph->data = bdz_config_new(); + break; + case CMPH_BDZ_PH: + mph->data = bdz_ph_config_new(); + break; + case CMPH_CHD_PH: + mph->data = chd_ph_config_new(); + break; + case CMPH_CHD: + mph->data = chd_config_new(mph); + break; + default: + assert(0); + } + } + mph->algo = algo; +} + +void cmph_config_set_tmp_dir(cmph_config_t *mph, cmph_uint8 *tmp_dir) +{ + if (mph->algo == CMPH_BRZ) + { + brz_config_set_tmp_dir(mph, tmp_dir); + } +} + + +void cmph_config_set_mphf_fd(cmph_config_t *mph, FILE *mphf_fd) +{ + if (mph->algo == CMPH_BRZ) + { + brz_config_set_mphf_fd(mph, mphf_fd); + } +} + +void cmph_config_set_b(cmph_config_t *mph, cmph_uint32 b) +{ + if (mph->algo == CMPH_BRZ) + { + brz_config_set_b(mph, b); + } + else if (mph->algo == CMPH_BDZ) + { + bdz_config_set_b(mph, b); + } + else if (mph->algo == CMPH_CHD_PH) + { + chd_ph_config_set_b(mph, b); + } + else if (mph->algo == CMPH_CHD) + { + chd_config_set_b(mph, b); + } +} + +void cmph_config_set_keys_per_bin(cmph_config_t *mph, cmph_uint32 keys_per_bin) +{ + if (mph->algo == CMPH_CHD_PH) + { + chd_ph_config_set_keys_per_bin(mph, keys_per_bin); + } + else if (mph->algo == CMPH_CHD) + { + chd_config_set_keys_per_bin(mph, keys_per_bin); + } +} + +void cmph_config_set_memory_availability(cmph_config_t *mph, cmph_uint32 memory_availability) +{ + if (mph->algo == CMPH_BRZ) + { + brz_config_set_memory_availability(mph, memory_availability); + } +} + +void cmph_config_destroy(cmph_config_t *mph) +{ + if(mph) + { + DEBUGP("Destroying mph with algo %s\n", cmph_names[mph->algo]); + switch (mph->algo) + { + case CMPH_CHM: + chm_config_destroy(mph); + break; + case CMPH_BMZ: /* included -- Fabiano */ + bmz_config_destroy(mph); + break; + case CMPH_BMZ8: /* included -- Fabiano */ + bmz8_config_destroy(mph); + break; + case CMPH_BRZ: /* included -- Fabiano */ + brz_config_destroy(mph); + break; + case CMPH_FCH: /* included -- Fabiano */ + fch_config_destroy(mph); + break; + case CMPH_BDZ: /* included -- Fabiano */ + bdz_config_destroy(mph); + break; + case CMPH_BDZ_PH: /* included -- Fabiano */ + bdz_ph_config_destroy(mph); + break; + case CMPH_CHD_PH: /* included -- Fabiano */ + chd_ph_config_destroy(mph); + break; + case CMPH_CHD: /* included -- Fabiano */ + chd_config_destroy(mph); + break; + default: + assert(0); + } + __config_destroy(mph); + } +} + +void cmph_config_set_verbosity(cmph_config_t *mph, cmph_uint32 verbosity) +{ + mph->verbosity = verbosity; +} + +void cmph_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs) +{ + switch (mph->algo) + { + case CMPH_CHM: + chm_config_set_hashfuncs(mph, hashfuncs); + break; + case CMPH_BMZ: /* included -- Fabiano */ + bmz_config_set_hashfuncs(mph, hashfuncs); + break; + case CMPH_BMZ8: /* included -- Fabiano */ + bmz8_config_set_hashfuncs(mph, hashfuncs); + break; + case CMPH_BRZ: /* included -- Fabiano */ + brz_config_set_hashfuncs(mph, hashfuncs); + break; + case CMPH_FCH: /* included -- Fabiano */ + fch_config_set_hashfuncs(mph, hashfuncs); + break; + case CMPH_BDZ: /* included -- Fabiano */ + bdz_config_set_hashfuncs(mph, hashfuncs); + break; + case CMPH_BDZ_PH: /* included -- Fabiano */ + bdz_ph_config_set_hashfuncs(mph, hashfuncs); + break; + case CMPH_CHD_PH: /* included -- Fabiano */ + chd_ph_config_set_hashfuncs(mph, hashfuncs); + break; + case CMPH_CHD: /* included -- Fabiano */ + chd_config_set_hashfuncs(mph, hashfuncs); + break; + default: + break; + } + return; +} +void cmph_config_set_graphsize(cmph_config_t *mph, double c) +{ + mph->c = c; + return; +} + +cmph_t *cmph_new(cmph_config_t *mph) +{ + cmph_t *mphf = NULL; + double c = mph->c; + + DEBUGP("Creating mph with algorithm %s\n", cmph_names[mph->algo]); + switch (mph->algo) + { + case CMPH_CHM: + DEBUGP("Creating chm hash\n"); + mphf = chm_new(mph, c); + break; + case CMPH_BMZ: /* included -- Fabiano */ + DEBUGP("Creating bmz hash\n"); + mphf = bmz_new(mph, c); + break; + case CMPH_BMZ8: /* included -- Fabiano */ + DEBUGP("Creating bmz8 hash\n"); + mphf = bmz8_new(mph, c); + break; + case CMPH_BRZ: /* included -- Fabiano */ + DEBUGP("Creating brz hash\n"); + if (c >= 2.0) brz_config_set_algo(mph, CMPH_FCH); + else brz_config_set_algo(mph, CMPH_BMZ8); + mphf = brz_new(mph, c); + break; + case CMPH_FCH: /* included -- Fabiano */ + DEBUGP("Creating fch hash\n"); + mphf = fch_new(mph, c); + break; + case CMPH_BDZ: /* included -- Fabiano */ + DEBUGP("Creating bdz hash\n"); + mphf = bdz_new(mph, c); + break; + case CMPH_BDZ_PH: /* included -- Fabiano */ + DEBUGP("Creating bdz_ph hash\n"); + mphf = bdz_ph_new(mph, c); + break; + case CMPH_CHD_PH: /* included -- Fabiano */ + DEBUGP("Creating chd_ph hash\n"); + mphf = chd_ph_new(mph, c); + break; + case CMPH_CHD: /* included -- Fabiano */ + DEBUGP("Creating chd hash\n"); + mphf = chd_new(mph, c); + break; + default: + assert(0); + } + return mphf; +} + +int cmph_dump(cmph_t *mphf, FILE *f) +{ + switch (mphf->algo) + { + case CMPH_CHM: + return chm_dump(mphf, f); + case CMPH_BMZ: /* included -- Fabiano */ + return bmz_dump(mphf, f); + case CMPH_BMZ8: /* included -- Fabiano */ + return bmz8_dump(mphf, f); + case CMPH_BRZ: /* included -- Fabiano */ + return brz_dump(mphf, f); + case CMPH_FCH: /* included -- Fabiano */ + return fch_dump(mphf, f); + case CMPH_BDZ: /* included -- Fabiano */ + return bdz_dump(mphf, f); + case CMPH_BDZ_PH: /* included -- Fabiano */ + return bdz_ph_dump(mphf, f); + case CMPH_CHD_PH: /* included -- Fabiano */ + return chd_ph_dump(mphf, f); + case CMPH_CHD: /* included -- Fabiano */ + return chd_dump(mphf, f); + default: + assert(0); + } + assert(0); + return 0; +} +cmph_t *cmph_load(FILE *f) +{ + cmph_t *mphf = NULL; + DEBUGP("Loading mphf generic parts\n"); + mphf = __cmph_load(f); + if (mphf == NULL) return NULL; + DEBUGP("Loading mphf algorithm dependent parts\n"); + + switch (mphf->algo) + { + case CMPH_CHM: + chm_load(f, mphf); + break; + case CMPH_BMZ: /* included -- Fabiano */ + DEBUGP("Loading bmz algorithm dependent parts\n"); + bmz_load(f, mphf); + break; + case CMPH_BMZ8: /* included -- Fabiano */ + DEBUGP("Loading bmz8 algorithm dependent parts\n"); + bmz8_load(f, mphf); + break; + case CMPH_BRZ: /* included -- Fabiano */ + DEBUGP("Loading brz algorithm dependent parts\n"); + brz_load(f, mphf); + break; + case CMPH_FCH: /* included -- Fabiano */ + DEBUGP("Loading fch algorithm dependent parts\n"); + fch_load(f, mphf); + break; + case CMPH_BDZ: /* included -- Fabiano */ + DEBUGP("Loading bdz algorithm dependent parts\n"); + bdz_load(f, mphf); + break; + case CMPH_BDZ_PH: /* included -- Fabiano */ + DEBUGP("Loading bdz_ph algorithm dependent parts\n"); + bdz_ph_load(f, mphf); + break; + case CMPH_CHD_PH: /* included -- Fabiano */ + DEBUGP("Loading chd_ph algorithm dependent parts\n"); + chd_ph_load(f, mphf); + break; + case CMPH_CHD: /* included -- Fabiano */ + DEBUGP("Loading chd algorithm dependent parts\n"); + chd_load(f, mphf); + break; + default: + assert(0); + } + DEBUGP("Loaded mphf\n"); + return mphf; +} + + +cmph_uint32 cmph_search(cmph_t *mphf, const char *key, cmph_uint32 keylen) +{ + DEBUGP("mphf algorithm: %u \n", mphf->algo); + switch(mphf->algo) + { + case CMPH_CHM: + return chm_search(mphf, key, keylen); + case CMPH_BMZ: /* included -- Fabiano */ + DEBUGP("bmz algorithm search\n"); + return bmz_search(mphf, key, keylen); + case CMPH_BMZ8: /* included -- Fabiano */ + DEBUGP("bmz8 algorithm search\n"); + return bmz8_search(mphf, key, keylen); + case CMPH_BRZ: /* included -- Fabiano */ + DEBUGP("brz algorithm search\n"); + return brz_search(mphf, key, keylen); + case CMPH_FCH: /* included -- Fabiano */ + DEBUGP("fch algorithm search\n"); + return fch_search(mphf, key, keylen); + case CMPH_BDZ: /* included -- Fabiano */ + DEBUGP("bdz algorithm search\n"); + return bdz_search(mphf, key, keylen); + case CMPH_BDZ_PH: /* included -- Fabiano */ + DEBUGP("bdz_ph algorithm search\n"); + return bdz_ph_search(mphf, key, keylen); + case CMPH_CHD_PH: /* included -- Fabiano */ + DEBUGP("chd_ph algorithm search\n"); + return chd_ph_search(mphf, key, keylen); + case CMPH_CHD: /* included -- Fabiano */ + DEBUGP("chd algorithm search\n"); + return chd_search(mphf, key, keylen); + default: + assert(0); + } + assert(0); + return 0; +} + +cmph_uint32 cmph_size(cmph_t *mphf) +{ + return mphf->size; +} + +void cmph_destroy(cmph_t *mphf) +{ + switch(mphf->algo) + { + case CMPH_CHM: + chm_destroy(mphf); + return; + case CMPH_BMZ: /* included -- Fabiano */ + bmz_destroy(mphf); + return; + case CMPH_BMZ8: /* included -- Fabiano */ + bmz8_destroy(mphf); + return; + case CMPH_BRZ: /* included -- Fabiano */ + brz_destroy(mphf); + return; + case CMPH_FCH: /* included -- Fabiano */ + fch_destroy(mphf); + return; + case CMPH_BDZ: /* included -- Fabiano */ + bdz_destroy(mphf); + return; + case CMPH_BDZ_PH: /* included -- Fabiano */ + bdz_ph_destroy(mphf); + return; + case CMPH_CHD_PH: /* included -- Fabiano */ + chd_ph_destroy(mphf); + return; + case CMPH_CHD: /* included -- Fabiano */ + chd_destroy(mphf); + return; + default: + assert(0); + } + assert(0); + return; +} + + +/** \fn void cmph_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void cmph_pack(cmph_t *mphf, void *packed_mphf) +{ + // packing algorithm type to be used in cmph.c + cmph_uint32 * ptr = (cmph_uint32 *) packed_mphf; + *ptr++ = mphf->algo; + DEBUGP("mphf->algo = %u\n", mphf->algo); + switch(mphf->algo) + { + case CMPH_CHM: + chm_pack(mphf, ptr); + break; + case CMPH_BMZ: /* included -- Fabiano */ + bmz_pack(mphf, ptr); + break; + case CMPH_BMZ8: /* included -- Fabiano */ + bmz8_pack(mphf, ptr); + break; + case CMPH_BRZ: /* included -- Fabiano */ + brz_pack(mphf, ptr); + break; + case CMPH_FCH: /* included -- Fabiano */ + fch_pack(mphf, ptr); + break; + case CMPH_BDZ: /* included -- Fabiano */ + bdz_pack(mphf, ptr); + break; + case CMPH_BDZ_PH: /* included -- Fabiano */ + bdz_ph_pack(mphf, ptr); + break; + case CMPH_CHD_PH: /* included -- Fabiano */ + chd_ph_pack(mphf, ptr); + break; + case CMPH_CHD: /* included -- Fabiano */ + chd_pack(mphf, ptr); + break; + default: + assert(0); + } + return; +} + +/** \fn cmph_uint32 cmph_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 cmph_packed_size(cmph_t *mphf) +{ + switch(mphf->algo) + { + case CMPH_CHM: + return chm_packed_size(mphf); + case CMPH_BMZ: /* included -- Fabiano */ + return bmz_packed_size(mphf); + case CMPH_BMZ8: /* included -- Fabiano */ + return bmz8_packed_size(mphf); + case CMPH_BRZ: /* included -- Fabiano */ + return brz_packed_size(mphf); + case CMPH_FCH: /* included -- Fabiano */ + return fch_packed_size(mphf); + case CMPH_BDZ: /* included -- Fabiano */ + return bdz_packed_size(mphf); + case CMPH_BDZ_PH: /* included -- Fabiano */ + return bdz_ph_packed_size(mphf); + case CMPH_CHD_PH: /* included -- Fabiano */ + return chd_ph_packed_size(mphf); + case CMPH_CHD: /* included -- Fabiano */ + return chd_packed_size(mphf); + default: + assert(0); + } + return 0; // FAILURE +} + +/** cmph_uint32 cmph_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint32 cmph_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen) +{ + cmph_uint32 *ptr = (cmph_uint32 *)packed_mphf; +// fprintf(stderr, "algo:%u\n", *ptr); + switch(*ptr) + { + case CMPH_CHM: + return chm_search_packed(++ptr, key, keylen); + case CMPH_BMZ: /* included -- Fabiano */ + return bmz_search_packed(++ptr, key, keylen); + case CMPH_BMZ8: /* included -- Fabiano */ + return bmz8_search_packed(++ptr, key, keylen); + case CMPH_BRZ: /* included -- Fabiano */ + return brz_search_packed(++ptr, key, keylen); + case CMPH_FCH: /* included -- Fabiano */ + return fch_search_packed(++ptr, key, keylen); + case CMPH_BDZ: /* included -- Fabiano */ + return bdz_search_packed(++ptr, key, keylen); + case CMPH_BDZ_PH: /* included -- Fabiano */ + return bdz_ph_search_packed(++ptr, key, keylen); + case CMPH_CHD_PH: /* included -- Fabiano */ + return chd_ph_search_packed(++ptr, key, keylen); + case CMPH_CHD: /* included -- Fabiano */ + return chd_search_packed(++ptr, key, keylen); + default: + assert(0); + } + return 0; // FAILURE +} diff --git a/cmph/cmph.h b/cmph/cmph.h new file mode 100644 index 000000000..1bc009e19 --- /dev/null +++ b/cmph/cmph.h @@ -0,0 +1,112 @@ +#ifndef __CMPH_H__ +#define __CMPH_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "cmph_types.h" + +typedef struct __config_t cmph_config_t; +typedef struct __cmph_t cmph_t; + +typedef struct +{ + void *data; + cmph_uint32 nkeys; + int (*read)(void *, char **, cmph_uint32 *); + void (*dispose)(void *, char *, cmph_uint32); + void (*rewind)(void *); +} cmph_io_adapter_t; + +/** Adapter pattern API **/ +/* please call free() in the created adapters */ +cmph_io_adapter_t *cmph_io_nlfile_adapter(FILE * keys_fd); +void cmph_io_nlfile_adapter_destroy(cmph_io_adapter_t * key_source); + +cmph_io_adapter_t *cmph_io_nlnkfile_adapter(FILE * keys_fd, cmph_uint32 nkeys); +void cmph_io_nlnkfile_adapter_destroy(cmph_io_adapter_t * key_source); + +cmph_io_adapter_t *cmph_io_vector_adapter(char ** vector, cmph_uint32 nkeys); +void cmph_io_vector_adapter_destroy(cmph_io_adapter_t * key_source); + +cmph_io_adapter_t *cmph_io_byte_vector_adapter(cmph_uint8 ** vector, cmph_uint32 nkeys); +void cmph_io_byte_vector_adapter_destroy(cmph_io_adapter_t * key_source); + +cmph_io_adapter_t *cmph_io_struct_vector_adapter(void * vector, + cmph_uint32 struct_size, + cmph_uint32 key_offset, + cmph_uint32 key_len, + cmph_uint32 nkeys); + +void cmph_io_struct_vector_adapter_destroy(cmph_io_adapter_t * key_source); + +/** Hash configuration API **/ +cmph_config_t *cmph_config_new(cmph_io_adapter_t *key_source); +void cmph_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); +void cmph_config_set_verbosity(cmph_config_t *mph, cmph_uint32 verbosity); +void cmph_config_set_graphsize(cmph_config_t *mph, double c); +void cmph_config_set_algo(cmph_config_t *mph, CMPH_ALGO algo); +void cmph_config_set_tmp_dir(cmph_config_t *mph, cmph_uint8 *tmp_dir); +void cmph_config_set_mphf_fd(cmph_config_t *mph, FILE *mphf_fd); +void cmph_config_set_b(cmph_config_t *mph, cmph_uint32 b); +void cmph_config_set_keys_per_bin(cmph_config_t *mph, cmph_uint32 keys_per_bin); +void cmph_config_set_memory_availability(cmph_config_t *mph, cmph_uint32 memory_availability); +void cmph_config_destroy(cmph_config_t *mph); + +/** Hash API **/ +cmph_t *cmph_new(cmph_config_t *mph); + +/** cmph_uint32 cmph_search(cmph_t *mphf, const char *key, cmph_uint32 keylen); + * \brief Computes the mphf value. + * \param mphf pointer to the resulting function + * \param key is the key to be hashed + * \param keylen is the key legth in bytes + * \return The mphf value + */ +cmph_uint32 cmph_search(cmph_t *mphf, const char *key, cmph_uint32 keylen); + +cmph_uint32 cmph_size(cmph_t *mphf); +void cmph_destroy(cmph_t *mphf); + +/** Hash serialization/deserialization */ +int cmph_dump(cmph_t *mphf, FILE *f); +cmph_t *cmph_load(FILE *f); + +/** \fn void cmph_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the + * \param resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void cmph_pack(cmph_t *mphf, void *packed_mphf); + +/** \fn cmph_uint32 cmph_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 cmph_packed_size(cmph_t *mphf); + +/** cmph_uint32 cmph_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint32 cmph_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen); + +// TIMING functions. To use the macro CMPH_TIMING must be defined +#include "cmph_time.h" + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cmph/cmph_structs.c b/cmph/cmph_structs.c new file mode 100644 index 000000000..b5634248f --- /dev/null +++ b/cmph/cmph_structs.c @@ -0,0 +1,69 @@ +#include "cmph_structs.h" + +#include + +//#define DEBUG +#include "debug.h" + +cmph_config_t *__config_new(cmph_io_adapter_t *key_source) +{ + cmph_config_t *mph = (cmph_config_t *)malloc(sizeof(cmph_config_t)); + memset(mph, 0, sizeof(cmph_config_t)); + if (mph == NULL) return NULL; + mph->key_source = key_source; + mph->verbosity = 0; + mph->data = NULL; + mph->c = 0; + return mph; +} + +void __config_destroy(cmph_config_t *mph) +{ + free(mph); +} + +void __cmph_dump(cmph_t *mphf, FILE *fd) +{ + register size_t nbytes; + nbytes = fwrite(cmph_names[mphf->algo], (size_t)(strlen(cmph_names[mphf->algo]) + 1), (size_t)1, fd); + nbytes = fwrite(&(mphf->size), sizeof(mphf->size), (size_t)1, fd); +} +cmph_t *__cmph_load(FILE *f) +{ + cmph_t *mphf = NULL; + cmph_uint32 i; + char algo_name[BUFSIZ]; + char *ptr = algo_name; + CMPH_ALGO algo = CMPH_COUNT; + register size_t nbytes; + + DEBUGP("Loading mphf\n"); + while(1) + { + size_t c = fread(ptr, (size_t)1, (size_t)1, f); + if (c != 1) return NULL; + if (*ptr == 0) break; + ++ptr; + } + for(i = 0; i < CMPH_COUNT; ++i) + { + if (strcmp(algo_name, cmph_names[i]) == 0) + { + algo = i; + } + } + if (algo == CMPH_COUNT) + { + DEBUGP("Algorithm %s not found\n", algo_name); + return NULL; + } + mphf = (cmph_t *)malloc(sizeof(cmph_t)); + mphf->algo = algo; + nbytes = fread(&(mphf->size), sizeof(mphf->size), (size_t)1, f); + mphf->data = NULL; + DEBUGP("Algorithm is %s and mphf is sized %u\n", cmph_names[algo], mphf->size); + + return mphf; +} + + diff --git a/cmph/cmph_structs.h b/cmph/cmph_structs.h new file mode 100644 index 000000000..88fafb6ce --- /dev/null +++ b/cmph/cmph_structs.h @@ -0,0 +1,33 @@ +#ifndef __CMPH_STRUCTS_H__ +#define __CMPH_STRUCTS_H__ + +#include "cmph.h" + +/** Hash generation algorithm data + */ +struct __config_t +{ + CMPH_ALGO algo; + cmph_io_adapter_t *key_source; + cmph_uint32 verbosity; + double c; + void *data; // algorithm dependent data +}; + +/** Hash querying algorithm data + */ +struct __cmph_t +{ + CMPH_ALGO algo; + cmph_uint32 size; + cmph_io_adapter_t *key_source; + void *data; // algorithm dependent data +}; + +cmph_config_t *__config_new(cmph_io_adapter_t *key_source); +void __config_destroy(cmph_config_t*); +void __cmph_dump(cmph_t *mphf, FILE *); +cmph_t *__cmph_load(FILE *f); + + +#endif diff --git a/cmph/cmph_time.h b/cmph/cmph_time.h new file mode 100644 index 000000000..d8018090c --- /dev/null +++ b/cmph/cmph_time.h @@ -0,0 +1,62 @@ +#ifdef ELAPSED_TIME_IN_SECONDS +#undef ELAPSED_TIME_IN_SECONDS +#endif + +#ifdef ELAPSED_TIME_IN_uSECONDS +#undef ELAPSED_TIME_IN_uSECONDS +#endif + +#ifdef WIN32 +// include headers to use gettimeofday +#else + #ifdef __GNUC__ + #include + #include + #endif +#endif + +#ifdef __GNUC__ + #ifndef __CMPH_TIME_H__ + #define __CMPH_TIME_H__ + static inline void elapsed_time_in_seconds(double * elapsed_time) + { + struct timeval e_time; + if (gettimeofday(&e_time, NULL) < 0) { + return; + } + *elapsed_time = (double)e_time.tv_sec + ((double)e_time.tv_usec/1000000.0); + } + static inline void dummy_elapsed_time_in_seconds() + { + } + static inline void elapsed_time_in_useconds(cmph_uint64 * elapsed_time) + { + struct timeval e_time; + if (gettimeofday(&e_time, NULL) < 0) { + return; + } + *elapsed_time = (cmph_uint64)(e_time.tv_sec*1000000 + e_time.tv_usec); + } + static inline void dummy_elapsed_time_in_useconds() + { + } + #endif +#endif + +#ifdef CMPH_TIMING + #ifdef __GNUC__ + #define ELAPSED_TIME_IN_SECONDS elapsed_time_in_seconds + #define ELAPSED_TIME_IN_uSECONDS elapsed_time_in_useconds + #else + #define ELAPSED_TIME_IN_SECONDS dummy_elapsed_time_in_seconds + #define ELAPSED_TIME_IN_uSECONDS dummy_elapsed_time_in_useconds + #endif +#else + #ifdef __GNUC__ + #define ELAPSED_TIME_IN_SECONDS + #define ELAPSED_TIME_IN_uSECONDS + #else + #define ELAPSED_TIME_IN_SECONDS dummy_elapsed_time_in_seconds + #define ELAPSED_TIME_IN_uSECONDS dummy_elapsed_time_in_useconds + #endif +#endif diff --git a/cmph/cmph_types.h b/cmph/cmph_types.h new file mode 100644 index 000000000..40f43329a --- /dev/null +++ b/cmph/cmph_types.h @@ -0,0 +1,42 @@ +#ifndef __CMPH_TYPES_H__ +#define __CMPH_TYPES_H__ + +typedef char cmph_int8; +typedef unsigned char cmph_uint8; + +typedef short cmph_int16; +typedef unsigned short cmph_uint16; + +typedef int cmph_int32; +typedef unsigned int cmph_uint32; + +#if defined(__ia64) || defined(__x86_64__) + /** \typedef long cmph_int64; + * \brief 64-bit integer for a 64-bit achitecture. + */ + typedef long cmph_int64; + + /** \typedef unsigned long cmph_uint64; + * \brief Unsigned 64-bit integer for a 64-bit achitecture. + */ + typedef unsigned long cmph_uint64; +#else + /** \typedef long long cmph_int64; + * \brief 64-bit integer for a 32-bit achitecture. + */ + typedef long long cmph_int64; + + /** \typedef unsigned long long cmph_uint64; + * \brief Unsigned 64-bit integer for a 32-bit achitecture. + */ + typedef unsigned long long cmph_uint64; +#endif + +typedef enum { CMPH_HASH_JENKINS, CMPH_HASH_COUNT } CMPH_HASH; +extern const char *cmph_hash_names[]; +typedef enum { CMPH_BMZ, CMPH_BMZ8, CMPH_CHM, CMPH_BRZ, CMPH_FCH, + CMPH_BDZ, CMPH_BDZ_PH, + CMPH_CHD_PH, CMPH_CHD, CMPH_COUNT } CMPH_ALGO; +extern const char *cmph_names[]; + +#endif diff --git a/cmph/compressed_rank.c b/cmph/compressed_rank.c new file mode 100644 index 000000000..822b2e155 --- /dev/null +++ b/cmph/compressed_rank.c @@ -0,0 +1,321 @@ +#include +#include +#include +#include +#include"compressed_rank.h" +#include"bitbool.h" +// #define DEBUG +#include"debug.h" +static inline cmph_uint32 compressed_rank_i_log2(cmph_uint32 x) +{ + register cmph_uint32 res = 0; + + while(x > 1) + { + x >>= 1; + res++; + } + return res; +}; + +void compressed_rank_init(compressed_rank_t * cr) +{ + cr->max_val = 0; + cr->n = 0; + cr->rem_r = 0; + select_init(&cr->sel); + cr->vals_rems = 0; +} + +void compressed_rank_destroy(compressed_rank_t * cr) +{ + free(cr->vals_rems); + cr->vals_rems = 0; + select_destroy(&cr->sel); +} + +void compressed_rank_generate(compressed_rank_t * cr, cmph_uint32 * vals_table, cmph_uint32 n) +{ + register cmph_uint32 i,j; + register cmph_uint32 rems_mask; + register cmph_uint32 * select_vec = 0; + cr->n = n; + cr->max_val = vals_table[cr->n - 1]; + cr->rem_r = compressed_rank_i_log2(cr->max_val/cr->n); + if(cr->rem_r == 0) + { + cr->rem_r = 1; + } + select_vec = (cmph_uint32 *) calloc(cr->max_val >> cr->rem_r, sizeof(cmph_uint32)); + cr->vals_rems = (cmph_uint32 *) calloc(BITS_TABLE_SIZE(cr->n, cr->rem_r), sizeof(cmph_uint32)); + rems_mask = (1U << cr->rem_r) - 1U; + + for(i = 0; i < cr->n; i++) + { + set_bits_value(cr->vals_rems, i, vals_table[i] & rems_mask, cr->rem_r, rems_mask); + } + + for(i = 1, j = 0; i <= cr->max_val >> cr->rem_r; i++) + { + while(i > (vals_table[j] >> cr->rem_r)) + { + j++; + } + select_vec[i - 1] = j; + }; + + + // FABIANO: before it was (cr->total_length >> cr->rem_r) + 1. But I wiped out the + 1 because + // I changed the select structure to work up to m, instead of up to m - 1. + select_generate(&cr->sel, select_vec, cr->max_val >> cr->rem_r, cr->n); + + free(select_vec); +} + +cmph_uint32 compressed_rank_query(compressed_rank_t * cr, cmph_uint32 idx) +{ + register cmph_uint32 rems_mask; + register cmph_uint32 val_quot, val_rem; + register cmph_uint32 sel_res, rank; + + if(idx > cr->max_val) + { + return cr->n; + } + + val_quot = idx >> cr->rem_r; + rems_mask = (1U << cr->rem_r) - 1U; + val_rem = idx & rems_mask; + if(val_quot == 0) + { + rank = sel_res = 0; + } + else + { + sel_res = select_query(&cr->sel, val_quot - 1) + 1; + rank = sel_res - val_quot; + } + + do + { + if(GETBIT32(cr->sel.bits_vec, sel_res)) + { + break; + } + if(get_bits_value(cr->vals_rems, rank, cr->rem_r, rems_mask) >= val_rem) + { + break; + } + sel_res++; + rank++; + } while(1); + + return rank; +} + +cmph_uint32 compressed_rank_get_space_usage(compressed_rank_t * cr) +{ + register cmph_uint32 space_usage = select_get_space_usage(&cr->sel); + space_usage += BITS_TABLE_SIZE(cr->n, cr->rem_r)*(cmph_uint32)sizeof(cmph_uint32)*8; + space_usage += 3*(cmph_uint32)sizeof(cmph_uint32)*8; + return space_usage; +} + +void compressed_rank_dump(compressed_rank_t * cr, char **buf, cmph_uint32 *buflen) +{ + register cmph_uint32 sel_size = select_packed_size(&(cr->sel)); + register cmph_uint32 vals_rems_size = BITS_TABLE_SIZE(cr->n, cr->rem_r) * (cmph_uint32)sizeof(cmph_uint32); + register cmph_uint32 pos = 0; + char * buf_sel = 0; + cmph_uint32 buflen_sel = 0; + + *buflen = 4*(cmph_uint32)sizeof(cmph_uint32) + sel_size + vals_rems_size; + + DEBUGP("sel_size = %u\n", sel_size); + DEBUGP("vals_rems_size = %u\n", vals_rems_size); + + *buf = (char *)calloc(*buflen, sizeof(char)); + + if (!*buf) + { + *buflen = UINT_MAX; + return; + } + + // dumping max_val, n and rem_r + memcpy(*buf, &(cr->max_val), sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + DEBUGP("max_val = %u\n", cr->max_val); + + memcpy(*buf + pos, &(cr->n), sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + DEBUGP("n = %u\n", cr->n); + + memcpy(*buf + pos, &(cr->rem_r), sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + DEBUGP("rem_r = %u\n", cr->rem_r); + + // dumping sel + select_dump(&cr->sel, &buf_sel, &buflen_sel); + memcpy(*buf + pos, &buflen_sel, sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + DEBUGP("buflen_sel = %u\n", buflen_sel); + + memcpy(*buf + pos, buf_sel, buflen_sel); + + #ifdef DEBUG + cmph_uint32 i = 0; + for(i = 0; i < buflen_sel; i++) + { + DEBUGP("pos = %u -- buf_sel[%u] = %u\n", pos, i, *(*buf + pos + i)); + } + #endif + pos += buflen_sel; + + free(buf_sel); + + // dumping vals_rems + memcpy(*buf + pos, cr->vals_rems, vals_rems_size); + #ifdef DEBUG + for(i = 0; i < vals_rems_size; i++) + { + DEBUGP("pos = %u -- vals_rems_size = %u -- vals_rems[%u] = %u\n", pos, vals_rems_size, i, *(*buf + pos + i)); + } + #endif + pos += vals_rems_size; + + DEBUGP("Dumped compressed rank structure with size %u bytes\n", *buflen); +} + +void compressed_rank_load(compressed_rank_t * cr, const char *buf, cmph_uint32 buflen) +{ + register cmph_uint32 pos = 0; + cmph_uint32 buflen_sel = 0; + register cmph_uint32 vals_rems_size = 0; + + // loading max_val, n, and rem_r + memcpy(&(cr->max_val), buf, sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + DEBUGP("max_val = %u\n", cr->max_val); + + memcpy(&(cr->n), buf + pos, sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + DEBUGP("n = %u\n", cr->n); + + memcpy(&(cr->rem_r), buf + pos, sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + DEBUGP("rem_r = %u\n", cr->rem_r); + + // loading sel + memcpy(&buflen_sel, buf + pos, sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + DEBUGP("buflen_sel = %u\n", buflen_sel); + + select_load(&cr->sel, buf + pos, buflen_sel); + #ifdef DEBUG + cmph_uint32 i = 0; + for(i = 0; i < buflen_sel; i++) + { + DEBUGP("pos = %u -- buf_sel[%u] = %u\n", pos, i, *(buf + pos + i)); + } + #endif + pos += buflen_sel; + + // loading vals_rems + if(cr->vals_rems) + { + free(cr->vals_rems); + } + vals_rems_size = BITS_TABLE_SIZE(cr->n, cr->rem_r); + cr->vals_rems = (cmph_uint32 *) calloc(vals_rems_size, sizeof(cmph_uint32)); + vals_rems_size *= 4; + memcpy(cr->vals_rems, buf + pos, vals_rems_size); + + #ifdef DEBUG + for(i = 0; i < vals_rems_size; i++) + { + DEBUGP("pos = %u -- vals_rems_size = %u -- vals_rems[%u] = %u\n", pos, vals_rems_size, i, *(buf + pos + i)); + } + #endif + pos += vals_rems_size; + + DEBUGP("Loaded compressed rank structure with size %u bytes\n", buflen); +} + + + +void compressed_rank_pack(compressed_rank_t *cr, void *cr_packed) +{ + if (cr && cr_packed) + { + char *buf = NULL; + cmph_uint32 buflen = 0; + compressed_rank_dump(cr, &buf, &buflen); + memcpy(cr_packed, buf, buflen); + free(buf); + } +} + +cmph_uint32 compressed_rank_packed_size(compressed_rank_t *cr) +{ + register cmph_uint32 sel_size = select_packed_size(&cr->sel); + register cmph_uint32 vals_rems_size = BITS_TABLE_SIZE(cr->n, cr->rem_r) * (cmph_uint32)sizeof(cmph_uint32); + return 4 * (cmph_uint32)sizeof(cmph_uint32) + sel_size + vals_rems_size; +} + +cmph_uint32 compressed_rank_query_packed(void * cr_packed, cmph_uint32 idx) +{ + // unpacking cr_packed + register cmph_uint32 *ptr = (cmph_uint32 *)cr_packed; + register cmph_uint32 max_val = *ptr++; + register cmph_uint32 n = *ptr++; + register cmph_uint32 rem_r = *ptr++; + register cmph_uint32 buflen_sel = *ptr++; + register cmph_uint32 * sel_packed = ptr; + + register cmph_uint32 * bits_vec = sel_packed + 2; // skipping n and m + + register cmph_uint32 * vals_rems = (ptr += (buflen_sel >> 2)); + + // compressed sequence query computation + register cmph_uint32 rems_mask; + register cmph_uint32 val_quot, val_rem; + register cmph_uint32 sel_res, rank; + + if(idx > max_val) + { + return n; + } + + val_quot = idx >> rem_r; + rems_mask = (1U << rem_r) - 1U; + val_rem = idx & rems_mask; + if(val_quot == 0) + { + rank = sel_res = 0; + } + else + { + sel_res = select_query_packed(sel_packed, val_quot - 1) + 1; + rank = sel_res - val_quot; + } + + do + { + if(GETBIT32(bits_vec, sel_res)) + { + break; + } + if(get_bits_value(vals_rems, rank, rem_r, rems_mask) >= val_rem) + { + break; + } + sel_res++; + rank++; + } while(1); + + return rank; +} + + + diff --git a/cmph/compressed_rank.h b/cmph/compressed_rank.h new file mode 100644 index 000000000..bfe930dd3 --- /dev/null +++ b/cmph/compressed_rank.h @@ -0,0 +1,55 @@ +#ifndef __CMPH_COMPRESSED_RANK_H__ +#define __CMPH_COMPRESSED_RANK_H__ + +#include "select.h" + +struct _compressed_rank_t +{ + cmph_uint32 max_val; + cmph_uint32 n; // number of values stored in vals_rems + // The length in bits of each value is decomposed into two compnents: the lg(n) MSBs are stored in rank_select data structure + // the remaining LSBs are stored in a table of n cells, each one of rem_r bits. + cmph_uint32 rem_r; + select_t sel; + cmph_uint32 * vals_rems; +}; + +typedef struct _compressed_rank_t compressed_rank_t; + +void compressed_rank_init(compressed_rank_t * cr); + +void compressed_rank_destroy(compressed_rank_t * cr); + +void compressed_rank_generate(compressed_rank_t * cr, cmph_uint32 * vals_table, cmph_uint32 n); + +cmph_uint32 compressed_rank_query(compressed_rank_t * cr, cmph_uint32 idx); + +cmph_uint32 compressed_rank_get_space_usage(compressed_rank_t * cr); + +void compressed_rank_dump(compressed_rank_t * cr, char **buf, cmph_uint32 *buflen); + +void compressed_rank_load(compressed_rank_t * cr, const char *buf, cmph_uint32 buflen); + + +/** \fn void compressed_rank_pack(compressed_rank_t *cr, void *cr_packed); + * \brief Support the ability to pack a compressed_rank structure into a preallocated contiguous memory space pointed by cr_packed. + * \param cr points to the compressed_rank structure + * \param cr_packed pointer to the contiguous memory area used to store the compressed_rank structure. The size of cr_packed must be at least @see compressed_rank_packed_size + */ +void compressed_rank_pack(compressed_rank_t *cr, void *cr_packed); + +/** \fn cmph_uint32 compressed_rank_packed_size(compressed_rank_t *cr); + * \brief Return the amount of space needed to pack a compressed_rank structure. + * \return the size of the packed compressed_rank structure or zero for failures + */ +cmph_uint32 compressed_rank_packed_size(compressed_rank_t *cr); + + +/** \fn cmph_uint32 compressed_rank_query_packed(void * cr_packed, cmph_uint32 idx); + * \param cr_packed is a pointer to a contiguous memory area + * \param idx is an index to compute the rank + * \return an integer that represents the compressed_rank value. + */ +cmph_uint32 compressed_rank_query_packed(void * cr_packed, cmph_uint32 idx); + +#endif diff --git a/cmph/compressed_seq.c b/cmph/compressed_seq.c new file mode 100644 index 000000000..e558196d4 --- /dev/null +++ b/cmph/compressed_seq.c @@ -0,0 +1,378 @@ +#include "compressed_seq.h" +#include +#include +#include +#include +#include + +#include "bitbool.h" + +// #define DEBUG +#include "debug.h" + +static inline cmph_uint32 compressed_seq_i_log2(cmph_uint32 x) +{ + register cmph_uint32 res = 0; + + while(x > 1) + { + x >>= 1; + res++; + } + return res; +}; + +void compressed_seq_init(compressed_seq_t * cs) +{ + select_init(&cs->sel); + cs->n = 0; + cs->rem_r = 0; + cs->length_rems = 0; + cs->total_length = 0; + cs->store_table = 0; +} + +void compressed_seq_destroy(compressed_seq_t * cs) +{ + free(cs->store_table); + cs->store_table = 0; + free(cs->length_rems); + cs->length_rems = 0; + select_destroy(&cs->sel); +}; + + +void compressed_seq_generate(compressed_seq_t * cs, cmph_uint32 * vals_table, cmph_uint32 n) +{ + register cmph_uint32 i; + // lengths: represents lengths of encoded values + register cmph_uint32 * lengths = (cmph_uint32 *)calloc(n, sizeof(cmph_uint32)); + register cmph_uint32 rems_mask; + register cmph_uint32 stored_value; + + cs->n = n; + cs->total_length = 0; + + for(i = 0; i < cs->n; i++) + { + if(vals_table[i] == 0) + { + lengths[i] = 0; + } + else + { + lengths[i] = compressed_seq_i_log2(vals_table[i] + 1); + cs->total_length += lengths[i]; + }; + }; + + if(cs->store_table) + { + free(cs->store_table); + } + cs->store_table = (cmph_uint32 *) calloc(((cs->total_length + 31) >> 5), sizeof(cmph_uint32)); + cs->total_length = 0; + + for(i = 0; i < cs->n; i++) + { + if(vals_table[i] == 0) + continue; + stored_value = vals_table[i] - ((1U << lengths[i]) - 1U); + set_bits_at_pos(cs->store_table, cs->total_length, stored_value, lengths[i]); + cs->total_length += lengths[i]; + }; + + cs->rem_r = compressed_seq_i_log2(cs->total_length/cs->n); + + if(cs->rem_r == 0) + { + cs->rem_r = 1; + } + + if(cs->length_rems) + { + free(cs->length_rems); + } + + cs->length_rems = (cmph_uint32 *) calloc(BITS_TABLE_SIZE(cs->n, cs->rem_r), sizeof(cmph_uint32)); + + rems_mask = (1U << cs->rem_r) - 1U; + cs->total_length = 0; + + for(i = 0; i < cs->n; i++) + { + cs->total_length += lengths[i]; + set_bits_value(cs->length_rems, i, cs->total_length & rems_mask, cs->rem_r, rems_mask); + lengths[i] = cs->total_length >> cs->rem_r; + }; + + select_init(&cs->sel); + + // FABIANO: before it was (cs->total_length >> cs->rem_r) + 1. But I wiped out the + 1 because + // I changed the select structure to work up to m, instead of up to m - 1. + select_generate(&cs->sel, lengths, cs->n, (cs->total_length >> cs->rem_r)); + + free(lengths); +}; + +cmph_uint32 compressed_seq_get_space_usage(compressed_seq_t * cs) +{ + register cmph_uint32 space_usage = select_get_space_usage(&cs->sel); + space_usage += ((cs->total_length + 31) >> 5) * (cmph_uint32)sizeof(cmph_uint32) * 8; + space_usage += BITS_TABLE_SIZE(cs->n, cs->rem_r) * (cmph_uint32)sizeof(cmph_uint32) * 8; + return 4 * (cmph_uint32)sizeof(cmph_uint32) * 8 + space_usage; +} + +cmph_uint32 compressed_seq_query(compressed_seq_t * cs, cmph_uint32 idx) +{ + register cmph_uint32 enc_idx, enc_length; + register cmph_uint32 rems_mask; + register cmph_uint32 stored_value; + register cmph_uint32 sel_res; + + assert(idx < cs->n); // FABIANO ADDED + + rems_mask = (1U << cs->rem_r) - 1U; + + if(idx == 0) + { + enc_idx = 0; + sel_res = select_query(&cs->sel, idx); + } + else + { + sel_res = select_query(&cs->sel, idx - 1); + + enc_idx = (sel_res - (idx - 1)) << cs->rem_r; + enc_idx += get_bits_value(cs->length_rems, idx-1, cs->rem_r, rems_mask); + + sel_res = select_next_query(&cs->sel, sel_res); + }; + + enc_length = (sel_res - idx) << cs->rem_r; + enc_length += get_bits_value(cs->length_rems, idx, cs->rem_r, rems_mask); + enc_length -= enc_idx; + if(enc_length == 0) + return 0; + + stored_value = get_bits_at_pos(cs->store_table, enc_idx, enc_length); + return stored_value + ((1U << enc_length) - 1U); +}; + +void compressed_seq_dump(compressed_seq_t * cs, char ** buf, cmph_uint32 * buflen) +{ + register cmph_uint32 sel_size = select_packed_size(&(cs->sel)); + register cmph_uint32 length_rems_size = BITS_TABLE_SIZE(cs->n, cs->rem_r) * 4; + register cmph_uint32 store_table_size = ((cs->total_length + 31) >> 5) * 4; + register cmph_uint32 pos = 0; + char * buf_sel = 0; + cmph_uint32 buflen_sel = 0; + + *buflen = 4*(cmph_uint32)sizeof(cmph_uint32) + sel_size + length_rems_size + store_table_size; + + DEBUGP("sel_size = %u\n", sel_size); + DEBUGP("length_rems_size = %u\n", length_rems_size); + DEBUGP("store_table_size = %u\n", store_table_size); + *buf = (char *)calloc(*buflen, sizeof(char)); + + if (!*buf) + { + *buflen = UINT_MAX; + return; + } + + // dumping n, rem_r and total_length + memcpy(*buf, &(cs->n), sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + DEBUGP("n = %u\n", cs->n); + + memcpy(*buf + pos, &(cs->rem_r), sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + DEBUGP("rem_r = %u\n", cs->rem_r); + + memcpy(*buf + pos, &(cs->total_length), sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + DEBUGP("total_length = %u\n", cs->total_length); + + + // dumping sel + select_dump(&cs->sel, &buf_sel, &buflen_sel); + memcpy(*buf + pos, &buflen_sel, sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + DEBUGP("buflen_sel = %u\n", buflen_sel); + + memcpy(*buf + pos, buf_sel, buflen_sel); + #ifdef DEBUG + cmph_uint32 i = 0; + for(i = 0; i < buflen_sel; i++) + { + DEBUGP("pos = %u -- buf_sel[%u] = %u\n", pos, i, *(*buf + pos + i)); + } + #endif + pos += buflen_sel; + + free(buf_sel); + + // dumping length_rems + memcpy(*buf + pos, cs->length_rems, length_rems_size); + #ifdef DEBUG + for(i = 0; i < length_rems_size; i++) + { + DEBUGP("pos = %u -- length_rems_size = %u -- length_rems[%u] = %u\n", pos, length_rems_size, i, *(*buf + pos + i)); + } + #endif + pos += length_rems_size; + + // dumping store_table + memcpy(*buf + pos, cs->store_table, store_table_size); + + #ifdef DEBUG + for(i = 0; i < store_table_size; i++) + { + DEBUGP("pos = %u -- store_table_size = %u -- store_table[%u] = %u\n", pos, store_table_size, i, *(*buf + pos + i)); + } + #endif + DEBUGP("Dumped compressed sequence structure with size %u bytes\n", *buflen); +} + +void compressed_seq_load(compressed_seq_t * cs, const char * buf, cmph_uint32 buflen) +{ + register cmph_uint32 pos = 0; + cmph_uint32 buflen_sel = 0; + register cmph_uint32 length_rems_size = 0; + register cmph_uint32 store_table_size = 0; + + // loading n, rem_r and total_length + memcpy(&(cs->n), buf, sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + DEBUGP("n = %u\n", cs->n); + + memcpy(&(cs->rem_r), buf + pos, sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + DEBUGP("rem_r = %u\n", cs->rem_r); + + memcpy(&(cs->total_length), buf + pos, sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + DEBUGP("total_length = %u\n", cs->total_length); + + // loading sel + memcpy(&buflen_sel, buf + pos, sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + DEBUGP("buflen_sel = %u\n", buflen_sel); + + select_load(&cs->sel, buf + pos, buflen_sel); + #ifdef DEBUG + cmph_uint32 i = 0; + for(i = 0; i < buflen_sel; i++) + { + DEBUGP("pos = %u -- buf_sel[%u] = %u\n", pos, i, *(buf + pos + i)); + } + #endif + pos += buflen_sel; + + // loading length_rems + if(cs->length_rems) + { + free(cs->length_rems); + } + length_rems_size = BITS_TABLE_SIZE(cs->n, cs->rem_r); + cs->length_rems = (cmph_uint32 *) calloc(length_rems_size, sizeof(cmph_uint32)); + length_rems_size *= 4; + memcpy(cs->length_rems, buf + pos, length_rems_size); + + #ifdef DEBUG + for(i = 0; i < length_rems_size; i++) + { + DEBUGP("pos = %u -- length_rems_size = %u -- length_rems[%u] = %u\n", pos, length_rems_size, i, *(buf + pos + i)); + } + #endif + pos += length_rems_size; + + // loading store_table + store_table_size = ((cs->total_length + 31) >> 5); + if(cs->store_table) + { + free(cs->store_table); + } + cs->store_table = (cmph_uint32 *) calloc(store_table_size, sizeof(cmph_uint32)); + store_table_size *= 4; + memcpy(cs->store_table, buf + pos, store_table_size); + + #ifdef DEBUG + for(i = 0; i < store_table_size; i++) + { + DEBUGP("pos = %u -- store_table_size = %u -- store_table[%u] = %u\n", pos, store_table_size, i, *(buf + pos + i)); + } + #endif + + DEBUGP("Loaded compressed sequence structure with size %u bytes\n", buflen); +} + +void compressed_seq_pack(compressed_seq_t *cs, void *cs_packed) +{ + if (cs && cs_packed) + { + char *buf = NULL; + cmph_uint32 buflen = 0; + compressed_seq_dump(cs, &buf, &buflen); + memcpy(cs_packed, buf, buflen); + free(buf); + } + +} + +cmph_uint32 compressed_seq_packed_size(compressed_seq_t *cs) +{ + register cmph_uint32 sel_size = select_packed_size(&cs->sel); + register cmph_uint32 store_table_size = ((cs->total_length + 31) >> 5) * (cmph_uint32)sizeof(cmph_uint32); + register cmph_uint32 length_rems_size = BITS_TABLE_SIZE(cs->n, cs->rem_r) * (cmph_uint32)sizeof(cmph_uint32); + return 4 * (cmph_uint32)sizeof(cmph_uint32) + sel_size + store_table_size + length_rems_size; +} + + +cmph_uint32 compressed_seq_query_packed(void * cs_packed, cmph_uint32 idx) +{ + // unpacking cs_packed + register cmph_uint32 *ptr = (cmph_uint32 *)cs_packed; + register cmph_uint32 n = *ptr++; + register cmph_uint32 rem_r = *ptr++; + ptr++; // skipping total_length +// register cmph_uint32 total_length = *ptr++; + register cmph_uint32 buflen_sel = *ptr++; + register cmph_uint32 * sel_packed = ptr; + register cmph_uint32 * length_rems = (ptr += (buflen_sel >> 2)); + register cmph_uint32 length_rems_size = BITS_TABLE_SIZE(n, rem_r); + register cmph_uint32 * store_table = (ptr += length_rems_size); + + // compressed sequence query computation + register cmph_uint32 enc_idx, enc_length; + register cmph_uint32 rems_mask; + register cmph_uint32 stored_value; + register cmph_uint32 sel_res; + + rems_mask = (1U << rem_r) - 1U; + + if(idx == 0) + { + enc_idx = 0; + sel_res = select_query_packed(sel_packed, idx); + } + else + { + sel_res = select_query_packed(sel_packed, idx - 1); + + enc_idx = (sel_res - (idx - 1)) << rem_r; + enc_idx += get_bits_value(length_rems, idx-1, rem_r, rems_mask); + + sel_res = select_next_query_packed(sel_packed, sel_res); + }; + + enc_length = (sel_res - idx) << rem_r; + enc_length += get_bits_value(length_rems, idx, rem_r, rems_mask); + enc_length -= enc_idx; + if(enc_length == 0) + return 0; + + stored_value = get_bits_at_pos(store_table, enc_idx, enc_length); + return stored_value + ((1U << enc_length) - 1U); +} diff --git a/cmph/compressed_seq.h b/cmph/compressed_seq.h new file mode 100644 index 000000000..8d87fc700 --- /dev/null +++ b/cmph/compressed_seq.h @@ -0,0 +1,84 @@ +#ifndef __CMPH_COMPRESSED_SEQ_H__ +#define __CMPH_COMPRESSED_SEQ_H__ + +#include"select.h" + +struct _compressed_seq_t +{ + cmph_uint32 n; // number of values stored in store_table + // The length in bits of each value is decomposed into two compnents: the lg(n) MSBs are stored in rank_select data structure + // the remaining LSBs are stored in a table of n cells, each one of rem_r bits. + cmph_uint32 rem_r; + cmph_uint32 total_length; // total length in bits of stored_table + select_t sel; + cmph_uint32 * length_rems; + cmph_uint32 * store_table; +}; + +typedef struct _compressed_seq_t compressed_seq_t; + +/** \fn void compressed_seq_init(compressed_seq_t * cs); + * \brief Initialize a compressed sequence structure. + * \param cs points to the compressed sequence structure to be initialized + */ +void compressed_seq_init(compressed_seq_t * cs); + +/** \fn void compressed_seq_destroy(compressed_seq_t * cs); + * \brief Destroy a compressed sequence given as input. + * \param cs points to the compressed sequence structure to be destroyed + */ +void compressed_seq_destroy(compressed_seq_t * cs); + +/** \fn void compressed_seq_generate(compressed_seq_t * cs, cmph_uint32 * vals_table, cmph_uint32 n); + * \brief Generate a compressed sequence from an input array with n values. + * \param cs points to the compressed sequence structure + * \param vals_table poiter to the array given as input + * \param n number of values in @see vals_table + */ +void compressed_seq_generate(compressed_seq_t * cs, cmph_uint32 * vals_table, cmph_uint32 n); + + +/** \fn cmph_uint32 compressed_seq_query(compressed_seq_t * cs, cmph_uint32 idx); + * \brief Returns the value stored at index @see idx of the compressed sequence structure. + * \param cs points to the compressed sequence structure + * \param idx index to retrieve the value from + * \return the value stored at index @see idx of the compressed sequence structure + */ +cmph_uint32 compressed_seq_query(compressed_seq_t * cs, cmph_uint32 idx); + + +/** \fn cmph_uint32 compressed_seq_get_space_usage(compressed_seq_t * cs); + * \brief Returns amount of space (in bits) to store the compressed sequence. + * \param cs points to the compressed sequence structure + * \return the amount of space (in bits) to store @see cs + */ +cmph_uint32 compressed_seq_get_space_usage(compressed_seq_t * cs); + +void compressed_seq_dump(compressed_seq_t * cs, char ** buf, cmph_uint32 * buflen); + +void compressed_seq_load(compressed_seq_t * cs, const char * buf, cmph_uint32 buflen); + + +/** \fn void compressed_seq_pack(compressed_seq_t *cs, void *cs_packed); + * \brief Support the ability to pack a compressed sequence structure into a preallocated contiguous memory space pointed by cs_packed. + * \param cs points to the compressed sequence structure + * \param cs_packed pointer to the contiguous memory area used to store the compressed sequence structure. The size of cs_packed must be at least @see compressed_seq_packed_size + */ +void compressed_seq_pack(compressed_seq_t *cs, void *cs_packed); + +/** \fn cmph_uint32 compressed_seq_packed_size(compressed_seq_t *cs); + * \brief Return the amount of space needed to pack a compressed sequence structure. + * \return the size of the packed compressed sequence structure or zero for failures + */ +cmph_uint32 compressed_seq_packed_size(compressed_seq_t *cs); + + +/** \fn cmph_uint32 compressed_seq_query_packed(void * cs_packed, cmph_uint32 idx); + * \brief Returns the value stored at index @see idx of the packed compressed sequence structure. + * \param cs_packed is a pointer to a contiguous memory area + * \param idx is the index to retrieve the value from + * \return the value stored at index @see idx of the packed compressed sequence structure + */ +cmph_uint32 compressed_seq_query_packed(void * cs_packed, cmph_uint32 idx); + +#endif diff --git a/cmph/debug.h b/cmph/debug.h new file mode 100644 index 000000000..0f7ddb139 --- /dev/null +++ b/cmph/debug.h @@ -0,0 +1,53 @@ +#ifdef DEBUGP +#undef DEBUGP +#endif + +#ifdef __cplusplus +#include +#ifdef WIN32 +#include +#endif +#else +#include +#ifdef WIN32 +#include +#endif +#endif + +#ifndef __GNUC__ +#ifndef __DEBUG_H__ +#define __DEBUG_H__ +#include +static void debugprintf(const char *format, ...) +{ + va_list ap; + char *f = NULL; + const char *p="%s:%d "; + size_t plen = strlen(p); + va_start(ap, format); + f = (char *)malloc(plen + strlen(format) + 1); + if (!f) return; + memcpy(f, p, plen); + memcpy(f + plen, format, strlen(format) + 1); + vfprintf(stderr, f, ap); + va_end(ap); + free(f); +} +static void dummyprintf(const char *format, ...) +{} +#endif +#endif + +#ifdef DEBUG +#ifndef __GNUC__ +#define DEBUGP debugprintf +#else +#define DEBUGP(args...) do { fprintf(stderr, "%s:%d ", __FILE__, __LINE__); fprintf(stderr, ## args); } while(0) +#endif +#else +#ifndef __GNUC__ +#define DEBUGP dummyprintf +#else +#define DEBUGP(args...) +#endif +#endif diff --git a/cmph/djb2_hash.c b/cmph/djb2_hash.c new file mode 100644 index 000000000..d3b4330ab --- /dev/null +++ b/cmph/djb2_hash.c @@ -0,0 +1,49 @@ +#include "djb2_hash.h" +#include + +djb2_state_t *djb2_state_new() +{ + djb2_state_t *state = (djb2_state_t *)malloc(sizeof(djb2_state_t)); + state->hashfunc = CMPH_HASH_DJB2; + return state; +} + +void djb2_state_destroy(djb2_state_t *state) +{ + free(state); +} + +cmph_uint32 djb2_hash(djb2_state_t *state, const char *k, cmph_uint32 keylen) +{ + register cmph_uint32 hash = 5381; + const unsigned char *ptr = (unsigned char *)k; + cmph_uint32 i = 0; + while (i < keylen) + { + hash = hash*33 ^ *ptr; + ++ptr, ++i; + } + return hash; +} + + +void djb2_state_dump(djb2_state_t *state, char **buf, cmph_uint32 *buflen) +{ + *buf = NULL; + *buflen = 0; + return; +} + +djb2_state_t *djb2_state_copy(djb2_state_t *src_state) +{ + djb2_state_t *dest_state = (djb2_state_t *)malloc(sizeof(djb2_state_t)); + dest_state->hashfunc = src_state->hashfunc; + return dest_state; +} + +djb2_state_t *djb2_state_load(const char *buf, cmph_uint32 buflen) +{ + djb2_state_t *state = (djb2_state_t *)malloc(sizeof(djb2_state_t)); + state->hashfunc = CMPH_HASH_DJB2; + return state; +} diff --git a/cmph/djb2_hash.h b/cmph/djb2_hash.h new file mode 100644 index 000000000..dda97e317 --- /dev/null +++ b/cmph/djb2_hash.h @@ -0,0 +1,18 @@ +#ifndef __DJB2_HASH_H__ +#define __DJB2_HASH_H__ + +#include "hash.h" + +typedef struct __djb2_state_t +{ + CMPH_HASH hashfunc; +} djb2_state_t; + +djb2_state_t *djb2_state_new(); +cmph_uint32 djb2_hash(djb2_state_t *state, const char *k, cmph_uint32 keylen); +void djb2_state_dump(djb2_state_t *state, char **buf, cmph_uint32 *buflen); +djb2_state_t *djb2_state_copy(djb2_state_t *src_state); +djb2_state_t *djb2_state_load(const char *buf, cmph_uint32 buflen); +void djb2_state_destroy(djb2_state_t *state); + +#endif diff --git a/cmph/fch.c b/cmph/fch.c new file mode 100644 index 000000000..67b68fbbe --- /dev/null +++ b/cmph/fch.c @@ -0,0 +1,517 @@ +#include "fch.h" +#include "cmph_structs.h" +#include "fch_structs.h" +#include "hash.h" +#include "bitbool.h" +#include "fch_buckets.h" +#include +#include +#include +#include +#include +#define INDEX 0 /* alignment index within a bucket */ +//#define DEBUG +#include "debug.h" + +static fch_buckets_t * mapping(cmph_config_t *mph); +static cmph_uint32 * ordering(fch_buckets_t * buckets); +static cmph_uint8 check_for_collisions_h2(fch_config_data_t *fch, fch_buckets_t * buckets, cmph_uint32 *sorted_indexes); +static void permut(cmph_uint32 * vector, cmph_uint32 n); +static cmph_uint8 searching(fch_config_data_t *fch, fch_buckets_t *buckets, cmph_uint32 *sorted_indexes); + +fch_config_data_t *fch_config_new() +{ + fch_config_data_t *fch; + fch = (fch_config_data_t *)malloc(sizeof(fch_config_data_t)); + assert(fch); + memset(fch, 0, sizeof(fch_config_data_t)); + fch->hashfuncs[0] = CMPH_HASH_JENKINS; + fch->hashfuncs[1] = CMPH_HASH_JENKINS; + fch->m = fch->b = 0; + fch->c = fch->p1 = fch->p2 = 0.0; + fch->g = NULL; + fch->h1 = NULL; + fch->h2 = NULL; + return fch; +} + +void fch_config_destroy(cmph_config_t *mph) +{ + fch_config_data_t *data = (fch_config_data_t *)mph->data; + //DEBUGP("Destroying algorithm dependent data\n"); + free(data); +} + +void fch_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs) +{ + fch_config_data_t *fch = (fch_config_data_t *)mph->data; + CMPH_HASH *hashptr = hashfuncs; + cmph_uint32 i = 0; + while(*hashptr != CMPH_HASH_COUNT) + { + if (i >= 2) break; //fch only uses two hash functions + fch->hashfuncs[i] = *hashptr; + ++i, ++hashptr; + } +} + +cmph_uint32 mixh10h11h12(cmph_uint32 b, double p1, double p2, cmph_uint32 initial_index) +{ + register cmph_uint32 int_p2 = (cmph_uint32)p2; + if (initial_index < p1) initial_index %= int_p2; /* h11 o h10 */ + else { /* h12 o h10 */ + initial_index %= b; + if(initial_index < p2) initial_index += int_p2; + } + return initial_index; +} + + +cmph_uint32 fch_calc_b(double c, cmph_uint32 m) +{ + return (cmph_uint32)ceil((c*m)/(log((double)m)/log(2.0) + 1)); +} + +double fch_calc_p1(cmph_uint32 m) +{ + return ceil(0.55*m); +} + +double fch_calc_p2(cmph_uint32 b) +{ + return ceil(0.3*b); +} + +static fch_buckets_t * mapping(cmph_config_t *mph) +{ + cmph_uint32 i = 0; + fch_buckets_t *buckets = NULL; + fch_config_data_t *fch = (fch_config_data_t *)mph->data; + if (fch->h1) hash_state_destroy(fch->h1); + fch->h1 = hash_state_new(fch->hashfuncs[0], fch->m); + fch->b = fch_calc_b(fch->c, fch->m); + fch->p1 = fch_calc_p1(fch->m); + fch->p2 = fch_calc_p2(fch->b); + //DEBUGP("b:%u p1:%f p2:%f\n", fch->b, fch->p1, fch->p2); + buckets = fch_buckets_new(fch->b); + + mph->key_source->rewind(mph->key_source->data); + for(i = 0; i < fch->m; i++) + { + cmph_uint32 h1, keylen; + char *key = NULL; + mph->key_source->read(mph->key_source->data, &key, &keylen); + h1 = hash(fch->h1, key, keylen) % fch->m; + h1 = mixh10h11h12 (fch->b, fch->p1, fch->p2, h1); + fch_buckets_insert(buckets, h1, key, keylen); + key = NULL; // transger memory ownership + + } + return buckets; +} + + +// returns the buckets indexes sorted by their sizes. +static cmph_uint32 * ordering(fch_buckets_t * buckets) +{ + return fch_buckets_get_indexes_sorted_by_size(buckets); +} + +/* Check whether function h2 causes collisions among the keys of each bucket */ +static cmph_uint8 check_for_collisions_h2(fch_config_data_t *fch, fch_buckets_t * buckets, cmph_uint32 *sorted_indexes) +{ + //cmph_uint32 max_size = fch_buckets_get_max_size(buckets); + cmph_uint8 * hashtable = (cmph_uint8 *)calloc((size_t)fch->m, sizeof(cmph_uint8)); + cmph_uint32 nbuckets = fch_buckets_get_nbuckets(buckets); + cmph_uint32 i = 0, index = 0, j =0; + for (i = 0; i < nbuckets; i++) + { + cmph_uint32 nkeys = fch_buckets_get_size(buckets, sorted_indexes[i]); + memset(hashtable, 0, (size_t)fch->m); + //DEBUGP("bucket %u -- nkeys: %u\n", i, nkeys); + for (j = 0; j < nkeys; j++) + { + char * key = fch_buckets_get_key(buckets, sorted_indexes[i], j); + cmph_uint32 keylen = fch_buckets_get_keylength(buckets, sorted_indexes[i], j); + index = hash(fch->h2, key, keylen) % fch->m; + if(hashtable[index]) { // collision detected + free(hashtable); + return 1; + } + hashtable[index] = 1; + } + } + free(hashtable); + return 0; +} + +static void permut(cmph_uint32 * vector, cmph_uint32 n) +{ + cmph_uint32 i, j, b; + for (i = 0; i < n; i++) { + j = (cmph_uint32) rand() % n; + b = vector[i]; + vector[i] = vector[j]; + vector[j] = b; + } +} + +static cmph_uint8 searching(fch_config_data_t *fch, fch_buckets_t *buckets, cmph_uint32 *sorted_indexes) +{ + cmph_uint32 * random_table = (cmph_uint32 *) calloc((size_t)fch->m, sizeof(cmph_uint32)); + cmph_uint32 * map_table = (cmph_uint32 *) calloc((size_t)fch->m, sizeof(cmph_uint32)); + cmph_uint32 iteration_to_generate_h2 = 0; + cmph_uint32 searching_iterations = 0; + cmph_uint8 restart = 0; + cmph_uint32 nbuckets = fch_buckets_get_nbuckets(buckets); + cmph_uint32 i, j, z, counter = 0, filled_count = 0; + if (fch->g) free (fch->g); + fch->g = (cmph_uint32 *) calloc((size_t)fch->b, sizeof(cmph_uint32)); + + //DEBUGP("max bucket size: %u\n", fch_buckets_get_max_size(buckets)); + + for(i = 0; i < fch->m; i++) + { + random_table[i] = i; + } + permut(random_table, fch->m); + for(i = 0; i < fch->m; i++) + { + map_table[random_table[i]] = i; + } + do { + if (fch->h2) hash_state_destroy(fch->h2); + fch->h2 = hash_state_new(fch->hashfuncs[1], fch->m); + restart = check_for_collisions_h2(fch, buckets, sorted_indexes); + filled_count = 0; + if (!restart) + { + searching_iterations++; iteration_to_generate_h2 = 0; + //DEBUGP("searching_iterations: %u\n", searching_iterations); + } + else { + iteration_to_generate_h2++; + //DEBUGP("iteration_to_generate_h2: %u\n", iteration_to_generate_h2); + } + for(i = 0; (i < nbuckets) && !restart; i++) { + cmph_uint32 bucketsize = fch_buckets_get_size(buckets, sorted_indexes[i]); + if (bucketsize == 0) + { + restart = 0; // false + break; + } + else restart = 1; // true + for(z = 0; (z < (fch->m - filled_count)) && restart; z++) { + char * key = fch_buckets_get_key(buckets, sorted_indexes[i], INDEX); + cmph_uint32 keylen = fch_buckets_get_keylength(buckets, sorted_indexes[i], INDEX); + cmph_uint32 h2 = hash(fch->h2, key, keylen) % fch->m; + counter = 0; + restart = 0; // false + fch->g[sorted_indexes[i]] = (fch->m + random_table[filled_count + z] - h2) % fch->m; + //DEBUGP("g[%u]: %u\n", sorted_indexes[i], fch->g[sorted_indexes[i]]); + j = INDEX; + do { + cmph_uint32 index = 0; + key = fch_buckets_get_key(buckets, sorted_indexes[i], j); + keylen = fch_buckets_get_keylength(buckets, sorted_indexes[i], j); + h2 = hash(fch->h2, key, keylen) % fch->m; + index = (h2 + fch->g[sorted_indexes[i]]) % fch->m; + //DEBUGP("key:%s keylen:%u index: %u h2:%u bucketsize:%u\n", key, keylen, index, h2, bucketsize); + if (map_table[index] >= filled_count) { + cmph_uint32 y = map_table[index]; + cmph_uint32 ry = random_table[y]; + random_table[y] = random_table[filled_count]; + random_table[filled_count] = ry; + map_table[random_table[y]] = y; + map_table[random_table[filled_count]] = filled_count; + filled_count++; + counter ++; + } + else { + restart = 1; // true + filled_count = filled_count - counter; + counter = 0; + break; + } + j = (j + 1) % bucketsize; + } while(j % bucketsize != INDEX); + } + //getchar(); + } + } while(restart && (searching_iterations < 10) && (iteration_to_generate_h2 < 1000)); + free(map_table); + free(random_table); + return restart; +} + + + +cmph_t *fch_new(cmph_config_t *mph, double c) +{ + cmph_t *mphf = NULL; + fch_data_t *fchf = NULL; + cmph_uint32 iterations = 100; + cmph_uint8 restart_mapping = 0; + fch_buckets_t * buckets = NULL; + cmph_uint32 * sorted_indexes = NULL; + fch_config_data_t *fch = (fch_config_data_t *)mph->data; + fch->m = mph->key_source->nkeys; + //DEBUGP("m: %f\n", fch->m); + if (c <= 2) c = 2.6; // validating restrictions over parameter c. + fch->c = c; + //DEBUGP("c: %f\n", fch->c); + fch->h1 = NULL; + fch->h2 = NULL; + fch->g = NULL; + do + { + if (mph->verbosity) + { + fprintf(stderr, "Entering mapping step for mph creation of %u keys\n", fch->m); + } + if (buckets) fch_buckets_destroy(buckets); + buckets = mapping(mph); + if (mph->verbosity) + { + fprintf(stderr, "Starting ordering step\n"); + } + if (sorted_indexes) free (sorted_indexes); + sorted_indexes = ordering(buckets); + if (mph->verbosity) + { + fprintf(stderr, "Starting searching step.\n"); + } + restart_mapping = searching(fch, buckets, sorted_indexes); + iterations--; + + } while(restart_mapping && iterations > 0); + if (buckets) fch_buckets_destroy(buckets); + if (sorted_indexes) free (sorted_indexes); + if (iterations == 0) return NULL; + mphf = (cmph_t *)malloc(sizeof(cmph_t)); + mphf->algo = mph->algo; + fchf = (fch_data_t *)malloc(sizeof(fch_data_t)); + fchf->g = fch->g; + fch->g = NULL; //transfer memory ownership + fchf->h1 = fch->h1; + fch->h1 = NULL; //transfer memory ownership + fchf->h2 = fch->h2; + fch->h2 = NULL; //transfer memory ownership + fchf->p2 = fch->p2; + fchf->p1 = fch->p1; + fchf->b = fch->b; + fchf->c = fch->c; + fchf->m = fch->m; + mphf->data = fchf; + mphf->size = fch->m; + //DEBUGP("Successfully generated minimal perfect hash\n"); + if (mph->verbosity) + { + fprintf(stderr, "Successfully generated minimal perfect hash function\n"); + } + return mphf; +} + +int fch_dump(cmph_t *mphf, FILE *fd) +{ + char *buf = NULL; + cmph_uint32 buflen; + register size_t nbytes; + + fch_data_t *data = (fch_data_t *)mphf->data; + __cmph_dump(mphf, fd); + + hash_state_dump(data->h1, &buf, &buflen); + //DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); + nbytes = fwrite(&buflen, sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(buf, (size_t)buflen, (size_t)1, fd); + free(buf); + + hash_state_dump(data->h2, &buf, &buflen); + //DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); + nbytes = fwrite(&buflen, sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(buf, (size_t)buflen, (size_t)1, fd); + free(buf); + + nbytes = fwrite(&(data->m), sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(&(data->c), sizeof(double), (size_t)1, fd); + nbytes = fwrite(&(data->b), sizeof(cmph_uint32), (size_t)1, fd); + nbytes = fwrite(&(data->p1), sizeof(double), (size_t)1, fd); + nbytes = fwrite(&(data->p2), sizeof(double), (size_t)1, fd); + nbytes = fwrite(data->g, sizeof(cmph_uint32)*(data->b), (size_t)1, fd); + #ifdef DEBUG + cmph_uint32 i; + fprintf(stderr, "G: "); + for (i = 0; i < data->b; ++i) fprintf(stderr, "%u ", data->g[i]); + fprintf(stderr, "\n"); + #endif + return 1; +} + +void fch_load(FILE *f, cmph_t *mphf) +{ + char *buf = NULL; + cmph_uint32 buflen; + register size_t nbytes; + fch_data_t *fch = (fch_data_t *)malloc(sizeof(fch_data_t)); + + //DEBUGP("Loading fch mphf\n"); + mphf->data = fch; + //DEBUGP("Reading h1\n"); + fch->h1 = NULL; + nbytes = fread(&buflen, sizeof(cmph_uint32), (size_t)1, f); + //DEBUGP("Hash state of h1 has %u bytes\n", buflen); + buf = (char *)malloc((size_t)buflen); + nbytes = fread(buf, (size_t)buflen, (size_t)1, f); + fch->h1 = hash_state_load(buf, buflen); + free(buf); + + //DEBUGP("Loading fch mphf\n"); + mphf->data = fch; + //DEBUGP("Reading h2\n"); + fch->h2 = NULL; + nbytes = fread(&buflen, sizeof(cmph_uint32), (size_t)1, f); + //DEBUGP("Hash state of h2 has %u bytes\n", buflen); + buf = (char *)malloc((size_t)buflen); + nbytes = fread(buf, (size_t)buflen, (size_t)1, f); + fch->h2 = hash_state_load(buf, buflen); + free(buf); + + + //DEBUGP("Reading m and n\n"); + nbytes = fread(&(fch->m), sizeof(cmph_uint32), (size_t)1, f); + nbytes = fread(&(fch->c), sizeof(double), (size_t)1, f); + nbytes = fread(&(fch->b), sizeof(cmph_uint32), (size_t)1, f); + nbytes = fread(&(fch->p1), sizeof(double), (size_t)1, f); + nbytes = fread(&(fch->p2), sizeof(double), (size_t)1, f); + + fch->g = (cmph_uint32 *)malloc(sizeof(cmph_uint32)*fch->b); + nbytes = fread(fch->g, fch->b*sizeof(cmph_uint32), (size_t)1, f); + #ifdef DEBUG + cmph_uint32 i; + fprintf(stderr, "G: "); + for (i = 0; i < fch->b; ++i) fprintf(stderr, "%u ", fch->g[i]); + fprintf(stderr, "\n"); + #endif + return; +} + +cmph_uint32 fch_search(cmph_t *mphf, const char *key, cmph_uint32 keylen) +{ + fch_data_t *fch = mphf->data; + cmph_uint32 h1 = hash(fch->h1, key, keylen) % fch->m; + cmph_uint32 h2 = hash(fch->h2, key, keylen) % fch->m; + h1 = mixh10h11h12 (fch->b, fch->p1, fch->p2, h1); + //DEBUGP("key: %s h1: %u h2: %u g[h1]: %u\n", key, h1, h2, fch->g[h1]); + return (h2 + fch->g[h1]) % fch->m; +} +void fch_destroy(cmph_t *mphf) +{ + fch_data_t *data = (fch_data_t *)mphf->data; + free(data->g); + hash_state_destroy(data->h1); + hash_state_destroy(data->h2); + free(data); + free(mphf); +} + +/** \fn void fch_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void fch_pack(cmph_t *mphf, void *packed_mphf) +{ + fch_data_t *data = (fch_data_t *)mphf->data; + cmph_uint8 * ptr = packed_mphf; + + // packing h1 type + CMPH_HASH h1_type = hash_get_type(data->h1); + *((cmph_uint32 *) ptr) = h1_type; + ptr += sizeof(cmph_uint32); + + // packing h1 + hash_state_pack(data->h1, ptr); + ptr += hash_state_packed_size(h1_type); + + // packing h2 type + CMPH_HASH h2_type = hash_get_type(data->h2); + *((cmph_uint32 *) ptr) = h2_type; + ptr += sizeof(cmph_uint32); + + // packing h2 + hash_state_pack(data->h2, ptr); + ptr += hash_state_packed_size(h2_type); + + // packing m + *((cmph_uint32 *) ptr) = data->m; + ptr += sizeof(data->m); + + // packing b + *((cmph_uint32 *) ptr) = data->b; + ptr += sizeof(data->b); + + // packing p1 + *((cmph_uint64 *)ptr) = (cmph_uint64)data->p1; + ptr += sizeof(data->p1); + + // packing p2 + *((cmph_uint64 *)ptr) = (cmph_uint64)data->p2; + ptr += sizeof(data->p2); + + // packing g + memcpy(ptr, data->g, sizeof(cmph_uint32)*(data->b)); +} + +/** \fn cmph_uint32 fch_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 fch_packed_size(cmph_t *mphf) +{ + fch_data_t *data = (fch_data_t *)mphf->data; + CMPH_HASH h1_type = hash_get_type(data->h1); + CMPH_HASH h2_type = hash_get_type(data->h2); + + return (cmph_uint32)(sizeof(CMPH_ALGO) + hash_state_packed_size(h1_type) + hash_state_packed_size(h2_type) + + 4*sizeof(cmph_uint32) + 2*sizeof(double) + sizeof(cmph_uint32)*(data->b)); +} + + +/** cmph_uint32 fch_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint32 fch_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen) +{ + register cmph_uint8 *h1_ptr = packed_mphf; + register CMPH_HASH h1_type = *((cmph_uint32 *)h1_ptr); + h1_ptr += 4; + + register cmph_uint8 *h2_ptr = h1_ptr + hash_state_packed_size(h1_type); + register CMPH_HASH h2_type = *((cmph_uint32 *)h2_ptr); + h2_ptr += 4; + + register cmph_uint32 *g_ptr = (cmph_uint32 *)(h2_ptr + hash_state_packed_size(h2_type)); + + register cmph_uint32 m = *g_ptr++; + + register cmph_uint32 b = *g_ptr++; + + register double p1 = (double)(*((cmph_uint64 *)g_ptr)); + g_ptr += 2; + + register double p2 = (double)(*((cmph_uint64 *)g_ptr)); + g_ptr += 2; + + register cmph_uint32 h1 = hash_packed(h1_ptr, h1_type, key, keylen) % m; + register cmph_uint32 h2 = hash_packed(h2_ptr, h2_type, key, keylen) % m; + + h1 = mixh10h11h12 (b, p1, p2, h1); + return (h2 + g_ptr[h1]) % m; +} + diff --git a/cmph/fch.h b/cmph/fch.h new file mode 100644 index 000000000..ec4f0f5b0 --- /dev/null +++ b/cmph/fch.h @@ -0,0 +1,48 @@ +#ifndef __CMPH_FCH_H__ +#define __CMPH_FCH_H__ + +#include "cmph.h" + +typedef struct __fch_data_t fch_data_t; +typedef struct __fch_config_data_t fch_config_data_t; + +/* Parameters calculation */ +cmph_uint32 fch_calc_b(double c, cmph_uint32 m); +double fch_calc_p1(cmph_uint32 m); +double fch_calc_p2(cmph_uint32 b); +cmph_uint32 mixh10h11h12(cmph_uint32 b, double p1, double p2, cmph_uint32 initial_index); + +fch_config_data_t *fch_config_new(); +void fch_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); +void fch_config_destroy(cmph_config_t *mph); +cmph_t *fch_new(cmph_config_t *mph, double c); + +void fch_load(FILE *f, cmph_t *mphf); +int fch_dump(cmph_t *mphf, FILE *f); +void fch_destroy(cmph_t *mphf); +cmph_uint32 fch_search(cmph_t *mphf, const char *key, cmph_uint32 keylen); + +/** \fn void fch_pack(cmph_t *mphf, void *packed_mphf); + * \brief Support the ability to pack a perfect hash function into a preallocated contiguous memory space pointed by packed_mphf. + * \param mphf pointer to the resulting mphf + * \param packed_mphf pointer to the contiguous memory area used to store the resulting mphf. The size of packed_mphf must be at least cmph_packed_size() + */ +void fch_pack(cmph_t *mphf, void *packed_mphf); + +/** \fn cmph_uint32 fch_packed_size(cmph_t *mphf); + * \brief Return the amount of space needed to pack mphf. + * \param mphf pointer to a mphf + * \return the size of the packed function or zero for failures + */ +cmph_uint32 fch_packed_size(cmph_t *mphf); + +/** cmph_uint32 fch_search(void *packed_mphf, const char *key, cmph_uint32 keylen); + * \brief Use the packed mphf to do a search. + * \param packed_mphf pointer to the packed mphf + * \param key key to be hashed + * \param keylen key legth in bytes + * \return The mphf value + */ +cmph_uint32 fch_search_packed(void *packed_mphf, const char *key, cmph_uint32 keylen); + +#endif diff --git a/cmph/fch_buckets.c b/cmph/fch_buckets.c new file mode 100644 index 000000000..24b98e672 --- /dev/null +++ b/cmph/fch_buckets.c @@ -0,0 +1,214 @@ +#include "vqueue.h" +#include "fch_buckets.h" +#include +#include +#include +//#define DEBUG +#include "debug.h" + +typedef struct __fch_bucket_entry_t +{ + char * value; + cmph_uint32 length; +} fch_bucket_entry_t; + +typedef struct __fch_bucket_t +{ + fch_bucket_entry_t * entries; + cmph_uint32 capacity, size; +} fch_bucket_t; + + + +static void fch_bucket_new(fch_bucket_t *bucket) +{ + assert(bucket); + bucket->size = 0; + bucket->entries = NULL; + bucket->capacity = 0; +} + +static void fch_bucket_destroy(fch_bucket_t *bucket) +{ + cmph_uint32 i; + assert(bucket); + for (i = 0; i < bucket->size; i++) + { + free((bucket->entries + i)->value); + } + free(bucket->entries); +} + + +static void fch_bucket_reserve(fch_bucket_t *bucket, cmph_uint32 size) +{ + assert(bucket); + if (bucket->capacity < size) + { + cmph_uint32 new_capacity = bucket->capacity + 1; + DEBUGP("Increasing current capacity %u to %u\n", bucket->capacity, size); + while (new_capacity < size) + { + new_capacity *= 2; + } + bucket->entries = (fch_bucket_entry_t *)realloc(bucket->entries, sizeof(fch_bucket_entry_t)*new_capacity); + assert(bucket->entries); + bucket->capacity = new_capacity; + DEBUGP("Increased\n"); + } +} + +static void fch_bucket_insert(fch_bucket_t *bucket, char *val, cmph_uint32 val_length) +{ + assert(bucket); + fch_bucket_reserve(bucket, bucket->size + 1); + (bucket->entries + bucket->size)->value = val; + (bucket->entries + bucket->size)->length = val_length; + ++(bucket->size); +} + + +static cmph_uint8 fch_bucket_is_empty(fch_bucket_t *bucket) +{ + assert(bucket); + return (cmph_uint8)(bucket->size == 0); +} + +static cmph_uint32 fch_bucket_size(fch_bucket_t *bucket) +{ + assert(bucket); + return bucket->size; +} + +static char * fch_bucket_get_key(fch_bucket_t *bucket, cmph_uint32 index_key) +{ + assert(bucket); assert(index_key < bucket->size); + return (bucket->entries + index_key)->value; +} + +static cmph_uint32 fch_bucket_get_length(fch_bucket_t *bucket, cmph_uint32 index_key) +{ + assert(bucket); assert(index_key < bucket->size); + return (bucket->entries + index_key)->length; +} + +static void fch_bucket_print(fch_bucket_t * bucket, cmph_uint32 index) +{ + cmph_uint32 i; + assert(bucket); + fprintf(stderr, "Printing bucket %u ...\n", index); + for (i = 0; i < bucket->size; i++) + { + fprintf(stderr, " key: %s\n", (bucket->entries + i)->value); + } +} + +////////////////////////////////////////////////////////////////////////////////////// + +struct __fch_buckets_t +{ + fch_bucket_t * values; + cmph_uint32 nbuckets, max_size; + +}; + +fch_buckets_t * fch_buckets_new(cmph_uint32 nbuckets) +{ + cmph_uint32 i; + fch_buckets_t *buckets = (fch_buckets_t *)malloc(sizeof(fch_buckets_t)); + assert(buckets); + buckets->values = (fch_bucket_t *)calloc((size_t)nbuckets, sizeof(fch_bucket_t)); + for (i = 0; i < nbuckets; i++) fch_bucket_new(buckets->values + i); + assert(buckets->values); + buckets->nbuckets = nbuckets; + buckets->max_size = 0; + return buckets; +} + +cmph_uint8 fch_buckets_is_empty(fch_buckets_t * buckets, cmph_uint32 index) +{ + assert(index < buckets->nbuckets); + return fch_bucket_is_empty(buckets->values + index); +} + +void fch_buckets_insert(fch_buckets_t * buckets, cmph_uint32 index, char * key, cmph_uint32 length) +{ + assert(index < buckets->nbuckets); + fch_bucket_insert(buckets->values + index, key, length); + if (fch_bucket_size(buckets->values + index) > buckets->max_size) + { + buckets->max_size = fch_bucket_size(buckets->values + index); + } +} + +cmph_uint32 fch_buckets_get_size(fch_buckets_t * buckets, cmph_uint32 index) +{ + assert(index < buckets->nbuckets); + return fch_bucket_size(buckets->values + index); +} + + +char * fch_buckets_get_key(fch_buckets_t * buckets, cmph_uint32 index, cmph_uint32 index_key) +{ + assert(index < buckets->nbuckets); + return fch_bucket_get_key(buckets->values + index, index_key); +} + +cmph_uint32 fch_buckets_get_keylength(fch_buckets_t * buckets, cmph_uint32 index, cmph_uint32 index_key) +{ + assert(index < buckets->nbuckets); + return fch_bucket_get_length(buckets->values + index, index_key); +} + +cmph_uint32 fch_buckets_get_max_size(fch_buckets_t * buckets) +{ + return buckets->max_size; +} + +cmph_uint32 fch_buckets_get_nbuckets(fch_buckets_t * buckets) +{ + return buckets->nbuckets; +} + +cmph_uint32 * fch_buckets_get_indexes_sorted_by_size(fch_buckets_t * buckets) +{ + int i = 0; + cmph_uint32 sum = 0, value; + cmph_uint32 *nbuckets_size = (cmph_uint32 *) calloc((size_t)buckets->max_size + 1, sizeof(cmph_uint32)); + cmph_uint32 * sorted_indexes = (cmph_uint32 *) calloc((size_t)buckets->nbuckets, sizeof(cmph_uint32)); + + // collect how many buckets for each size. + for(i = 0; i < buckets->nbuckets; i++) nbuckets_size[fch_bucket_size(buckets->values + i)] ++; + + // calculating offset considering a decreasing order of buckets size. + value = nbuckets_size[buckets->max_size]; + nbuckets_size[buckets->max_size] = sum; + for(i = (int)buckets->max_size - 1; i >= 0; i--) + { + sum += value; + value = nbuckets_size[i]; + nbuckets_size[i] = sum; + + } + for(i = 0; i < buckets->nbuckets; i++) + { + sorted_indexes[nbuckets_size[fch_bucket_size(buckets->values + i)]] = (cmph_uint32)i; + nbuckets_size[fch_bucket_size(buckets->values + i)] ++; + } + free(nbuckets_size); + return sorted_indexes; +} + +void fch_buckets_print(fch_buckets_t * buckets) +{ + cmph_uint32 i; + for (i = 0; i < buckets->nbuckets; i++) fch_bucket_print(buckets->values + i, i); +} + +void fch_buckets_destroy(fch_buckets_t * buckets) +{ + cmph_uint32 i; + for (i = 0; i < buckets->nbuckets; i++) fch_bucket_destroy(buckets->values + i); + free(buckets->values); + free(buckets); +} diff --git a/cmph/fch_buckets.h b/cmph/fch_buckets.h new file mode 100644 index 000000000..2a1b8b2a6 --- /dev/null +++ b/cmph/fch_buckets.h @@ -0,0 +1,30 @@ +#ifndef __CMPH_FCH_BUCKETS_H__ +#define __CMPH_FCH_BUCKETS_H__ + +#include "cmph_types.h" +typedef struct __fch_buckets_t fch_buckets_t; + +fch_buckets_t * fch_buckets_new(cmph_uint32 nbuckets); + +cmph_uint8 fch_buckets_is_empty(fch_buckets_t * buckets, cmph_uint32 index); + +void fch_buckets_insert(fch_buckets_t * buckets, cmph_uint32 index, char * key, cmph_uint32 length); + +cmph_uint32 fch_buckets_get_size(fch_buckets_t * buckets, cmph_uint32 index); + +char * fch_buckets_get_key(fch_buckets_t * buckets, cmph_uint32 index, cmph_uint32 index_key); + +cmph_uint32 fch_buckets_get_keylength(fch_buckets_t * buckets, cmph_uint32 index, cmph_uint32 index_key); + +// returns the size of biggest bucket. +cmph_uint32 fch_buckets_get_max_size(fch_buckets_t * buckets); + +// returns the number of buckets. +cmph_uint32 fch_buckets_get_nbuckets(fch_buckets_t * buckets); + +cmph_uint32 * fch_buckets_get_indexes_sorted_by_size(fch_buckets_t * buckets); + +void fch_buckets_print(fch_buckets_t * buckets); + +void fch_buckets_destroy(fch_buckets_t * buckets); +#endif diff --git a/cmph/fch_structs.h b/cmph/fch_structs.h new file mode 100755 index 000000000..fcd1555ea --- /dev/null +++ b/cmph/fch_structs.h @@ -0,0 +1,30 @@ +#ifndef __CMPH_FCH_STRUCTS_H__ +#define __CMPH_FCH_STRUCTS_H__ + +#include "hash_state.h" + +struct __fch_data_t +{ + cmph_uint32 m; // words count + double c; // constant c + cmph_uint32 b; // parameter b = ceil(c*m/(log(m)/log(2) + 1)). Don't need to be stored + double p1; // constant p1 = ceil(0.6*m). Don't need to be stored + double p2; // constant p2 = ceil(0.3*b). Don't need to be stored + cmph_uint32 *g; // g function. + hash_state_t *h1; // h10 function. + hash_state_t *h2; // h20 function. +}; + +struct __fch_config_data_t +{ + CMPH_HASH hashfuncs[2]; + cmph_uint32 m; // words count + double c; // constant c + cmph_uint32 b; // parameter b = ceil(c*m/(log(m)/log(2) + 1)). Don't need to be stored + double p1; // constant p1 = ceil(0.6*m). Don't need to be stored + double p2; // constant p2 = ceil(0.3*b). Don't need to be stored + cmph_uint32 *g; // g function. + hash_state_t *h1; // h10 function. + hash_state_t *h2; // h20 function. +}; +#endif diff --git a/cmph/fnv_hash.c b/cmph/fnv_hash.c new file mode 100644 index 000000000..aeaca8ff4 --- /dev/null +++ b/cmph/fnv_hash.c @@ -0,0 +1,53 @@ +#include "fnv_hash.h" +#include + +fnv_state_t *fnv_state_new() +{ + fnv_state_t *state = (fnv_state_t *)malloc(sizeof(fnv_state_t)); + state->hashfunc = CMPH_HASH_FNV; + return state; +} + +void fnv_state_destroy(fnv_state_t *state) +{ + free(state); +} + +cmph_uint32 fnv_hash(fnv_state_t *state, const char *k, cmph_uint32 keylen) +{ + const unsigned char *bp = (const unsigned char *)k; + const unsigned char *be = bp + keylen; + static unsigned int hval = 0; + + while (bp < be) + { + + //hval *= 0x01000193; good for non-gcc compiler + hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24); //good for gcc + + hval ^= *bp++; + } + return hval; +} + + +void fnv_state_dump(fnv_state_t *state, char **buf, cmph_uint32 *buflen) +{ + *buf = NULL; + *buflen = 0; + return; +} + +fnv_state_t * fnv_state_copy(fnv_state_t *src_state) +{ + fnv_state_t *dest_state = (fnv_state_t *)malloc(sizeof(fnv_state_t)); + dest_state->hashfunc = src_state->hashfunc; + return dest_state; +} + +fnv_state_t *fnv_state_load(const char *buf, cmph_uint32 buflen) +{ + fnv_state_t *state = (fnv_state_t *)malloc(sizeof(fnv_state_t)); + state->hashfunc = CMPH_HASH_FNV; + return state; +} diff --git a/cmph/fnv_hash.h b/cmph/fnv_hash.h new file mode 100644 index 000000000..7f5794657 --- /dev/null +++ b/cmph/fnv_hash.h @@ -0,0 +1,18 @@ +#ifndef __FNV_HASH_H__ +#define __FNV_HASH_H__ + +#include "hash.h" + +typedef struct __fnv_state_t +{ + CMPH_HASH hashfunc; +} fnv_state_t; + +fnv_state_t *fnv_state_new(); +cmph_uint32 fnv_hash(fnv_state_t *state, const char *k, cmph_uint32 keylen); +void fnv_state_dump(fnv_state_t *state, char **buf, cmph_uint32 *buflen); +fnv_state_t *fnv_state_copy(fnv_state_t *src_state); +fnv_state_t *fnv_state_load(const char *buf, cmph_uint32 buflen); +void fnv_state_destroy(fnv_state_t *state); + +#endif diff --git a/cmph/graph.c b/cmph/graph.c new file mode 100644 index 000000000..c29fd8b9c --- /dev/null +++ b/cmph/graph.c @@ -0,0 +1,338 @@ +#include "graph.h" + +#include +#include +#include +#include +#include +#include "vstack.h" +#include "bitbool.h" + +//#define DEBUG +#include "debug.h" + +/* static const cmph_uint8 bitmask[8] = { 1, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7 }; */ +/* #define GETBIT(array, i) (array[(i) / 8] & bitmask[(i) % 8]) */ +/* #define SETBIT(array, i) (array[(i) / 8] |= bitmask[(i) % 8]) */ +/* #define UNSETBIT(array, i) (array[(i) / 8] &= (~(bitmask[(i) % 8]))) */ + +#define abs_edge(e, i) (e % g->nedges + i * g->nedges) + +struct __graph_t +{ + cmph_uint32 nnodes; + cmph_uint32 nedges; + cmph_uint32 *edges; + cmph_uint32 *first; + cmph_uint32 *next; + cmph_uint8 *critical_nodes; /* included -- Fabiano*/ + cmph_uint32 ncritical_nodes; /* included -- Fabiano*/ + cmph_uint32 cedges; + int shrinking; +}; + +static cmph_uint32 EMPTY = UINT_MAX; + +graph_t *graph_new(cmph_uint32 nnodes, cmph_uint32 nedges) +{ + graph_t *graph = (graph_t *)malloc(sizeof(graph_t)); + if (!graph) return NULL; + + graph->edges = (cmph_uint32 *)malloc(sizeof(cmph_uint32) * 2 * nedges); + graph->next = (cmph_uint32 *)malloc(sizeof(cmph_uint32) * 2 * nedges); + graph->first = (cmph_uint32 *)malloc(sizeof(cmph_uint32) * nnodes); + graph->critical_nodes = NULL; /* included -- Fabiano*/ + graph->ncritical_nodes = 0; /* included -- Fabiano*/ + graph->nnodes = nnodes; + graph->nedges = nedges; + + graph_clear_edges(graph); + return graph; +} + + +void graph_destroy(graph_t *graph) +{ + DEBUGP("Destroying graph\n"); + free(graph->edges); + free(graph->first); + free(graph->next); + free(graph->critical_nodes); /* included -- Fabiano*/ + free(graph); + return; +} + +void graph_print(graph_t *g) +{ + cmph_uint32 i, e; + for (i = 0; i < g->nnodes; ++i) + { + DEBUGP("Printing edges connected to %u\n", i); + e = g->first[i]; + if (e != EMPTY) + { + printf("%u -> %u\n", g->edges[abs_edge(e, 0)], g->edges[abs_edge(e, 1)]); + while ((e = g->next[e]) != EMPTY) + { + printf("%u -> %u\n", g->edges[abs_edge(e, 0)], g->edges[abs_edge(e, 1)]); + } + } + + } + return; +} + +void graph_add_edge(graph_t *g, cmph_uint32 v1, cmph_uint32 v2) +{ + cmph_uint32 e = g->cedges; + + assert(v1 < g->nnodes); + assert(v2 < g->nnodes); + assert(e < g->nedges); + assert(!g->shrinking); + + g->next[e] = g->first[v1]; + g->first[v1] = e; + g->edges[e] = v2; + + g->next[e + g->nedges] = g->first[v2]; + g->first[v2] = e + g->nedges; + g->edges[e + g->nedges] = v1; + + ++(g->cedges); +} + +static int check_edge(graph_t *g, cmph_uint32 e, cmph_uint32 v1, cmph_uint32 v2) +{ + DEBUGP("Checking edge %u %u looking for %u %u\n", g->edges[abs_edge(e, 0)], g->edges[abs_edge(e, 1)], v1, v2); + if (g->edges[abs_edge(e, 0)] == v1 && g->edges[abs_edge(e, 1)] == v2) return 1; + if (g->edges[abs_edge(e, 0)] == v2 && g->edges[abs_edge(e, 1)] == v1) return 1; + return 0; +} + +cmph_uint32 graph_edge_id(graph_t *g, cmph_uint32 v1, cmph_uint32 v2) +{ + cmph_uint32 e; + e = g->first[v1]; + assert(e != EMPTY); + if (check_edge(g, e, v1, v2)) return abs_edge(e, 0); + do + { + e = g->next[e]; + assert(e != EMPTY); + } + while (!check_edge(g, e, v1, v2)); + return abs_edge(e, 0); +} +static void del_edge_point(graph_t *g, cmph_uint32 v1, cmph_uint32 v2) +{ + cmph_uint32 e, prev; + + DEBUGP("Deleting edge point %u %u\n", v1, v2); + e = g->first[v1]; + if (check_edge(g, e, v1, v2)) + { + g->first[v1] = g->next[e]; + //g->edges[e] = EMPTY; + DEBUGP("Deleted\n"); + return; + } + DEBUGP("Checking linked list\n"); + do + { + prev = e; + e = g->next[e]; + assert(e != EMPTY); + } + while (!check_edge(g, e, v1, v2)); + + g->next[prev] = g->next[e]; + //g->edges[e] = EMPTY; + DEBUGP("Deleted\n"); +} + + +void graph_del_edge(graph_t *g, cmph_uint32 v1, cmph_uint32 v2) +{ + g->shrinking = 1; + del_edge_point(g, v1, v2); + del_edge_point(g, v2, v1); +} + +void graph_clear_edges(graph_t *g) +{ + cmph_uint32 i; + for (i = 0; i < g->nnodes; ++i) g->first[i] = EMPTY; + for (i = 0; i < g->nedges*2; ++i) + { + g->edges[i] = EMPTY; + g->next[i] = EMPTY; + } + g->cedges = 0; + g->shrinking = 0; +} + +static cmph_uint8 find_degree1_edge(graph_t *g, cmph_uint32 v, cmph_uint8 *deleted, cmph_uint32 *e) +{ + cmph_uint32 edge = g->first[v]; + cmph_uint8 found = 0; + DEBUGP("Checking degree of vertex %u\n", v); + if (edge == EMPTY) return 0; + else if (!(GETBIT(deleted, abs_edge(edge, 0)))) + { + found = 1; + *e = edge; + } + while(1) + { + edge = g->next[edge]; + if (edge == EMPTY) break; + if (GETBIT(deleted, abs_edge(edge, 0))) continue; + if (found) return 0; + DEBUGP("Found first edge\n"); + *e = edge; + found = 1; + } + return found; +} + +static void cyclic_del_edge(graph_t *g, cmph_uint32 v, cmph_uint8 *deleted) +{ + + cmph_uint32 e = 0; + cmph_uint8 degree1; + cmph_uint32 v1 = v; + cmph_uint32 v2 = 0; + + degree1 = find_degree1_edge(g, v1, deleted, &e); + if (!degree1) return; + while(1) + { + DEBUGP("Deleting edge %u (%u->%u)\n", e, g->edges[abs_edge(e, 0)], g->edges[abs_edge(e, 1)]); + SETBIT(deleted, abs_edge(e, 0)); + + v2 = g->edges[abs_edge(e, 0)]; + if (v2 == v1) v2 = g->edges[abs_edge(e, 1)]; + + DEBUGP("Checking if second endpoint %u has degree 1\n", v2); + degree1 = find_degree1_edge(g, v2, deleted, &e); + if (degree1) + { + DEBUGP("Inspecting vertex %u\n", v2); + v1 = v2; + } + else break; + } +} + +int graph_is_cyclic(graph_t *g) +{ + cmph_uint32 i; + cmph_uint32 v; + cmph_uint8 *deleted = (cmph_uint8 *)malloc((g->nedges*sizeof(cmph_uint8))/8 + 1); + size_t deleted_len = g->nedges/8 + 1; + memset(deleted, 0, deleted_len); + + DEBUGP("Looking for cycles in graph with %u vertices and %u edges\n", g->nnodes, g->nedges); + for (v = 0; v < g->nnodes; ++v) + { + cyclic_del_edge(g, v, deleted); + } + for (i = 0; i < g->nedges; ++i) + { + if (!(GETBIT(deleted, i))) + { + DEBUGP("Edge %u %u->%u was not deleted\n", i, g->edges[i], g->edges[i + g->nedges]); + free(deleted); + return 1; + } + } + free(deleted); + return 0; +} + +cmph_uint8 graph_node_is_critical(graph_t * g, cmph_uint32 v) /* included -- Fabiano */ +{ + return (cmph_uint8)GETBIT(g->critical_nodes,v); +} + +void graph_obtain_critical_nodes(graph_t *g) /* included -- Fabiano*/ +{ + cmph_uint32 i; + cmph_uint32 v; + cmph_uint8 *deleted = (cmph_uint8 *)malloc((g->nedges*sizeof(cmph_uint8))/8+1); + size_t deleted_len = g->nedges/8 + 1; + memset(deleted, 0, deleted_len); + free(g->critical_nodes); + g->critical_nodes = (cmph_uint8 *)malloc((g->nnodes*sizeof(cmph_uint8))/8 + 1); + g->ncritical_nodes = 0; + memset(g->critical_nodes, 0, (g->nnodes*sizeof(cmph_uint8))/8 + 1); + DEBUGP("Looking for the 2-core in graph with %u vertices and %u edges\n", g->nnodes, g->nedges); + for (v = 0; v < g->nnodes; ++v) + { + cyclic_del_edge(g, v, deleted); + } + + for (i = 0; i < g->nedges; ++i) + { + if (!(GETBIT(deleted,i))) + { + DEBUGP("Edge %u %u->%u belongs to the 2-core\n", i, g->edges[i], g->edges[i + g->nedges]); + if(!(GETBIT(g->critical_nodes,g->edges[i]))) + { + g->ncritical_nodes ++; + SETBIT(g->critical_nodes,g->edges[i]); + } + if(!(GETBIT(g->critical_nodes,g->edges[i + g->nedges]))) + { + g->ncritical_nodes ++; + SETBIT(g->critical_nodes,g->edges[i + g->nedges]); + } + } + } + free(deleted); +} + +cmph_uint8 graph_contains_edge(graph_t *g, cmph_uint32 v1, cmph_uint32 v2) /* included -- Fabiano*/ +{ + cmph_uint32 e; + e = g->first[v1]; + if(e == EMPTY) return 0; + if (check_edge(g, e, v1, v2)) return 1; + do + { + e = g->next[e]; + if(e == EMPTY) return 0; + } + while (!check_edge(g, e, v1, v2)); + return 1; +} + +cmph_uint32 graph_vertex_id(graph_t *g, cmph_uint32 e, cmph_uint32 id) /* included -- Fabiano*/ +{ + return (g->edges[e + id*g->nedges]); +} + +cmph_uint32 graph_ncritical_nodes(graph_t *g) /* included -- Fabiano*/ +{ + return g->ncritical_nodes; +} + +graph_iterator_t graph_neighbors_it(graph_t *g, cmph_uint32 v) +{ + graph_iterator_t it; + it.vertex = v; + it.edge = g->first[v]; + return it; +} +cmph_uint32 graph_next_neighbor(graph_t *g, graph_iterator_t* it) +{ + cmph_uint32 ret; + if(it->edge == EMPTY) return GRAPH_NO_NEIGHBOR; + if (g->edges[it->edge] == it->vertex) ret = g->edges[it->edge + g->nedges]; + else ret = g->edges[it->edge]; + it->edge = g->next[it->edge]; + return ret; +} + + diff --git a/cmph/graph.h b/cmph/graph.h new file mode 100644 index 000000000..e1b5de6f6 --- /dev/null +++ b/cmph/graph.h @@ -0,0 +1,40 @@ +#ifndef _CMPH_GRAPH_H__ +#define _CMPH_GRAPH_H__ + +#include +#include "cmph_types.h" + +#define GRAPH_NO_NEIGHBOR UINT_MAX + +typedef struct __graph_t graph_t; +typedef struct __graph_iterator_t graph_iterator_t; +struct __graph_iterator_t +{ + cmph_uint32 vertex; + cmph_uint32 edge; +}; + + + +graph_t *graph_new(cmph_uint32 nnodes, cmph_uint32 nedges); +void graph_destroy(graph_t *graph); + +void graph_add_edge(graph_t *g, cmph_uint32 v1, cmph_uint32 v2); +void graph_del_edge(graph_t *g, cmph_uint32 v1, cmph_uint32 v2); +void graph_clear_edges(graph_t *g); +cmph_uint32 graph_edge_id(graph_t *g, cmph_uint32 v1, cmph_uint32 v2); +cmph_uint8 graph_contains_edge(graph_t *g, cmph_uint32 v1, cmph_uint32 v2); + +graph_iterator_t graph_neighbors_it(graph_t *g, cmph_uint32 v); +cmph_uint32 graph_next_neighbor(graph_t *g, graph_iterator_t* it); + +void graph_obtain_critical_nodes(graph_t *g); /* included -- Fabiano*/ +cmph_uint8 graph_node_is_critical(graph_t * g, cmph_uint32 v); /* included -- Fabiano */ +cmph_uint32 graph_ncritical_nodes(graph_t *g); /* included -- Fabiano*/ +cmph_uint32 graph_vertex_id(graph_t *g, cmph_uint32 e, cmph_uint32 id); /* included -- Fabiano*/ + +int graph_is_cyclic(graph_t *g); + +void graph_print(graph_t *); + +#endif diff --git a/cmph/hash.c b/cmph/hash.c new file mode 100644 index 000000000..be86d6e75 --- /dev/null +++ b/cmph/hash.c @@ -0,0 +1,216 @@ +#include "hash_state.h" +#include +#include +#include +#include + +//#define DEBUG +#include "debug.h" + +const char *cmph_hash_names[] = { "jenkins", NULL }; + +hash_state_t *hash_state_new(CMPH_HASH hashfunc, cmph_uint32 hashsize) +{ + hash_state_t *state = NULL; + switch (hashfunc) + { + case CMPH_HASH_JENKINS: + DEBUGP("Jenkins function - %u\n", hashsize); + state = (hash_state_t *)jenkins_state_new(hashsize); + DEBUGP("Jenkins function created\n"); + break; + default: + assert(0); + } + state->hashfunc = hashfunc; + return state; +} +cmph_uint32 hash(hash_state_t *state, const char *key, cmph_uint32 keylen) +{ + switch (state->hashfunc) + { + case CMPH_HASH_JENKINS: + return jenkins_hash((jenkins_state_t *)state, key, keylen); + default: + assert(0); + } + assert(0); + return 0; +} + +void hash_vector(hash_state_t *state, const char *key, cmph_uint32 keylen, cmph_uint32 * hashes) +{ + switch (state->hashfunc) + { + case CMPH_HASH_JENKINS: + jenkins_hash_vector_((jenkins_state_t *)state, key, keylen, hashes); + break; + default: + assert(0); + } +} + + +void hash_state_dump(hash_state_t *state, char **buf, cmph_uint32 *buflen) +{ + char *algobuf; + size_t len; + switch (state->hashfunc) + { + case CMPH_HASH_JENKINS: + jenkins_state_dump((jenkins_state_t *)state, &algobuf, buflen); + if (*buflen == UINT_MAX) return; + break; + default: + assert(0); + } + *buf = (char *)malloc(strlen(cmph_hash_names[state->hashfunc]) + 1 + *buflen); + memcpy(*buf, cmph_hash_names[state->hashfunc], strlen(cmph_hash_names[state->hashfunc]) + 1); + DEBUGP("Algobuf is %u\n", *(cmph_uint32 *)algobuf); + len = *buflen; + memcpy(*buf + strlen(cmph_hash_names[state->hashfunc]) + 1, algobuf, len); + *buflen = (cmph_uint32)strlen(cmph_hash_names[state->hashfunc]) + 1 + *buflen; + free(algobuf); + return; +} + +hash_state_t * hash_state_copy(hash_state_t *src_state) +{ + hash_state_t *dest_state = NULL; + switch (src_state->hashfunc) + { + case CMPH_HASH_JENKINS: + dest_state = (hash_state_t *)jenkins_state_copy((jenkins_state_t *)src_state); + break; + default: + assert(0); + } + dest_state->hashfunc = src_state->hashfunc; + return dest_state; +} + +hash_state_t *hash_state_load(const char *buf, cmph_uint32 buflen) +{ + cmph_uint32 i; + cmph_uint32 offset; + CMPH_HASH hashfunc = CMPH_HASH_COUNT; + for (i = 0; i < CMPH_HASH_COUNT; ++i) + { + if (strcmp(buf, cmph_hash_names[i]) == 0) + { + hashfunc = i; + break; + } + } + if (hashfunc == CMPH_HASH_COUNT) return NULL; + offset = (cmph_uint32)strlen(cmph_hash_names[hashfunc]) + 1; + switch (hashfunc) + { + case CMPH_HASH_JENKINS: + return (hash_state_t *)jenkins_state_load(buf + offset, buflen - offset); + default: + return NULL; + } + return NULL; +} +void hash_state_destroy(hash_state_t *state) +{ + switch (state->hashfunc) + { + case CMPH_HASH_JENKINS: + jenkins_state_destroy((jenkins_state_t *)state); + break; + default: + assert(0); + } + return; +} + +/** \fn void hash_state_pack(hash_state_t *state, void *hash_packed) + * \brief Support the ability to pack a hash function into a preallocated contiguous memory space pointed by hash_packed. + * \param state points to the hash function + * \param hash_packed pointer to the contiguous memory area used to store the hash function. The size of hash_packed must be at least hash_state_packed_size() + * + * Support the ability to pack a hash function into a preallocated contiguous memory space pointed by hash_packed. + * However, the hash function type must be packed outside. + */ +void hash_state_pack(hash_state_t *state, void *hash_packed) +{ + switch (state->hashfunc) + { + case CMPH_HASH_JENKINS: + // pack the jenkins hash function + jenkins_state_pack((jenkins_state_t *)state, hash_packed); + break; + default: + assert(0); + } + return; +} + +/** \fn cmph_uint32 hash_state_packed_size(CMPH_HASH hashfunc) + * \brief Return the amount of space needed to pack a hash function. + * \param hashfunc function type + * \return the size of the packed function or zero for failures + */ +cmph_uint32 hash_state_packed_size(CMPH_HASH hashfunc) +{ + cmph_uint32 size = 0; + switch (hashfunc) + { + case CMPH_HASH_JENKINS: + size += jenkins_state_packed_size(); + break; + default: + assert(0); + } + return size; +} + +/** \fn cmph_uint32 hash_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen) + * \param hash_packed is a pointer to a contiguous memory area + * \param hashfunc is the type of the hash function packed in hash_packed + * \param key is a pointer to a key + * \param keylen is the key length + * \return an integer that represents a hash value of 32 bits. + */ +cmph_uint32 hash_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen) +{ + switch (hashfunc) + { + case CMPH_HASH_JENKINS: + return jenkins_hash_packed(hash_packed, k, keylen); + default: + assert(0); + } + assert(0); + return 0; +} + +/** \fn hash_vector_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes) + * \param hash_packed is a pointer to a contiguous memory area + * \param key is a pointer to a key + * \param keylen is the key length + * \param hashes is a pointer to a memory large enough to fit three 32-bit integers. + */ +void hash_vector_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes) +{ + switch (hashfunc) + { + case CMPH_HASH_JENKINS: + jenkins_hash_vector_packed(hash_packed, k, keylen, hashes); + break; + default: + assert(0); + } +} + + +/** \fn CMPH_HASH hash_get_type(hash_state_t *state); + * \param state is a pointer to a hash_state_t structure + * \return the hash function type pointed by state + */ +CMPH_HASH hash_get_type(hash_state_t *state) +{ + return state->hashfunc; +} diff --git a/cmph/hash.h b/cmph/hash.h new file mode 100644 index 000000000..0ec4ce1c7 --- /dev/null +++ b/cmph/hash.h @@ -0,0 +1,76 @@ +#ifndef __CMPH_HASH_H__ +#define __CMPH_HASH_H__ + +#include "cmph_types.h" + +typedef union __hash_state_t hash_state_t; + +hash_state_t *hash_state_new(CMPH_HASH, cmph_uint32 hashsize); + +/** \fn cmph_uint32 hash(hash_state_t *state, const char *key, cmph_uint32 keylen); + * \param state is a pointer to a hash_state_t structure + * \param key is a pointer to a key + * \param keylen is the key length + * \return an integer that represents a hash value of 32 bits. + */ +cmph_uint32 hash(hash_state_t *state, const char *key, cmph_uint32 keylen); + +/** \fn void hash_vector(hash_state_t *state, const char *key, cmph_uint32 keylen, cmph_uint32 * hashes); + * \param state is a pointer to a hash_state_t structure + * \param key is a pointer to a key + * \param keylen is the key length + * \param hashes is a pointer to a memory large enough to fit three 32-bit integers. + */ +void hash_vector(hash_state_t *state, const char *key, cmph_uint32 keylen, cmph_uint32 * hashes); + +void hash_state_dump(hash_state_t *state, char **buf, cmph_uint32 *buflen); + +hash_state_t * hash_state_copy(hash_state_t *src_state); + +hash_state_t *hash_state_load(const char *buf, cmph_uint32 buflen); + +void hash_state_destroy(hash_state_t *state); + +/** \fn void hash_state_pack(hash_state_t *state, void *hash_packed); + * \brief Support the ability to pack a hash function into a preallocated contiguous memory space pointed by hash_packed. + * \param state points to the hash function + * \param hash_packed pointer to the contiguous memory area used to store the hash function. The size of hash_packed must be at least hash_state_packed_size() + * + * Support the ability to pack a hash function into a preallocated contiguous memory space pointed by hash_packed. + * However, the hash function type must be packed outside. + */ +void hash_state_pack(hash_state_t *state, void *hash_packed); + +/** \fn cmph_uint32 hash_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen); + * \param hash_packed is a pointer to a contiguous memory area + * \param hashfunc is the type of the hash function packed in hash_packed + * \param key is a pointer to a key + * \param keylen is the key length + * \return an integer that represents a hash value of 32 bits. + */ +cmph_uint32 hash_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen); + +/** \fn cmph_uint32 hash_state_packed_size(CMPH_HASH hashfunc) + * \brief Return the amount of space needed to pack a hash function. + * \param hashfunc function type + * \return the size of the packed function or zero for failures + */ +cmph_uint32 hash_state_packed_size(CMPH_HASH hashfunc); + + +/** \fn hash_vector_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes); + * \param hash_packed is a pointer to a contiguous memory area + * \param key is a pointer to a key + * \param keylen is the key length + * \param hashes is a pointer to a memory large enough to fit three 32-bit integers. + */ +void hash_vector_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes); + + +/** \fn CMPH_HASH hash_get_type(hash_state_t *state); + * \param state is a pointer to a hash_state_t structure + * \return the hash function type pointed by state + */ +CMPH_HASH hash_get_type(hash_state_t *state); + +#endif diff --git a/cmph/hash_state.h b/cmph/hash_state.h new file mode 100644 index 000000000..1b567dca1 --- /dev/null +++ b/cmph/hash_state.h @@ -0,0 +1,12 @@ +#ifndef __HASH_STATE_H__ +#define __HASH_STATE_H__ + +#include "hash.h" +#include "jenkins_hash.h" +union __hash_state_t +{ + CMPH_HASH hashfunc; + jenkins_state_t jenkins; +}; + +#endif diff --git a/cmph/hashtree.c b/cmph/hashtree.c new file mode 100644 index 000000000..2f3567e55 --- /dev/null +++ b/cmph/hashtree.c @@ -0,0 +1,289 @@ +#include "graph.h" +#include "hashtree.h" +#include "cmph_structs.h" +#include "hastree_structs.h" +#include "hash.h" +#include "bitbool.h" + +#include +#include +#include +#include +#include + +//#define DEBUG +#include "debug.h" + +hashtree_config_data_t *hashtree_config_new() +{ + hashtree_config_data_t *hashtree; + hashtree = (hashtree_config_data_t *)malloc(sizeof(hashtree_config_data_t)); + if (!hashtree) return NULL; + memset(hashtree, 0, sizeof(hashtree_config_data_t)); + hashtree->hashfuncs[0] = CMPH_HASH_JENKINS; + hashtree->hashfuncs[1] = CMPH_HASH_JENKINS; + hashtree->hashfuncs[2] = CMPH_HASH_JENKINS; + hashtree->memory = 32 * 1024 * 1024; + return hashtree; +} +void hashtree_config_destroy(cmph_config_t *mph) +{ + hashtree_config_data_t *data = (hashtree_config_data_t *)mph->data; + DEBUGP("Destroying algorithm dependent data\n"); + free(data); +} + +void hashtree_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs) +{ + hashtree_config_data_t *hashtree = (hashtree_config_data_t *)mph->data; + CMPH_HASH *hashptr = hashfuncs; + cmph_uint32 i = 0; + while(*hashptr != CMPH_HASH_COUNT) + { + if (i >= 3) break; //hashtree only uses three hash functions + hashtree->hashfuncs[i] = *hashptr; + ++i, ++hashptr; + } +} + +cmph_t *hashtree_new(cmph_config_t *mph, double c) +{ + cmph_t *mphf = NULL; + hashtree_data_t *hashtreef = NULL; + + cmph_uint32 i; + cmph_uint32 iterations = 20; + cmph_uint8 *visited = NULL; + hashtree_config_data_t *hashtree = (hashtree_config_data_t *)mph->data; + hashtree->m = mph->key_source->nkeys; + hashtree->n = ceil(c * mph->key_source->nkeys); + DEBUGP("m (edges): %u n (vertices): %u c: %f\n", hashtree->m, hashtree->n, c); + hashtree->graph = graph_new(hashtree->n, hashtree->m); + DEBUGP("Created graph\n"); + + hashtree->hashes = (hash_state_t **)malloc(sizeof(hash_state_t *)*3); + for(i = 0; i < 3; ++i) hashtree->hashes[i] = NULL; + //Mapping step + if (mph->verbosity) + { + fprintf(stderr, "Entering mapping step for mph creation of %u keys with graph sized %u\n", hashtree->m, hashtree->n); + } + while(1) + { + int ok; + hashtree->hashes[0] = hash_state_new(hashtree->hashfuncs[0], hashtree->n); + hashtree->hashes[1] = hash_state_new(hashtree->hashfuncs[1], hashtree->n); + ok = hashtree_gen_edges(mph); + if (!ok) + { + --iterations; + hash_state_destroy(hashtree->hashes[0]); + hashtree->hashes[0] = NULL; + hash_state_destroy(hashtree->hashes[1]); + hashtree->hashes[1] = NULL; + DEBUGP("%u iterations remaining\n", iterations); + if (mph->verbosity) + { + fprintf(stderr, "Acyclic graph creation failure - %u iterations remaining\n", iterations); + } + if (iterations == 0) break; + } + else break; + } + if (iterations == 0) + { + graph_destroy(hashtree->graph); + return NULL; + } + + //Assignment step + if (mph->verbosity) + { + fprintf(stderr, "Starting assignment step\n"); + } + DEBUGP("Assignment step\n"); + visited = (char *)malloc(hashtree->n/8 + 1); + memset(visited, 0, hashtree->n/8 + 1); + free(hashtree->g); + hashtree->g = (cmph_uint32 *)malloc(hashtree->n * sizeof(cmph_uint32)); + assert(hashtree->g); + for (i = 0; i < hashtree->n; ++i) + { + if (!GETBIT(visited,i)) + { + hashtree->g[i] = 0; + hashtree_traverse(hashtree, visited, i); + } + } + graph_destroy(hashtree->graph); + free(visited); + hashtree->graph = NULL; + + mphf = (cmph_t *)malloc(sizeof(cmph_t)); + mphf->algo = mph->algo; + hashtreef = (hashtree_data_t *)malloc(sizeof(hashtree_data_t)); + hashtreef->g = hashtree->g; + hashtree->g = NULL; //transfer memory ownership + hashtreef->hashes = hashtree->hashes; + hashtree->hashes = NULL; //transfer memory ownership + hashtreef->n = hashtree->n; + hashtreef->m = hashtree->m; + mphf->data = hashtreef; + mphf->size = hashtree->m; + DEBUGP("Successfully generated minimal perfect hash\n"); + if (mph->verbosity) + { + fprintf(stderr, "Successfully generated minimal perfect hash function\n"); + } + return mphf; +} + +static void hashtree_traverse(hashtree_config_data_t *hashtree, cmph_uint8 *visited, cmph_uint32 v) +{ + + graph_iterator_t it = graph_neighbors_it(hashtree->graph, v); + cmph_uint32 neighbor = 0; + SETBIT(visited,v); + + DEBUGP("Visiting vertex %u\n", v); + while((neighbor = graph_next_neighbor(hashtree->graph, &it)) != GRAPH_NO_NEIGHBOR) + { + DEBUGP("Visiting neighbor %u\n", neighbor); + if(GETBIT(visited,neighbor)) continue; + DEBUGP("Visiting neighbor %u\n", neighbor); + DEBUGP("Visiting edge %u->%u with id %u\n", v, neighbor, graph_edge_id(hashtree->graph, v, neighbor)); + hashtree->g[neighbor] = graph_edge_id(hashtree->graph, v, neighbor) - hashtree->g[v]; + DEBUGP("g is %u (%u - %u mod %u)\n", hashtree->g[neighbor], graph_edge_id(hashtree->graph, v, neighbor), hashtree->g[v], hashtree->m); + hashtree_traverse(hashtree, visited, neighbor); + } +} + +static int hashtree_gen_edges(cmph_config_t *mph) +{ + cmph_uint32 e; + hashtree_config_data_t *hashtree = (hashtree_config_data_t *)mph->data; + int cycles = 0; + + DEBUGP("Generating edges for %u vertices with hash functions %s and %s\n", hashtree->n, cmph_hash_names[hashtree->hashfuncs[0]], cmph_hash_names[hashtree->hashfuncs[1]]); + graph_clear_edges(hashtree->graph); + mph->key_source->rewind(mph->key_source->data); + for (e = 0; e < mph->key_source->nkeys; ++e) + { + cmph_uint32 h1, h2; + cmph_uint32 keylen; + char *key; + mph->key_source->read(mph->key_source->data, &key, &keylen); + h1 = hash(hashtree->hashes[0], key, keylen) % hashtree->n; + h2 = hash(hashtree->hashes[1], key, keylen) % hashtree->n; + if (h1 == h2) if (++h2 >= hashtree->n) h2 = 0; + if (h1 == h2) + { + if (mph->verbosity) fprintf(stderr, "Self loop for key %u\n", e); + mph->key_source->dispose(mph->key_source->data, key, keylen); + return 0; + } + DEBUGP("Adding edge: %u -> %u for key %s\n", h1, h2, key); + mph->key_source->dispose(mph->key_source->data, key, keylen); + graph_add_edge(hashtree->graph, h1, h2); + } + cycles = graph_is_cyclic(hashtree->graph); + if (mph->verbosity && cycles) fprintf(stderr, "Cyclic graph generated\n"); + DEBUGP("Looking for cycles: %u\n", cycles); + + return ! cycles; +} + +int hashtree_dump(cmph_t *mphf, FILE *fd) +{ + char *buf = NULL; + cmph_uint32 buflen; + cmph_uint32 two = 2; //number of hash functions + hashtree_data_t *data = (hashtree_data_t *)mphf->data; + __cmph_dump(mphf, fd); + + fwrite(&two, sizeof(cmph_uint32), 1, fd); + hash_state_dump(data->hashes[0], &buf, &buflen); + DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); + fwrite(&buflen, sizeof(cmph_uint32), 1, fd); + fwrite(buf, buflen, 1, fd); + free(buf); + + hash_state_dump(data->hashes[1], &buf, &buflen); + DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); + fwrite(&buflen, sizeof(cmph_uint32), 1, fd); + fwrite(buf, buflen, 1, fd); + free(buf); + + fwrite(&(data->n), sizeof(cmph_uint32), 1, fd); + fwrite(&(data->m), sizeof(cmph_uint32), 1, fd); + + fwrite(data->g, sizeof(cmph_uint32)*data->n, 1, fd); + #ifdef DEBUG + fprintf(stderr, "G: "); + for (i = 0; i < data->n; ++i) fprintf(stderr, "%u ", data->g[i]); + fprintf(stderr, "\n"); + #endif + return 1; +} + +void hashtree_load(FILE *f, cmph_t *mphf) +{ + cmph_uint32 nhashes; + char *buf = NULL; + cmph_uint32 buflen; + cmph_uint32 i; + hashtree_data_t *hashtree = (hashtree_data_t *)malloc(sizeof(hashtree_data_t)); + + DEBUGP("Loading hashtree mphf\n"); + mphf->data = hashtree; + fread(&nhashes, sizeof(cmph_uint32), 1, f); + hashtree->hashes = (hash_state_t **)malloc(sizeof(hash_state_t *)*(nhashes + 1)); + hashtree->hashes[nhashes] = NULL; + DEBUGP("Reading %u hashes\n", nhashes); + for (i = 0; i < nhashes; ++i) + { + hash_state_t *state = NULL; + fread(&buflen, sizeof(cmph_uint32), 1, f); + DEBUGP("Hash state has %u bytes\n", buflen); + buf = (char *)malloc(buflen); + fread(buf, buflen, 1, f); + state = hash_state_load(buf, buflen); + hashtree->hashes[i] = state; + free(buf); + } + + DEBUGP("Reading m and n\n"); + fread(&(hashtree->n), sizeof(cmph_uint32), 1, f); + fread(&(hashtree->m), sizeof(cmph_uint32), 1, f); + + hashtree->g = (cmph_uint32 *)malloc(sizeof(cmph_uint32)*hashtree->n); + fread(hashtree->g, hashtree->n*sizeof(cmph_uint32), 1, f); + #ifdef DEBUG + fprintf(stderr, "G: "); + for (i = 0; i < hashtree->n; ++i) fprintf(stderr, "%u ", hashtree->g[i]); + fprintf(stderr, "\n"); + #endif + return; +} + + +cmph_uint32 hashtree_search(cmph_t *mphf, const char *key, cmph_uint32 keylen) +{ + hashtree_data_t *hashtree = mphf->data; + cmph_uint32 h1 = hash(hashtree->hashes[0], key, keylen) % hashtree->n; + cmph_uint32 h2 = hash(hashtree->hashes[1], key, keylen) % hashtree->n; + DEBUGP("key: %s h1: %u h2: %u\n", key, h1, h2); + if (h1 == h2 && ++h2 >= hashtree->n) h2 = 0; + DEBUGP("key: %s g[h1]: %u g[h2]: %u edges: %u\n", key, hashtree->g[h1], hashtree->g[h2], hashtree->m); + return (hashtree->g[h1] + hashtree->g[h2]) % hashtree->m; +} +void hashtree_destroy(cmph_t *mphf) +{ + hashtree_data_t *data = (hashtree_data_t *)mphf->data; + free(data->g); + hash_state_destroy(data->hashes[0]); + hash_state_destroy(data->hashes[1]); + free(data->hashes); + free(data); + free(mphf); +} diff --git a/cmph/hashtree.h b/cmph/hashtree.h new file mode 100644 index 000000000..8bff67462 --- /dev/null +++ b/cmph/hashtree.h @@ -0,0 +1,19 @@ +#ifndef __CMPH_HASHTREE_H__ +#define __CMPH_HASHTREE_H__ + +#include "cmph.h" + +typedef struct __hashtree_data_t hashtree_data_t; +typedef struct __hashtree_config_data_t hashtree_config_data_t; + +hashtree_config_data_t *hashtree_config_new(); +void hashtree_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); +void hashtree_config_set_leaf_algo(cmph_config_t *mph, CMPH_ALGO leaf_algo); +void hashtree_config_destroy(cmph_config_t *mph); +cmph_t *hashtree_new(cmph_config_t *mph, double c); + +void hashtree_load(FILE *f, cmph_t *mphf); +int hashtree_dump(cmph_t *mphf, FILE *f); +void hashtree_destroy(cmph_t *mphf); +cmph_uint32 hashtree_search(cmph_t *mphf, const char *key, cmph_uint32 keylen); +#endif diff --git a/cmph/hashtree_structs.h b/cmph/hashtree_structs.h new file mode 100644 index 000000000..7258cd399 --- /dev/null +++ b/cmph/hashtree_structs.h @@ -0,0 +1,32 @@ +#ifndef __CMPH_HASHTREE_STRUCTS_H__ +#define __CMPH_HASHTREE_STRUCTS_H__ + +#include "hash_state.h" + +struct __hashtree_data_t +{ + cmph_uint32 m; //edges (words) count + double c; //constant c + cmph_uint8 *size; //size[i] stores the number of edges represented by g[i] + cmph_uint32 **g; + cmph_uint32 k; //number of components + hash_state_t **h1; + hash_state_t **h2; + hash_state_t *h3; +}; + +struct __hashtree_config_data_t +{ + CMPH_ALGO leaf_algo; + CMPH_HASH hashfuncs[3]; + cmph_uint32 m; //edges (words) count + cmph_uint8 *size; //size[i] stores the number of edges represented by g[i] + cmph_uint32 *offset; //offset[i] stores the sum size[0] + ... size[i - 1] + cmph_uint32 k; //number of components + cmph_uint32 memory; + hash_state_t **h1; + hash_state_t **h2; + hash_state_t *h3; +}; + +#endif diff --git a/cmph/jenkins_hash.c b/cmph/jenkins_hash.c new file mode 100644 index 000000000..f5233a5a5 --- /dev/null +++ b/cmph/jenkins_hash.c @@ -0,0 +1,297 @@ +#include "jenkins_hash.h" +#include +#ifdef WIN32 +#define _USE_MATH_DEFINES //For M_LOG2E +#endif +#include +#include +#include + +//#define DEBUG +#include "debug.h" + +#define hashsize(n) ((cmph_uint32)1<<(n)) +#define hashmask(n) (hashsize(n)-1) + + + +//#define NM2 /* Define this if you do not want power of 2 table sizes*/ + + +/* + -------------------------------------------------------------------- + mix -- mix 3 32-bit values reversibly. + For every delta with one or two bits set, and the deltas of all three + high bits or all three low bits, whether the original value of a,b,c + is almost all zero or is uniformly distributed, + * If mix() is run forward or backward, at least 32 bits in a,b,c + have at least 1/4 probability of changing. + * If mix() is run forward, every bit of c will change between 1/3 and + 2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.) + mix() was built out of 36 single-cycle latency instructions in a + structure that could supported 2x parallelism, like so: + a -= b; + a -= c; x = (c>>13); + b -= c; a ^= x; + b -= a; x = (a<<8); + c -= a; b ^= x; + c -= b; x = (b>>13); + ... + Unfortunately, superscalar Pentiums and Sparcs can't take advantage + of that parallelism. They've also turned some of those single-cycle + latency instructions into multi-cycle latency instructions. Still, + this is the fastest good hash I could find. There were about 2^^68 + to choose from. I only looked at a billion or so. + -------------------------------------------------------------------- + */ +#define mix(a,b,c) \ +{ \ + a -= b; a -= c; a ^= (c>>13); \ + b -= c; b -= a; b ^= (a<<8); \ + c -= a; c -= b; c ^= (b>>13); \ + a -= b; a -= c; a ^= (c>>12); \ + b -= c; b -= a; b ^= (a<<16); \ + c -= a; c -= b; c ^= (b>>5); \ + a -= b; a -= c; a ^= (c>>3); \ + b -= c; b -= a; b ^= (a<<10); \ + c -= a; c -= b; c ^= (b>>15); \ +} + +/* + -------------------------------------------------------------------- + hash() -- hash a variable-length key into a 32-bit value +k : the key (the unaligned variable-length array of bytes) +len : the length of the key, counting by bytes +initval : can be any 4-byte value +Returns a 32-bit value. Every bit of the key affects every bit of +the return value. Every 1-bit and 2-bit delta achieves avalanche. +About 6*len+35 instructions. + +The best hash table sizes are powers of 2. There is no need to do +mod a prime (mod is sooo slow!). If you need less than 32 bits, +use a bitmask. For example, if you need only 10 bits, do +h = (h & hashmask(10)); +In which case, the hash table should have hashsize(10) elements. + +If you are hashing n strings (cmph_uint8 **)k, do it like this: +for (i=0, h=0; iseed = ((cmph_uint32)rand() % size); + return state; +} +void jenkins_state_destroy(jenkins_state_t *state) +{ + free(state); +} + + +inline void __jenkins_hash_vector(cmph_uint32 seed, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes) +{ + register cmph_uint32 len, length; + + /* Set up the internal state */ + length = keylen; + len = length; + hashes[0] = hashes[1] = 0x9e3779b9; /* the golden ratio; an arbitrary value */ + hashes[2] = seed; /* the previous hash value - seed in our case */ + + /*---------------------------------------- handle most of the key */ + while (len >= 12) + { + hashes[0] += ((cmph_uint32)k[0] +((cmph_uint32)k[1]<<8) +((cmph_uint32)k[2]<<16) +((cmph_uint32)k[3]<<24)); + hashes[1] += ((cmph_uint32)k[4] +((cmph_uint32)k[5]<<8) +((cmph_uint32)k[6]<<16) +((cmph_uint32)k[7]<<24)); + hashes[2] += ((cmph_uint32)k[8] +((cmph_uint32)k[9]<<8) +((cmph_uint32)k[10]<<16)+((cmph_uint32)k[11]<<24)); + mix(hashes[0],hashes[1],hashes[2]); + k += 12; len -= 12; + } + + /*------------------------------------- handle the last 11 bytes */ + hashes[2] += length; + switch(len) /* all the case statements fall through */ + { + case 11: + hashes[2] +=((cmph_uint32)k[10]<<24); + case 10: + hashes[2] +=((cmph_uint32)k[9]<<16); + case 9 : + hashes[2] +=((cmph_uint32)k[8]<<8); + /* the first byte of hashes[2] is reserved for the length */ + case 8 : + hashes[1] +=((cmph_uint32)k[7]<<24); + case 7 : + hashes[1] +=((cmph_uint32)k[6]<<16); + case 6 : + hashes[1] +=((cmph_uint32)k[5]<<8); + case 5 : + hashes[1] +=(cmph_uint8) k[4]; + case 4 : + hashes[0] +=((cmph_uint32)k[3]<<24); + case 3 : + hashes[0] +=((cmph_uint32)k[2]<<16); + case 2 : + hashes[0] +=((cmph_uint32)k[1]<<8); + case 1 : + hashes[0] +=(cmph_uint8)k[0]; + /* case 0: nothing left to add */ + } + + mix(hashes[0],hashes[1],hashes[2]); +} + +cmph_uint32 jenkins_hash(jenkins_state_t *state, const char *k, cmph_uint32 keylen) +{ + cmph_uint32 hashes[3]; + __jenkins_hash_vector(state->seed, k, keylen, hashes); + return hashes[2]; +/* cmph_uint32 a, b, c; + cmph_uint32 len, length; + + // Set up the internal state + length = keylen; + len = length; + a = b = 0x9e3779b9; // the golden ratio; an arbitrary value + c = state->seed; // the previous hash value - seed in our case + + // handle most of the key + while (len >= 12) + { + a += (k[0] +((cmph_uint32)k[1]<<8) +((cmph_uint32)k[2]<<16) +((cmph_uint32)k[3]<<24)); + b += (k[4] +((cmph_uint32)k[5]<<8) +((cmph_uint32)k[6]<<16) +((cmph_uint32)k[7]<<24)); + c += (k[8] +((cmph_uint32)k[9]<<8) +((cmph_uint32)k[10]<<16)+((cmph_uint32)k[11]<<24)); + mix(a,b,c); + k += 12; len -= 12; + } + + // handle the last 11 bytes + c += length; + switch(len) /// all the case statements fall through + { + case 11: + c +=((cmph_uint32)k[10]<<24); + case 10: + c +=((cmph_uint32)k[9]<<16); + case 9 : + c +=((cmph_uint32)k[8]<<8); + // the first byte of c is reserved for the length + case 8 : + b +=((cmph_uint32)k[7]<<24); + case 7 : + b +=((cmph_uint32)k[6]<<16); + case 6 : + b +=((cmph_uint32)k[5]<<8); + case 5 : + b +=k[4]; + case 4 : + a +=((cmph_uint32)k[3]<<24); + case 3 : + a +=((cmph_uint32)k[2]<<16); + case 2 : + a +=((cmph_uint32)k[1]<<8); + case 1 : + a +=k[0]; + // case 0: nothing left to add + } + + mix(a,b,c); + + /// report the result + + return c; + */ +} + +void jenkins_hash_vector_(jenkins_state_t *state, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes) +{ + __jenkins_hash_vector(state->seed, k, keylen, hashes); +} + +void jenkins_state_dump(jenkins_state_t *state, char **buf, cmph_uint32 *buflen) +{ + *buflen = sizeof(cmph_uint32); + *buf = (char *)malloc(sizeof(cmph_uint32)); + if (!*buf) + { + *buflen = UINT_MAX; + return; + } + memcpy(*buf, &(state->seed), sizeof(cmph_uint32)); + DEBUGP("Dumped jenkins state with seed %u\n", state->seed); + return; +} + +jenkins_state_t *jenkins_state_copy(jenkins_state_t *src_state) +{ + jenkins_state_t *dest_state = (jenkins_state_t *)malloc(sizeof(jenkins_state_t)); + dest_state->hashfunc = src_state->hashfunc; + dest_state->seed = src_state->seed; + return dest_state; +} + +jenkins_state_t *jenkins_state_load(const char *buf, cmph_uint32 buflen) +{ + jenkins_state_t *state = (jenkins_state_t *)malloc(sizeof(jenkins_state_t)); + state->seed = *(cmph_uint32 *)buf; + state->hashfunc = CMPH_HASH_JENKINS; + DEBUGP("Loaded jenkins state with seed %u\n", state->seed); + return state; +} + + +/** \fn void jenkins_state_pack(jenkins_state_t *state, void *jenkins_packed); + * \brief Support the ability to pack a jenkins function into a preallocated contiguous memory space pointed by jenkins_packed. + * \param state points to the jenkins function + * \param jenkins_packed pointer to the contiguous memory area used to store the jenkins function. The size of jenkins_packed must be at least jenkins_state_packed_size() + */ +void jenkins_state_pack(jenkins_state_t *state, void *jenkins_packed) +{ + if (state && jenkins_packed) + { + memcpy(jenkins_packed, &(state->seed), sizeof(cmph_uint32)); + } +} + +/** \fn cmph_uint32 jenkins_state_packed_size(jenkins_state_t *state); + * \brief Return the amount of space needed to pack a jenkins function. + * \return the size of the packed function or zero for failures + */ +cmph_uint32 jenkins_state_packed_size() +{ + return sizeof(cmph_uint32); +} + + +/** \fn cmph_uint32 jenkins_hash_packed(void *jenkins_packed, const char *k, cmph_uint32 keylen); + * \param jenkins_packed is a pointer to a contiguous memory area + * \param key is a pointer to a key + * \param keylen is the key length + * \return an integer that represents a hash value of 32 bits. + */ +cmph_uint32 jenkins_hash_packed(void *jenkins_packed, const char *k, cmph_uint32 keylen) +{ + cmph_uint32 hashes[3]; + __jenkins_hash_vector(*((cmph_uint32 *)jenkins_packed), k, keylen, hashes); + return hashes[2]; +} + +/** \fn jenkins_hash_vector_packed(void *jenkins_packed, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes); + * \param jenkins_packed is a pointer to a contiguous memory area + * \param key is a pointer to a key + * \param keylen is the key length + * \param hashes is a pointer to a memory large enough to fit three 32-bit integers. + */ +void jenkins_hash_vector_packed(void *jenkins_packed, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes) +{ + __jenkins_hash_vector(*((cmph_uint32 *)jenkins_packed), k, keylen, hashes); +} diff --git a/cmph/jenkins_hash.h b/cmph/jenkins_hash.h new file mode 100644 index 000000000..8e8b9173e --- /dev/null +++ b/cmph/jenkins_hash.h @@ -0,0 +1,65 @@ +#ifndef __JEKINS_HASH_H__ +#define __JEKINS_HASH_H__ + +#include "hash.h" + +typedef struct __jenkins_state_t +{ + CMPH_HASH hashfunc; + cmph_uint32 seed; +} jenkins_state_t; + +jenkins_state_t *jenkins_state_new(cmph_uint32 size); //size of hash table + +/** \fn cmph_uint32 jenkins_hash(jenkins_state_t *state, const char *k, cmph_uint32 keylen); + * \param state is a pointer to a jenkins_state_t structure + * \param key is a pointer to a key + * \param keylen is the key length + * \return an integer that represents a hash value of 32 bits. + */ +cmph_uint32 jenkins_hash(jenkins_state_t *state, const char *k, cmph_uint32 keylen); + +/** \fn void jenkins_hash_vector_(jenkins_state_t *state, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes); + * \param state is a pointer to a jenkins_state_t structure + * \param key is a pointer to a key + * \param keylen is the key length + * \param hashes is a pointer to a memory large enough to fit three 32-bit integers. + */ +void jenkins_hash_vector_(jenkins_state_t *state, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes); + +void jenkins_state_dump(jenkins_state_t *state, char **buf, cmph_uint32 *buflen); +jenkins_state_t *jenkins_state_copy(jenkins_state_t *src_state); +jenkins_state_t *jenkins_state_load(const char *buf, cmph_uint32 buflen); +void jenkins_state_destroy(jenkins_state_t *state); + +/** \fn void jenkins_state_pack(jenkins_state_t *state, void *jenkins_packed); + * \brief Support the ability to pack a jenkins function into a preallocated contiguous memory space pointed by jenkins_packed. + * \param state points to the jenkins function + * \param jenkins_packed pointer to the contiguous memory area used to store the jenkins function. The size of jenkins_packed must be at least jenkins_state_packed_size() + */ +void jenkins_state_pack(jenkins_state_t *state, void *jenkins_packed); + +/** \fn cmph_uint32 jenkins_state_packed_size(); + * \brief Return the amount of space needed to pack a jenkins function. + * \return the size of the packed function or zero for failures + */ +cmph_uint32 jenkins_state_packed_size(); + + +/** \fn cmph_uint32 jenkins_hash_packed(void *jenkins_packed, const char *k, cmph_uint32 keylen); + * \param jenkins_packed is a pointer to a contiguous memory area + * \param key is a pointer to a key + * \param keylen is the key length + * \return an integer that represents a hash value of 32 bits. + */ +cmph_uint32 jenkins_hash_packed(void *jenkins_packed, const char *k, cmph_uint32 keylen); + +/** \fn jenkins_hash_vector_packed(void *jenkins_packed, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes); + * \param jenkins_packed is a pointer to a contiguous memory area + * \param key is a pointer to a key + * \param keylen is the key length + * \param hashes is a pointer to a memory large enough to fit three 32-bit integers. + */ +void jenkins_hash_vector_packed(void *jenkins_packed, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes); + +#endif diff --git a/cmph/main.c b/cmph/main.c new file mode 100644 index 000000000..f739b325f --- /dev/null +++ b/cmph/main.c @@ -0,0 +1,342 @@ +#ifdef WIN32 +#include "wingetopt.h" +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include "cmph.h" +#include "hash.h" + +#ifdef WIN32 +#define VERSION "0.8" +#else +#include "config.h" +#endif + + +void usage(const char *prg) +{ + fprintf(stderr, "usage: %s [-v] [-h] [-V] [-k nkeys] [-f hash_function] [-g [-c algorithm_dependent_value][-s seed] ] [-a algorithm] [-M memory_in_MB] [-b algorithm_dependent_value] [-t keys_per_bin] [-d tmp_dir] [-m file.mph] keysfile\n", prg); +} +void usage_long(const char *prg) +{ + cmph_uint32 i; + fprintf(stderr, "usage: %s [-v] [-h] [-V] [-k nkeys] [-f hash_function] [-g [-c algorithm_dependent_value][-s seed] ] [-a algorithm] [-M memory_in_MB] [-b algorithm_dependent_value] [-t keys_per_bin] [-d tmp_dir] [-m file.mph] keysfile\n", prg); + fprintf(stderr, "Minimum perfect hashing tool\n\n"); + fprintf(stderr, " -h\t print this help message\n"); + fprintf(stderr, " -c\t c value determines:\n"); + fprintf(stderr, " \t * the number of vertices in the graph for the algorithms BMZ and CHM\n"); + fprintf(stderr, " \t * the number of bits per key required in the FCH algorithm\n"); + fprintf(stderr, " \t * the load factor in the CHD_PH algorithm\n"); + fprintf(stderr, " -a\t algorithm - valid values are\n"); + for (i = 0; i < CMPH_COUNT; ++i) fprintf(stderr, " \t * %s\n", cmph_names[i]); + fprintf(stderr, " -f\t hash function (may be used multiple times) - valid values are\n"); + for (i = 0; i < CMPH_HASH_COUNT; ++i) fprintf(stderr, " \t * %s\n", cmph_hash_names[i]); + fprintf(stderr, " -V\t print version number and exit\n"); + fprintf(stderr, " -v\t increase verbosity (may be used multiple times)\n"); + fprintf(stderr, " -k\t number of keys\n"); + fprintf(stderr, " -g\t generation mode\n"); + fprintf(stderr, " -s\t random seed\n"); + fprintf(stderr, " -m\t minimum perfect hash function file \n"); + fprintf(stderr, " -M\t main memory availability (in MB) used in BRZ algorithm \n"); + fprintf(stderr, " -d\t temporary directory used in BRZ algorithm \n"); + fprintf(stderr, " -b\t the meaning of this parameter depends on the algorithm selected in the -a option:\n"); + fprintf(stderr, " \t * For BRZ it is used to make the maximal number of keys in a bucket lower than 256.\n"); + fprintf(stderr, " \t In this case its value should be an integer in the range [64,175]. Default is 128.\n\n"); + fprintf(stderr, " \t * For BDZ it is used to determine the size of some precomputed rank\n"); + fprintf(stderr, " \t information and its value should be an integer in the range [3,10]. Default\n"); + fprintf(stderr, " \t is 7. The larger is this value, the more compact are the resulting functions\n"); + fprintf(stderr, " \t and the slower are them at evaluation time.\n\n"); + fprintf(stderr, " \t * For CHD and CHD_PH it is used to set the average number of keys per bucket\n"); + fprintf(stderr, " \t and its value should be an integer in the range [1,32]. Default is 4. The\n"); + fprintf(stderr, " \t larger is this value, the slower is the construction of the functions.\n"); + fprintf(stderr, " \t This parameter has no effect for other algorithms.\n\n"); + fprintf(stderr, " -t\t set the number of keys per bin for a t-perfect hashing function. A t-perfect\n"); + fprintf(stderr, " \t hash function allows at most t collisions in a given bin. This parameter applies\n"); + fprintf(stderr, " \t only to the CHD and CHD_PH algorithms. Its value should be an integer in the\n"); + fprintf(stderr, " \t range [1,128]. Defaul is 1\n"); + fprintf(stderr, " keysfile\t line separated file with keys\n"); +} + +int main(int argc, char **argv) +{ + cmph_uint32 verbosity = 0; + char generate = 0; + char *mphf_file = NULL; + FILE *mphf_fd = stdout; + const char *keys_file = NULL; + FILE *keys_fd; + cmph_uint32 nkeys = UINT_MAX; + cmph_uint32 seed = UINT_MAX; + CMPH_HASH *hashes = NULL; + cmph_uint32 nhashes = 0; + cmph_uint32 i; + CMPH_ALGO mph_algo = CMPH_CHM; + double c = 0; + cmph_config_t *config = NULL; + cmph_t *mphf = NULL; + char * tmp_dir = NULL; + cmph_io_adapter_t *source; + cmph_uint32 memory_availability = 0; + cmph_uint32 b = 0; + cmph_uint32 keys_per_bin = 1; + while (1) + { + char ch = (char)getopt(argc, argv, "hVvgc:k:a:M:b:t:f:m:d:s:"); + if (ch == -1) break; + switch (ch) + { + case 's': + { + char *cptr; + seed = (cmph_uint32)strtoul(optarg, &cptr, 10); + if(*cptr != 0) { + fprintf(stderr, "Invalid seed %s\n", optarg); + exit(1); + } + } + break; + case 'c': + { + char *endptr; + c = strtod(optarg, &endptr); + if(*endptr != 0) { + fprintf(stderr, "Invalid c value %s\n", optarg); + exit(1); + } + } + break; + case 'g': + generate = 1; + break; + case 'k': + { + char *endptr; + nkeys = (cmph_uint32)strtoul(optarg, &endptr, 10); + if(*endptr != 0) { + fprintf(stderr, "Invalid number of keys %s\n", optarg); + exit(1); + } + } + break; + case 'm': + mphf_file = strdup(optarg); + break; + case 'd': + tmp_dir = strdup(optarg); + break; + case 'M': + { + char *cptr; + memory_availability = (cmph_uint32)strtoul(optarg, &cptr, 10); + if(*cptr != 0) { + fprintf(stderr, "Invalid memory availability %s\n", optarg); + exit(1); + } + } + break; + case 'b': + { + char *cptr; + b = (cmph_uint32)strtoul(optarg, &cptr, 10); + if(*cptr != 0) { + fprintf(stderr, "Parameter b was not found: %s\n", optarg); + exit(1); + } + } + break; + case 't': + { + char *cptr; + keys_per_bin = (cmph_uint32)strtoul(optarg, &cptr, 10); + if(*cptr != 0) { + fprintf(stderr, "Parameter t was not found: %s\n", optarg); + exit(1); + } + } + break; + case 'v': + ++verbosity; + break; + case 'V': + printf("%s\n", VERSION); + return 0; + case 'h': + usage_long(argv[0]); + return 0; + case 'a': + { + char valid = 0; + for (i = 0; i < CMPH_COUNT; ++i) + { + if (strcmp(cmph_names[i], optarg) == 0) + { + mph_algo = i; + valid = 1; + break; + } + } + if (!valid) + { + fprintf(stderr, "Invalid mph algorithm: %s. It is not available in version %s\n", optarg, VERSION); + return -1; + } + } + break; + case 'f': + { + char valid = 0; + for (i = 0; i < CMPH_HASH_COUNT; ++i) + { + if (strcmp(cmph_hash_names[i], optarg) == 0) + { + hashes = (CMPH_HASH *)realloc(hashes, sizeof(CMPH_HASH) * ( nhashes + 2 )); + hashes[nhashes] = i; + hashes[nhashes + 1] = CMPH_HASH_COUNT; + ++nhashes; + valid = 1; + break; + } + } + if (!valid) + { + fprintf(stderr, "Invalid hash function: %s\n", optarg); + return -1; + } + } + break; + default: + usage(argv[0]); + return 1; + } + } + + if (optind != argc - 1) + { + usage(argv[0]); + return 1; + } + keys_file = argv[optind]; + + if (seed == UINT_MAX) seed = (cmph_uint32)time(NULL); + srand(seed); + int ret = 0; + if (mphf_file == NULL) + { + mphf_file = (char *)malloc(strlen(keys_file) + 5); + memcpy(mphf_file, keys_file, strlen(keys_file)); + memcpy(mphf_file + strlen(keys_file), ".mph\0", (size_t)5); + } + + keys_fd = fopen(keys_file, "r"); + + if (keys_fd == NULL) + { + fprintf(stderr, "Unable to open file %s: %s\n", keys_file, strerror(errno)); + return -1; + } + + if (seed == UINT_MAX) seed = (cmph_uint32)time(NULL); + if(nkeys == UINT_MAX) source = cmph_io_nlfile_adapter(keys_fd); + else source = cmph_io_nlnkfile_adapter(keys_fd, nkeys); + if (generate) + { + //Create mphf + mphf_fd = fopen(mphf_file, "w"); + config = cmph_config_new(source); + cmph_config_set_algo(config, mph_algo); + if (nhashes) cmph_config_set_hashfuncs(config, hashes); + cmph_config_set_verbosity(config, verbosity); + cmph_config_set_tmp_dir(config, (cmph_uint8 *) tmp_dir); + cmph_config_set_mphf_fd(config, mphf_fd); + cmph_config_set_memory_availability(config, memory_availability); + cmph_config_set_b(config, b); + cmph_config_set_keys_per_bin(config, keys_per_bin); + + //if((mph_algo == CMPH_BMZ || mph_algo == CMPH_BRZ) && c >= 2.0) c=1.15; + if(mph_algo == CMPH_BMZ && c >= 2.0) c=1.15; + if (c != 0) cmph_config_set_graphsize(config, c); + mphf = cmph_new(config); + + cmph_config_destroy(config); + if (mphf == NULL) + { + fprintf(stderr, "Unable to create minimum perfect hashing function\n"); + //cmph_config_destroy(config); + free(mphf_file); + return -1; + } + + if (mphf_fd == NULL) + { + fprintf(stderr, "Unable to open output file %s: %s\n", mphf_file, strerror(errno)); + free(mphf_file); + return -1; + } + cmph_dump(mphf, mphf_fd); + cmph_destroy(mphf); + fclose(mphf_fd); + } + else + { + cmph_uint8 * hashtable = NULL; + mphf_fd = fopen(mphf_file, "r"); + if (mphf_fd == NULL) + { + fprintf(stderr, "Unable to open input file %s: %s\n", mphf_file, strerror(errno)); + free(mphf_file); + return -1; + } + mphf = cmph_load(mphf_fd); + fclose(mphf_fd); + if (!mphf) + { + fprintf(stderr, "Unable to parser input file %s\n", mphf_file); + free(mphf_file); + return -1; + } + cmph_uint32 siz = cmph_size(mphf); + hashtable = (cmph_uint8*)calloc(siz, sizeof(cmph_uint8)); + memset(hashtable, 0,(size_t) siz); + //check all keys + for (i = 0; i < source->nkeys; ++i) + { + cmph_uint32 h; + char *buf; + cmph_uint32 buflen = 0; + source->read(source->data, &buf, &buflen); + h = cmph_search(mphf, buf, buflen); + if (!(h < siz)) + { + fprintf(stderr, "Unknown key %*s in the input.\n", buflen, buf); + ret = 1; + } else if(hashtable[h] >= keys_per_bin) + { + fprintf(stderr, "More than %u keys were mapped to bin %u\n", keys_per_bin, h); + fprintf(stderr, "Duplicated or unknown key %*s in the input\n", buflen, buf); + ret = 1; + } else hashtable[h]++; + + if (verbosity) + { + printf("%s -> %u\n", buf, h); + } + source->dispose(source->data, buf, buflen); + } + + cmph_destroy(mphf); + free(hashtable); + } + fclose(keys_fd); + free(mphf_file); + free(tmp_dir); + cmph_io_nlfile_adapter_destroy(source); + return ret; + +} diff --git a/cmph/miller_rabin.c b/cmph/miller_rabin.c new file mode 100644 index 000000000..17d0ed344 --- /dev/null +++ b/cmph/miller_rabin.c @@ -0,0 +1,67 @@ +#include "miller_rabin.h" + +static inline cmph_uint64 int_pow(cmph_uint64 a, cmph_uint64 d, cmph_uint64 n) +{ + cmph_uint64 a_pow = a; + cmph_uint64 res = 1; + while(d > 0) + { + if((d & 1) == 1) + res =(((cmph_uint64)res) * a_pow) % n; + a_pow = (((cmph_uint64)a_pow) * a_pow) % n; + d /= 2; + }; + return res; +}; + +static inline cmph_uint8 check_witness(cmph_uint64 a_exp_d, cmph_uint64 n, cmph_uint64 s) +{ + cmph_uint64 i; + cmph_uint64 a_exp = a_exp_d; + if(a_exp == 1 || a_exp == (n - 1)) + return 1; + for(i = 1; i < s; i++) + { + a_exp = (((cmph_uint64)a_exp) * a_exp) % n; + if(a_exp == (n - 1)) + return 1; + }; + return 0; +}; + +cmph_uint8 check_primality(cmph_uint64 n) +{ + cmph_uint64 a, d, s, a_exp_d; + if((n % 2) == 0) + return 0; + if((n % 3) == 0) + return 0; + if((n % 5) == 0) + return 0; + if((n % 7 ) == 0) + return 0; + //we decompoe the number n - 1 into 2^s*d + s = 0; + d = n - 1; + do + { + s++; + d /= 2; + }while((d % 2) == 0); + + a = 2; + a_exp_d = int_pow(a, d, n); + if(check_witness(a_exp_d, n, s) == 0) + return 0; + a = 7; + a_exp_d = int_pow(a, d, n); + if(check_witness(a_exp_d, n, s) == 0) + return 0; + a = 61; + a_exp_d = int_pow(a, d, n); + if(check_witness(a_exp_d, n, s) == 0) + return 0; + return 1; +}; + + diff --git a/cmph/miller_rabin.h b/cmph/miller_rabin.h new file mode 100644 index 000000000..42dc6ce5e --- /dev/null +++ b/cmph/miller_rabin.h @@ -0,0 +1,5 @@ +#ifndef _CMPH_MILLER_RABIN_H__ +#define _CMPH_MILLER_RABIN_H__ +#include "cmph_types.h" +cmph_uint8 check_primality(cmph_uint64 n); +#endif diff --git a/cmph/sdbm_hash.c b/cmph/sdbm_hash.c new file mode 100644 index 000000000..2f706c9ff --- /dev/null +++ b/cmph/sdbm_hash.c @@ -0,0 +1,49 @@ +#include "sdbm_hash.h" +#include + +sdbm_state_t *sdbm_state_new() +{ + sdbm_state_t *state = (sdbm_state_t *)malloc(sizeof(sdbm_state_t)); + state->hashfunc = CMPH_HASH_SDBM; + return state; +} + +void sdbm_state_destroy(sdbm_state_t *state) +{ + free(state); +} + +cmph_uint32 sdbm_hash(sdbm_state_t *state, const char *k, cmph_uint32 keylen) +{ + register cmph_uint32 hash = 0; + const unsigned char *ptr = (unsigned char *)k; + cmph_uint32 i = 0; + + while(i < keylen) { + hash = *ptr + (hash << 6) + (hash << 16) - hash; + ++ptr, ++i; + } + return hash; +} + + +void sdbm_state_dump(sdbm_state_t *state, char **buf, cmph_uint32 *buflen) +{ + *buf = NULL; + *buflen = 0; + return; +} + +sdbm_state_t *sdbm_state_copy(sdbm_state_t *src_state) +{ + sdbm_state_t *dest_state = (sdbm_state_t *)malloc(sizeof(sdbm_state_t)); + dest_state->hashfunc = src_state->hashfunc; + return dest_state; +} + +sdbm_state_t *sdbm_state_load(const char *buf, cmph_uint32 buflen) +{ + sdbm_state_t *state = (sdbm_state_t *)malloc(sizeof(sdbm_state_t)); + state->hashfunc = CMPH_HASH_SDBM; + return state; +} diff --git a/cmph/sdbm_hash.h b/cmph/sdbm_hash.h new file mode 100644 index 000000000..f44b2f15a --- /dev/null +++ b/cmph/sdbm_hash.h @@ -0,0 +1,18 @@ +#ifndef __SDBM_HASH_H__ +#define __SDBM_HASH_H__ + +#include "hash.h" + +typedef struct __sdbm_state_t +{ + CMPH_HASH hashfunc; +} sdbm_state_t; + +sdbm_state_t *sdbm_state_new(); +cmph_uint32 sdbm_hash(sdbm_state_t *state, const char *k, cmph_uint32 keylen); +void sdbm_state_dump(sdbm_state_t *state, char **buf, cmph_uint32 *buflen); +sdbm_state_t *sdbm_state_copy(sdbm_state_t *src_state); +sdbm_state_t *sdbm_state_load(const char *buf, cmph_uint32 buflen); +void sdbm_state_destroy(sdbm_state_t *state); + +#endif diff --git a/cmph/select.c b/cmph/select.c new file mode 100644 index 000000000..fec4b7ada --- /dev/null +++ b/cmph/select.c @@ -0,0 +1,337 @@ +#include +#include +#include +#include +#include +#include "select_lookup_tables.h" +#include "select.h" + +//#define DEBUG +#include "debug.h" + +#ifndef STEP_SELECT_TABLE +#define STEP_SELECT_TABLE 128 +#endif + +#ifndef NBITS_STEP_SELECT_TABLE +#define NBITS_STEP_SELECT_TABLE 7 +#endif + +#ifndef MASK_STEP_SELECT_TABLE +#define MASK_STEP_SELECT_TABLE 0x7f // 0x7f = 127 +#endif + +static inline void select_insert_0(cmph_uint32 * buffer) +{ + (*buffer) >>= 1; +}; + +static inline void select_insert_1(cmph_uint32 * buffer) +{ + (*buffer) >>= 1; + (*buffer) |= 0x80000000; +}; + +void select_init(select_t * sel) +{ + sel->n = 0; + sel->m = 0; + sel->bits_vec = 0; + sel->select_table = 0; +}; + +cmph_uint32 select_get_space_usage(select_t * sel) +{ + register cmph_uint32 nbits; + register cmph_uint32 vec_size; + register cmph_uint32 sel_table_size; + register cmph_uint32 space_usage; + + nbits = sel->n + sel->m; + vec_size = (nbits + 31) >> 5; + sel_table_size = (sel->n >> NBITS_STEP_SELECT_TABLE) + 1; // (sel->n >> NBITS_STEP_SELECT_TABLE) = (sel->n/STEP_SELECT_TABLE) + + space_usage = 2 * sizeof(cmph_uint32) * 8; // n and m + space_usage += vec_size * (cmph_uint32) sizeof(cmph_uint32) * 8; + space_usage += sel_table_size * (cmph_uint32)sizeof(cmph_uint32) * 8; + return space_usage; +} + +void select_destroy(select_t * sel) +{ + free(sel->bits_vec); + free(sel->select_table); + sel->bits_vec = 0; + sel->select_table = 0; +}; + +static inline void select_generate_sel_table(select_t * sel) +{ + register cmph_uint8 * bits_table = (cmph_uint8 *)sel->bits_vec; + register cmph_uint32 part_sum, old_part_sum; + register cmph_uint32 vec_idx, one_idx, sel_table_idx; + + part_sum = vec_idx = one_idx = sel_table_idx = 0; + + for(;;) + { + // FABIANO: Should'n it be one_idx >= sel->n + if(one_idx >= sel->n) + break; + do + { + old_part_sum = part_sum; + part_sum += rank_lookup_table[bits_table[vec_idx]]; + vec_idx++; + } while (part_sum <= one_idx); + + sel->select_table[sel_table_idx] = select_lookup_table[bits_table[vec_idx - 1]][one_idx - old_part_sum] + ((vec_idx - 1) << 3); // ((vec_idx - 1) << 3) = ((vec_idx - 1) * 8) + one_idx += STEP_SELECT_TABLE ; + sel_table_idx++; + }; +}; + +void select_generate(select_t * sel, cmph_uint32 * keys_vec, cmph_uint32 n, cmph_uint32 m) +{ + register cmph_uint32 i, j, idx; + cmph_uint32 buffer = 0; + + register cmph_uint32 nbits; + register cmph_uint32 vec_size; + register cmph_uint32 sel_table_size; + sel->n = n; + sel->m = m; // n values in the range [0,m-1] + + nbits = sel->n + sel->m; + vec_size = (nbits + 31) >> 5; // (nbits + 31) >> 5 = (nbits + 31)/32 + + sel_table_size = (sel->n >> NBITS_STEP_SELECT_TABLE) + 1; // (sel->n >> NBITS_STEP_SELECT_TABLE) = (sel->n/STEP_SELECT_TABLE) + + if(sel->bits_vec) + { + free(sel->bits_vec); + } + sel->bits_vec = (cmph_uint32 *)calloc(vec_size, sizeof(cmph_uint32)); + + if(sel->select_table) + { + free(sel->select_table); + } + sel->select_table = (cmph_uint32 *)calloc(sel_table_size, sizeof(cmph_uint32)); + + + + idx = i = j = 0; + + for(;;) + { + while(keys_vec[j]==i) + { + select_insert_1(&buffer); + idx++; + + if((idx & 0x1f) == 0 ) // (idx & 0x1f) = idx % 32 + sel->bits_vec[(idx >> 5) - 1] = buffer; // (idx >> 5) = idx/32 + j++; + + if(j == sel->n) + goto loop_end; + + //assert(keys_vec[j] < keys_vec[j-1]); + } + + if(i == sel->m) + break; + + while(keys_vec[j] > i) + { + select_insert_0(&buffer); + idx++; + + if((idx & 0x1f) == 0 ) // (idx & 0x1f) = idx % 32 + sel->bits_vec[(idx >> 5) - 1] = buffer; // (idx >> 5) = idx/32 + i++; + }; + + }; + loop_end: + if((idx & 0x1f) != 0 ) // (idx & 0x1f) = idx % 32 + { + buffer >>= 32 - (idx & 0x1f); + sel->bits_vec[ (idx - 1) >> 5 ] = buffer; + }; + + select_generate_sel_table(sel); +}; + +static inline cmph_uint32 _select_query(cmph_uint8 * bits_table, cmph_uint32 * select_table, cmph_uint32 one_idx) +{ + register cmph_uint32 vec_bit_idx ,vec_byte_idx; + register cmph_uint32 part_sum, old_part_sum; + + vec_bit_idx = select_table[one_idx >> NBITS_STEP_SELECT_TABLE]; // one_idx >> NBITS_STEP_SELECT_TABLE = one_idx/STEP_SELECT_TABLE + vec_byte_idx = vec_bit_idx >> 3; // vec_bit_idx / 8 + + one_idx &= MASK_STEP_SELECT_TABLE; // one_idx %= STEP_SELECT_TABLE == one_idx &= MASK_STEP_SELECT_TABLE + one_idx += rank_lookup_table[bits_table[vec_byte_idx] & ((1 << (vec_bit_idx & 0x7)) - 1)]; + part_sum = 0; + + do + { + old_part_sum = part_sum; + part_sum += rank_lookup_table[bits_table[vec_byte_idx]]; + vec_byte_idx++; + + }while (part_sum <= one_idx); + + return select_lookup_table[bits_table[vec_byte_idx - 1]][one_idx - old_part_sum] + ((vec_byte_idx-1) << 3); +} + +cmph_uint32 select_query(select_t * sel, cmph_uint32 one_idx) +{ + return _select_query((cmph_uint8 *)sel->bits_vec, sel->select_table, one_idx); +}; + + +static inline cmph_uint32 _select_next_query(cmph_uint8 * bits_table, cmph_uint32 vec_bit_idx) +{ + register cmph_uint32 vec_byte_idx, one_idx; + register cmph_uint32 part_sum, old_part_sum; + + vec_byte_idx = vec_bit_idx >> 3; + + one_idx = rank_lookup_table[bits_table[vec_byte_idx] & ((1U << (vec_bit_idx & 0x7)) - 1U)] + 1U; + part_sum = 0; + + do + { + old_part_sum = part_sum; + part_sum += rank_lookup_table[bits_table[vec_byte_idx]]; + vec_byte_idx++; + + }while (part_sum <= one_idx); + + return select_lookup_table[bits_table[(vec_byte_idx - 1)]][(one_idx - old_part_sum)] + ((vec_byte_idx - 1) << 3); +} + +cmph_uint32 select_next_query(select_t * sel, cmph_uint32 vec_bit_idx) +{ + return _select_next_query((cmph_uint8 *)sel->bits_vec, vec_bit_idx); +}; + +void select_dump(select_t *sel, char **buf, cmph_uint32 *buflen) +{ + register cmph_uint32 nbits = sel->n + sel->m; + register cmph_uint32 vec_size = ((nbits + 31) >> 5) * (cmph_uint32)sizeof(cmph_uint32); // (nbits + 31) >> 5 = (nbits + 31)/32 + register cmph_uint32 sel_table_size = ((sel->n >> NBITS_STEP_SELECT_TABLE) + 1) * (cmph_uint32)sizeof(cmph_uint32); // (sel->n >> NBITS_STEP_SELECT_TABLE) = (sel->n/STEP_SELECT_TABLE) + register cmph_uint32 pos = 0; + + *buflen = 2*(cmph_uint32)sizeof(cmph_uint32) + vec_size + sel_table_size; + + *buf = (char *)calloc(*buflen, sizeof(char)); + + if (!*buf) + { + *buflen = UINT_MAX; + return; + } + + memcpy(*buf, &(sel->n), sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + memcpy(*buf + pos, &(sel->m), sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + memcpy(*buf + pos, sel->bits_vec, vec_size); + pos += vec_size; + memcpy(*buf + pos, sel->select_table, sel_table_size); + + DEBUGP("Dumped select structure with size %u bytes\n", *buflen); +} + +void select_load(select_t * sel, const char *buf, cmph_uint32 buflen) +{ + register cmph_uint32 pos = 0; + register cmph_uint32 nbits = 0; + register cmph_uint32 vec_size = 0; + register cmph_uint32 sel_table_size = 0; + + memcpy(&(sel->n), buf, sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + memcpy(&(sel->m), buf + pos, sizeof(cmph_uint32)); + pos += (cmph_uint32)sizeof(cmph_uint32); + + nbits = sel->n + sel->m; + vec_size = ((nbits + 31) >> 5) * (cmph_uint32)sizeof(cmph_uint32); // (nbits + 31) >> 5 = (nbits + 31)/32 + sel_table_size = ((sel->n >> NBITS_STEP_SELECT_TABLE) + 1) * (cmph_uint32)sizeof(cmph_uint32); // (sel->n >> NBITS_STEP_SELECT_TABLE) = (sel->n/STEP_SELECT_TABLE) + + if(sel->bits_vec) + { + free(sel->bits_vec); + } + sel->bits_vec = (cmph_uint32 *)calloc(vec_size/sizeof(cmph_uint32), sizeof(cmph_uint32)); + + if(sel->select_table) + { + free(sel->select_table); + } + sel->select_table = (cmph_uint32 *)calloc(sel_table_size/sizeof(cmph_uint32), sizeof(cmph_uint32)); + + memcpy(sel->bits_vec, buf + pos, vec_size); + pos += vec_size; + memcpy(sel->select_table, buf + pos, sel_table_size); + + DEBUGP("Loaded select structure with size %u bytes\n", buflen); +} + + +/** \fn void select_pack(select_t *sel, void *sel_packed); + * \brief Support the ability to pack a select structure function into a preallocated contiguous memory space pointed by sel_packed. + * \param sel points to the select structure + * \param sel_packed pointer to the contiguous memory area used to store the select structure. The size of sel_packed must be at least @see select_packed_size + */ +void select_pack(select_t *sel, void *sel_packed) +{ + if (sel && sel_packed) + { + char *buf = NULL; + cmph_uint32 buflen = 0; + select_dump(sel, &buf, &buflen); + memcpy(sel_packed, buf, buflen); + free(buf); + } +} + + +/** \fn cmph_uint32 select_packed_size(select_t *sel); + * \brief Return the amount of space needed to pack a select structure. + * \return the size of the packed select structure or zero for failures + */ +cmph_uint32 select_packed_size(select_t *sel) +{ + register cmph_uint32 nbits = sel->n + sel->m; + register cmph_uint32 vec_size = ((nbits + 31) >> 5) * (cmph_uint32)sizeof(cmph_uint32); // (nbits + 31) >> 5 = (nbits + 31)/32 + register cmph_uint32 sel_table_size = ((sel->n >> NBITS_STEP_SELECT_TABLE) + 1) * (cmph_uint32)sizeof(cmph_uint32); // (sel->n >> NBITS_STEP_SELECT_TABLE) = (sel->n/STEP_SELECT_TABLE) + return 2*(cmph_uint32)sizeof(cmph_uint32) + vec_size + sel_table_size; +} + + + +cmph_uint32 select_query_packed(void * sel_packed, cmph_uint32 one_idx) +{ + register cmph_uint32 *ptr = (cmph_uint32 *)sel_packed; + register cmph_uint32 n = *ptr++; + register cmph_uint32 m = *ptr++; + register cmph_uint32 nbits = n + m; + register cmph_uint32 vec_size = (nbits + 31) >> 5; // (nbits + 31) >> 5 = (nbits + 31)/32 + register cmph_uint8 * bits_vec = (cmph_uint8 *)ptr; + register cmph_uint32 * select_table = ptr + vec_size; + + return _select_query(bits_vec, select_table, one_idx); +} + + +cmph_uint32 select_next_query_packed(void * sel_packed, cmph_uint32 vec_bit_idx) +{ + register cmph_uint8 * bits_vec = (cmph_uint8 *)sel_packed; + bits_vec += 8; // skipping n and m + return _select_next_query(bits_vec, vec_bit_idx); +} diff --git a/cmph/select.h b/cmph/select.h new file mode 100644 index 000000000..a31eb0f22 --- /dev/null +++ b/cmph/select.h @@ -0,0 +1,61 @@ +#ifndef __CMPH_SELECT_H__ +#define __CMPH_SELECT_H__ + +#include "cmph_types.h" + +struct _select_t +{ + cmph_uint32 n,m; + cmph_uint32 * bits_vec; + cmph_uint32 * select_table; +}; + +typedef struct _select_t select_t; + +void select_init(select_t * sel); + +void select_destroy(select_t * sel); + +void select_generate(select_t * sel, cmph_uint32 * keys_vec, cmph_uint32 n, cmph_uint32 m); + +cmph_uint32 select_query(select_t * sel, cmph_uint32 one_idx); + +cmph_uint32 select_next_query(select_t * sel, cmph_uint32 vec_bit_idx); + +cmph_uint32 select_get_space_usage(select_t * sel); + +void select_dump(select_t *sel, char **buf, cmph_uint32 *buflen); + +void select_load(select_t * sel, const char *buf, cmph_uint32 buflen); + + +/** \fn void select_pack(select_t *sel, void *sel_packed); + * \brief Support the ability to pack a select structure into a preallocated contiguous memory space pointed by sel_packed. + * \param sel points to the select structure + * \param sel_packed pointer to the contiguous memory area used to store the select structure. The size of sel_packed must be at least @see select_packed_size + */ +void select_pack(select_t *sel, void *sel_packed); + +/** \fn cmph_uint32 select_packed_size(select_t *sel); + * \brief Return the amount of space needed to pack a select structure. + * \return the size of the packed select structure or zero for failures + */ +cmph_uint32 select_packed_size(select_t *sel); + + +/** \fn cmph_uint32 select_query_packed(void * sel_packed, cmph_uint32 one_idx); + * \param sel_packed is a pointer to a contiguous memory area + * \param one_idx is the rank for which we want to calculate the inverse function select + * \return an integer that represents the select value of rank idx. + */ +cmph_uint32 select_query_packed(void * sel_packed, cmph_uint32 one_idx); + + +/** \fn cmph_uint32 select_next_query_packed(void * sel_packed, cmph_uint32 vec_bit_idx); + * \param sel_packed is a pointer to a contiguous memory area + * \param vec_bit_idx is a value prior computed by @see select_query_packed + * \return an integer that represents the next select value greater than @see vec_bit_idx. + */ +cmph_uint32 select_next_query_packed(void * sel_packed, cmph_uint32 vec_bit_idx); + +#endif diff --git a/cmph/select_lookup_tables.h b/cmph/select_lookup_tables.h new file mode 100644 index 000000000..efd595ed5 --- /dev/null +++ b/cmph/select_lookup_tables.h @@ -0,0 +1,170 @@ +#ifndef SELECT_LOOKUP_TABLES +#define SELECT_LOOKUP_TABLES + +#include "cmph_types.h" + +/* +rank_lookup_table[i] simply gives the number of bits set to one in the byte of value i. +For example if i = 01010101 in binary then we have : +rank_lookup_table[i] = 4 +*/ + +static cmph_uint8 rank_lookup_table[256] ={ + 0 , 1 , 1 , 2 , 1 , 2 , 2 , 3 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 +, 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 +, 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 +, 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 +, 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 +, 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 +, 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 +, 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 +, 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 +, 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 +, 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 +, 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 +, 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 +, 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 +, 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 +, 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 , 5 , 6 , 6 , 7 , 6 , 7 , 7 , 8 + }; + +/* +select_lookup_table[i][j] simply gives the index of the j'th bit set to one in the byte of value i. +For example if i=01010101 in binary then we have : +select_lookup_table[i][0] = 0, the first bit set to one is at position 0 +select_lookup_table[i][1] = 2, the second bit set to one is at position 2 +select_lookup_table[i][2] = 4, the third bit set to one is at position 4 +select_lookup_table[i][3] = 6, the fourth bit set to one is at position 6 +select_lookup_table[i][4] = 255, there is no more than 4 bits set to one in i, so we return escape value 255. +*/ +static cmph_uint8 select_lookup_table[256][8]={ +{ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 255 , 255 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 255 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 255 , 255 , 255 , 255 , 255 , 255 } , +{ 2 , 255 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 2 , 255 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 2 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 2 , 255 , 255 , 255 , 255 , 255 } , +{ 3 , 255 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 3 , 255 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 3 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 3 , 255 , 255 , 255 , 255 , 255 } , +{ 2 , 3 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 2 , 3 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 2 , 3 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 2 , 3 , 255 , 255 , 255 , 255 } , +{ 4 , 255 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 4 , 255 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 4 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 4 , 255 , 255 , 255 , 255 , 255 } , +{ 2 , 4 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 2 , 4 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 2 , 4 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 2 , 4 , 255 , 255 , 255 , 255 } , +{ 3 , 4 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 3 , 4 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 3 , 4 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 3 , 4 , 255 , 255 , 255 , 255 } , +{ 2 , 3 , 4 , 255 , 255 , 255 , 255 , 255 } , { 0 , 2 , 3 , 4 , 255 , 255 , 255 , 255 } , +{ 1 , 2 , 3 , 4 , 255 , 255 , 255 , 255 } , { 0 , 1 , 2 , 3 , 4 , 255 , 255 , 255 } , +{ 5 , 255 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 5 , 255 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 5 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 5 , 255 , 255 , 255 , 255 , 255 } , +{ 2 , 5 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 2 , 5 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 2 , 5 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 2 , 5 , 255 , 255 , 255 , 255 } , +{ 3 , 5 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 3 , 5 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 3 , 5 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 3 , 5 , 255 , 255 , 255 , 255 } , +{ 2 , 3 , 5 , 255 , 255 , 255 , 255 , 255 } , { 0 , 2 , 3 , 5 , 255 , 255 , 255 , 255 } , +{ 1 , 2 , 3 , 5 , 255 , 255 , 255 , 255 } , { 0 , 1 , 2 , 3 , 5 , 255 , 255 , 255 } , +{ 4 , 5 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 4 , 5 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 4 , 5 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 4 , 5 , 255 , 255 , 255 , 255 } , +{ 2 , 4 , 5 , 255 , 255 , 255 , 255 , 255 } , { 0 , 2 , 4 , 5 , 255 , 255 , 255 , 255 } , +{ 1 , 2 , 4 , 5 , 255 , 255 , 255 , 255 } , { 0 , 1 , 2 , 4 , 5 , 255 , 255 , 255 } , +{ 3 , 4 , 5 , 255 , 255 , 255 , 255 , 255 } , { 0 , 3 , 4 , 5 , 255 , 255 , 255 , 255 } , +{ 1 , 3 , 4 , 5 , 255 , 255 , 255 , 255 } , { 0 , 1 , 3 , 4 , 5 , 255 , 255 , 255 } , +{ 2 , 3 , 4 , 5 , 255 , 255 , 255 , 255 } , { 0 , 2 , 3 , 4 , 5 , 255 , 255 , 255 } , +{ 1 , 2 , 3 , 4 , 5 , 255 , 255 , 255 } , { 0 , 1 , 2 , 3 , 4 , 5 , 255 , 255 } , +{ 6 , 255 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 6 , 255 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 6 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 6 , 255 , 255 , 255 , 255 , 255 } , +{ 2 , 6 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 2 , 6 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 2 , 6 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 2 , 6 , 255 , 255 , 255 , 255 } , +{ 3 , 6 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 3 , 6 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 3 , 6 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 3 , 6 , 255 , 255 , 255 , 255 } , +{ 2 , 3 , 6 , 255 , 255 , 255 , 255 , 255 } , { 0 , 2 , 3 , 6 , 255 , 255 , 255 , 255 } , +{ 1 , 2 , 3 , 6 , 255 , 255 , 255 , 255 } , { 0 , 1 , 2 , 3 , 6 , 255 , 255 , 255 } , +{ 4 , 6 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 4 , 6 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 4 , 6 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 4 , 6 , 255 , 255 , 255 , 255 } , +{ 2 , 4 , 6 , 255 , 255 , 255 , 255 , 255 } , { 0 , 2 , 4 , 6 , 255 , 255 , 255 , 255 } , +{ 1 , 2 , 4 , 6 , 255 , 255 , 255 , 255 } , { 0 , 1 , 2 , 4 , 6 , 255 , 255 , 255 } , +{ 3 , 4 , 6 , 255 , 255 , 255 , 255 , 255 } , { 0 , 3 , 4 , 6 , 255 , 255 , 255 , 255 } , +{ 1 , 3 , 4 , 6 , 255 , 255 , 255 , 255 } , { 0 , 1 , 3 , 4 , 6 , 255 , 255 , 255 } , +{ 2 , 3 , 4 , 6 , 255 , 255 , 255 , 255 } , { 0 , 2 , 3 , 4 , 6 , 255 , 255 , 255 } , +{ 1 , 2 , 3 , 4 , 6 , 255 , 255 , 255 } , { 0 , 1 , 2 , 3 , 4 , 6 , 255 , 255 } , +{ 5 , 6 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 5 , 6 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 5 , 6 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 5 , 6 , 255 , 255 , 255 , 255 } , +{ 2 , 5 , 6 , 255 , 255 , 255 , 255 , 255 } , { 0 , 2 , 5 , 6 , 255 , 255 , 255 , 255 } , +{ 1 , 2 , 5 , 6 , 255 , 255 , 255 , 255 } , { 0 , 1 , 2 , 5 , 6 , 255 , 255 , 255 } , +{ 3 , 5 , 6 , 255 , 255 , 255 , 255 , 255 } , { 0 , 3 , 5 , 6 , 255 , 255 , 255 , 255 } , +{ 1 , 3 , 5 , 6 , 255 , 255 , 255 , 255 } , { 0 , 1 , 3 , 5 , 6 , 255 , 255 , 255 } , +{ 2 , 3 , 5 , 6 , 255 , 255 , 255 , 255 } , { 0 , 2 , 3 , 5 , 6 , 255 , 255 , 255 } , +{ 1 , 2 , 3 , 5 , 6 , 255 , 255 , 255 } , { 0 , 1 , 2 , 3 , 5 , 6 , 255 , 255 } , +{ 4 , 5 , 6 , 255 , 255 , 255 , 255 , 255 } , { 0 , 4 , 5 , 6 , 255 , 255 , 255 , 255 } , +{ 1 , 4 , 5 , 6 , 255 , 255 , 255 , 255 } , { 0 , 1 , 4 , 5 , 6 , 255 , 255 , 255 } , +{ 2 , 4 , 5 , 6 , 255 , 255 , 255 , 255 } , { 0 , 2 , 4 , 5 , 6 , 255 , 255 , 255 } , +{ 1 , 2 , 4 , 5 , 6 , 255 , 255 , 255 } , { 0 , 1 , 2 , 4 , 5 , 6 , 255 , 255 } , +{ 3 , 4 , 5 , 6 , 255 , 255 , 255 , 255 } , { 0 , 3 , 4 , 5 , 6 , 255 , 255 , 255 } , +{ 1 , 3 , 4 , 5 , 6 , 255 , 255 , 255 } , { 0 , 1 , 3 , 4 , 5 , 6 , 255 , 255 } , +{ 2 , 3 , 4 , 5 , 6 , 255 , 255 , 255 } , { 0 , 2 , 3 , 4 , 5 , 6 , 255 , 255 } , +{ 1 , 2 , 3 , 4 , 5 , 6 , 255 , 255 } , { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 255 } , +{ 7 , 255 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 7 , 255 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 7 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 7 , 255 , 255 , 255 , 255 , 255 } , +{ 2 , 7 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 2 , 7 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 2 , 7 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 2 , 7 , 255 , 255 , 255 , 255 } , +{ 3 , 7 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 3 , 7 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 3 , 7 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 3 , 7 , 255 , 255 , 255 , 255 } , +{ 2 , 3 , 7 , 255 , 255 , 255 , 255 , 255 } , { 0 , 2 , 3 , 7 , 255 , 255 , 255 , 255 } , +{ 1 , 2 , 3 , 7 , 255 , 255 , 255 , 255 } , { 0 , 1 , 2 , 3 , 7 , 255 , 255 , 255 } , +{ 4 , 7 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 4 , 7 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 4 , 7 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 4 , 7 , 255 , 255 , 255 , 255 } , +{ 2 , 4 , 7 , 255 , 255 , 255 , 255 , 255 } , { 0 , 2 , 4 , 7 , 255 , 255 , 255 , 255 } , +{ 1 , 2 , 4 , 7 , 255 , 255 , 255 , 255 } , { 0 , 1 , 2 , 4 , 7 , 255 , 255 , 255 } , +{ 3 , 4 , 7 , 255 , 255 , 255 , 255 , 255 } , { 0 , 3 , 4 , 7 , 255 , 255 , 255 , 255 } , +{ 1 , 3 , 4 , 7 , 255 , 255 , 255 , 255 } , { 0 , 1 , 3 , 4 , 7 , 255 , 255 , 255 } , +{ 2 , 3 , 4 , 7 , 255 , 255 , 255 , 255 } , { 0 , 2 , 3 , 4 , 7 , 255 , 255 , 255 } , +{ 1 , 2 , 3 , 4 , 7 , 255 , 255 , 255 } , { 0 , 1 , 2 , 3 , 4 , 7 , 255 , 255 } , +{ 5 , 7 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 5 , 7 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 5 , 7 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 5 , 7 , 255 , 255 , 255 , 255 } , +{ 2 , 5 , 7 , 255 , 255 , 255 , 255 , 255 } , { 0 , 2 , 5 , 7 , 255 , 255 , 255 , 255 } , +{ 1 , 2 , 5 , 7 , 255 , 255 , 255 , 255 } , { 0 , 1 , 2 , 5 , 7 , 255 , 255 , 255 } , +{ 3 , 5 , 7 , 255 , 255 , 255 , 255 , 255 } , { 0 , 3 , 5 , 7 , 255 , 255 , 255 , 255 } , +{ 1 , 3 , 5 , 7 , 255 , 255 , 255 , 255 } , { 0 , 1 , 3 , 5 , 7 , 255 , 255 , 255 } , +{ 2 , 3 , 5 , 7 , 255 , 255 , 255 , 255 } , { 0 , 2 , 3 , 5 , 7 , 255 , 255 , 255 } , +{ 1 , 2 , 3 , 5 , 7 , 255 , 255 , 255 } , { 0 , 1 , 2 , 3 , 5 , 7 , 255 , 255 } , +{ 4 , 5 , 7 , 255 , 255 , 255 , 255 , 255 } , { 0 , 4 , 5 , 7 , 255 , 255 , 255 , 255 } , +{ 1 , 4 , 5 , 7 , 255 , 255 , 255 , 255 } , { 0 , 1 , 4 , 5 , 7 , 255 , 255 , 255 } , +{ 2 , 4 , 5 , 7 , 255 , 255 , 255 , 255 } , { 0 , 2 , 4 , 5 , 7 , 255 , 255 , 255 } , +{ 1 , 2 , 4 , 5 , 7 , 255 , 255 , 255 } , { 0 , 1 , 2 , 4 , 5 , 7 , 255 , 255 } , +{ 3 , 4 , 5 , 7 , 255 , 255 , 255 , 255 } , { 0 , 3 , 4 , 5 , 7 , 255 , 255 , 255 } , +{ 1 , 3 , 4 , 5 , 7 , 255 , 255 , 255 } , { 0 , 1 , 3 , 4 , 5 , 7 , 255 , 255 } , +{ 2 , 3 , 4 , 5 , 7 , 255 , 255 , 255 } , { 0 , 2 , 3 , 4 , 5 , 7 , 255 , 255 } , +{ 1 , 2 , 3 , 4 , 5 , 7 , 255 , 255 } , { 0 , 1 , 2 , 3 , 4 , 5 , 7 , 255 } , +{ 6 , 7 , 255 , 255 , 255 , 255 , 255 , 255 } , { 0 , 6 , 7 , 255 , 255 , 255 , 255 , 255 } , +{ 1 , 6 , 7 , 255 , 255 , 255 , 255 , 255 } , { 0 , 1 , 6 , 7 , 255 , 255 , 255 , 255 } , +{ 2 , 6 , 7 , 255 , 255 , 255 , 255 , 255 } , { 0 , 2 , 6 , 7 , 255 , 255 , 255 , 255 } , +{ 1 , 2 , 6 , 7 , 255 , 255 , 255 , 255 } , { 0 , 1 , 2 , 6 , 7 , 255 , 255 , 255 } , +{ 3 , 6 , 7 , 255 , 255 , 255 , 255 , 255 } , { 0 , 3 , 6 , 7 , 255 , 255 , 255 , 255 } , +{ 1 , 3 , 6 , 7 , 255 , 255 , 255 , 255 } , { 0 , 1 , 3 , 6 , 7 , 255 , 255 , 255 } , +{ 2 , 3 , 6 , 7 , 255 , 255 , 255 , 255 } , { 0 , 2 , 3 , 6 , 7 , 255 , 255 , 255 } , +{ 1 , 2 , 3 , 6 , 7 , 255 , 255 , 255 } , { 0 , 1 , 2 , 3 , 6 , 7 , 255 , 255 } , +{ 4 , 6 , 7 , 255 , 255 , 255 , 255 , 255 } , { 0 , 4 , 6 , 7 , 255 , 255 , 255 , 255 } , +{ 1 , 4 , 6 , 7 , 255 , 255 , 255 , 255 } , { 0 , 1 , 4 , 6 , 7 , 255 , 255 , 255 } , +{ 2 , 4 , 6 , 7 , 255 , 255 , 255 , 255 } , { 0 , 2 , 4 , 6 , 7 , 255 , 255 , 255 } , +{ 1 , 2 , 4 , 6 , 7 , 255 , 255 , 255 } , { 0 , 1 , 2 , 4 , 6 , 7 , 255 , 255 } , +{ 3 , 4 , 6 , 7 , 255 , 255 , 255 , 255 } , { 0 , 3 , 4 , 6 , 7 , 255 , 255 , 255 } , +{ 1 , 3 , 4 , 6 , 7 , 255 , 255 , 255 } , { 0 , 1 , 3 , 4 , 6 , 7 , 255 , 255 } , +{ 2 , 3 , 4 , 6 , 7 , 255 , 255 , 255 } , { 0 , 2 , 3 , 4 , 6 , 7 , 255 , 255 } , +{ 1 , 2 , 3 , 4 , 6 , 7 , 255 , 255 } , { 0 , 1 , 2 , 3 , 4 , 6 , 7 , 255 } , +{ 5 , 6 , 7 , 255 , 255 , 255 , 255 , 255 } , { 0 , 5 , 6 , 7 , 255 , 255 , 255 , 255 } , +{ 1 , 5 , 6 , 7 , 255 , 255 , 255 , 255 } , { 0 , 1 , 5 , 6 , 7 , 255 , 255 , 255 } , +{ 2 , 5 , 6 , 7 , 255 , 255 , 255 , 255 } , { 0 , 2 , 5 , 6 , 7 , 255 , 255 , 255 } , +{ 1 , 2 , 5 , 6 , 7 , 255 , 255 , 255 } , { 0 , 1 , 2 , 5 , 6 , 7 , 255 , 255 } , +{ 3 , 5 , 6 , 7 , 255 , 255 , 255 , 255 } , { 0 , 3 , 5 , 6 , 7 , 255 , 255 , 255 } , +{ 1 , 3 , 5 , 6 , 7 , 255 , 255 , 255 } , { 0 , 1 , 3 , 5 , 6 , 7 , 255 , 255 } , +{ 2 , 3 , 5 , 6 , 7 , 255 , 255 , 255 } , { 0 , 2 , 3 , 5 , 6 , 7 , 255 , 255 } , +{ 1 , 2 , 3 , 5 , 6 , 7 , 255 , 255 } , { 0 , 1 , 2 , 3 , 5 , 6 , 7 , 255 } , +{ 4 , 5 , 6 , 7 , 255 , 255 , 255 , 255 } , { 0 , 4 , 5 , 6 , 7 , 255 , 255 , 255 } , +{ 1 , 4 , 5 , 6 , 7 , 255 , 255 , 255 } , { 0 , 1 , 4 , 5 , 6 , 7 , 255 , 255 } , +{ 2 , 4 , 5 , 6 , 7 , 255 , 255 , 255 } , { 0 , 2 , 4 , 5 , 6 , 7 , 255 , 255 } , +{ 1 , 2 , 4 , 5 , 6 , 7 , 255 , 255 } , { 0 , 1 , 2 , 4 , 5 , 6 , 7 , 255 } , +{ 3 , 4 , 5 , 6 , 7 , 255 , 255 , 255 } , { 0 , 3 , 4 , 5 , 6 , 7 , 255 , 255 } , +{ 1 , 3 , 4 , 5 , 6 , 7 , 255 , 255 } , { 0 , 1 , 3 , 4 , 5 , 6 , 7 , 255 } , +{ 2 , 3 , 4 , 5 , 6 , 7 , 255 , 255 } , { 0 , 2 , 3 , 4 , 5 , 6 , 7 , 255 } , +{ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 255 } , { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 } }; + +#endif diff --git a/cmph/vqueue.c b/cmph/vqueue.c new file mode 100644 index 000000000..0619dd7cc --- /dev/null +++ b/cmph/vqueue.c @@ -0,0 +1,51 @@ +#include "vqueue.h" +#include +#include +#include +struct __vqueue_t +{ + cmph_uint32 * values; + cmph_uint32 beg, end, capacity; +}; + +vqueue_t * vqueue_new(cmph_uint32 capacity) +{ + size_t capacity_plus_one = capacity + 1; + vqueue_t *q = (vqueue_t *)malloc(sizeof(vqueue_t)); + assert(q); + q->values = (cmph_uint32 *)calloc(capacity_plus_one, sizeof(cmph_uint32)); + q->beg = q->end = 0; + q->capacity = (cmph_uint32) capacity_plus_one; + return q; +} + +cmph_uint8 vqueue_is_empty(vqueue_t * q) +{ + return (cmph_uint8)(q->beg == q->end); +} + +void vqueue_insert(vqueue_t * q, cmph_uint32 val) +{ + assert((q->end + 1)%q->capacity != q->beg); // Is queue full? + q->end = (q->end + 1)%q->capacity; + q->values[q->end] = val; +} + +cmph_uint32 vqueue_remove(vqueue_t * q) +{ + assert(!vqueue_is_empty(q)); // Is queue empty? + q->beg = (q->beg + 1)%q->capacity; + return q->values[q->beg]; +} + +void vqueue_print(vqueue_t * q) +{ + cmph_uint32 i; + for (i = q->beg; i != q->end; i = (i + 1)%q->capacity) + fprintf(stderr, "%u\n", q->values[(i + 1)%q->capacity]); +} + +void vqueue_destroy(vqueue_t *q) +{ + free(q->values); q->values = NULL; free(q); +} diff --git a/cmph/vqueue.h b/cmph/vqueue.h new file mode 100644 index 000000000..86fccab68 --- /dev/null +++ b/cmph/vqueue.h @@ -0,0 +1,18 @@ +#ifndef __CMPH_VQUEUE_H__ +#define __CMPH_VQUEUE_H__ + +#include "cmph_types.h" +typedef struct __vqueue_t vqueue_t; + +vqueue_t * vqueue_new(cmph_uint32 capacity); + +cmph_uint8 vqueue_is_empty(vqueue_t * q); + +void vqueue_insert(vqueue_t * q, cmph_uint32 val); + +cmph_uint32 vqueue_remove(vqueue_t * q); + +void vqueue_print(vqueue_t * q); + +void vqueue_destroy(vqueue_t * q); +#endif diff --git a/cmph/vstack.c b/cmph/vstack.c new file mode 100644 index 000000000..24555cd6e --- /dev/null +++ b/cmph/vstack.c @@ -0,0 +1,79 @@ +#include "vstack.h" + +#include +#include + +//#define DEBUG +#include "debug.h" + +struct __vstack_t +{ + cmph_uint32 pointer; + cmph_uint32 *values; + cmph_uint32 capacity; +}; + +vstack_t *vstack_new() +{ + vstack_t *stack = (vstack_t *)malloc(sizeof(vstack_t)); + assert(stack); + stack->pointer = 0; + stack->values = NULL; + stack->capacity = 0; + return stack; +} + +void vstack_destroy(vstack_t *stack) +{ + assert(stack); + free(stack->values); + free(stack); +} + +void vstack_push(vstack_t *stack, cmph_uint32 val) +{ + assert(stack); + vstack_reserve(stack, stack->pointer + 1); + stack->values[stack->pointer] = val; + ++(stack->pointer); +} +void vstack_pop(vstack_t *stack) +{ + assert(stack); + assert(stack->pointer > 0); + --(stack->pointer); +} + +cmph_uint32 vstack_top(vstack_t *stack) +{ + assert(stack); + assert(stack->pointer > 0); + return stack->values[(stack->pointer - 1)]; +} +int vstack_empty(vstack_t *stack) +{ + assert(stack); + return stack->pointer == 0; +} +cmph_uint32 vstack_size(vstack_t *stack) +{ + return stack->pointer; +} +void vstack_reserve(vstack_t *stack, cmph_uint32 size) +{ + assert(stack); + if (stack->capacity < size) + { + cmph_uint32 new_capacity = stack->capacity + 1; + DEBUGP("Increasing current capacity %u to %u\n", stack->capacity, size); + while (new_capacity < size) + { + new_capacity *= 2; + } + stack->values = (cmph_uint32 *)realloc(stack->values, sizeof(cmph_uint32)*new_capacity); + assert(stack->values); + stack->capacity = new_capacity; + DEBUGP("Increased\n"); + } +} + diff --git a/cmph/vstack.h b/cmph/vstack.h new file mode 100644 index 000000000..1cefaaffb --- /dev/null +++ b/cmph/vstack.h @@ -0,0 +1,18 @@ +#ifndef __CMPH_VSTACK_H__ +#define __CMPH_VSTACK_H__ + +#include "cmph_types.h" +typedef struct __vstack_t vstack_t; + +vstack_t *vstack_new(); +void vstack_destroy(vstack_t *stack); + +void vstack_push(vstack_t *stack, cmph_uint32 val); +cmph_uint32 vstack_top(vstack_t *stack); +void vstack_pop(vstack_t *stack); +int vstack_empty(vstack_t *stack); +cmph_uint32 vstack_size(vstack_t *stack); + +void vstack_reserve(vstack_t *stack, cmph_uint32 size); + +#endif diff --git a/cmph/wingetopt.c b/cmph/wingetopt.c new file mode 100644 index 000000000..c981d0f04 --- /dev/null +++ b/cmph/wingetopt.c @@ -0,0 +1,179 @@ +#ifdef WIN32 +/***************************************************************************** + * + * MODULE NAME : GETOPT.C + * + * COPYRIGHTS: + * This module contains code made available by IBM + * Corporation on an AS IS basis. Any one receiving the + * module is considered to be licensed under IBM copyrights + * to use the IBM-provided source code in any way he or she + * deems fit, including copying it, compiling it, modifying + * it, and redistributing it, with or without + * modifications. No license under any IBM patents or + * patent applications is to be implied from this copyright + * license. + * + * A user of the module should understand that IBM cannot + * provide technical support for the module and will not be + * responsible for any consequences of use of the program. + * + * Any notices, including this one, are not to be removed + * from the module without the prior written consent of + * IBM. + * + * AUTHOR: Original author: + * G. R. Blair (BOBBLAIR at AUSVM1) + * Internet: bobblair@bobblair.austin.ibm.com + * + * Extensively revised by: + * John Q. Walker II, Ph.D. (JOHHQ at RALVM6) + * Internet: johnq@ralvm6.vnet.ibm.com + * + *****************************************************************************/ + +/****************************************************************************** + * getopt() + * + * The getopt() function is a command line parser. It returns the next + * option character in argv that matches an option character in opstring. + * + * The argv argument points to an array of argc+1 elements containing argc + * pointers to character strings followed by a null pointer. + * + * The opstring argument points to a string of option characters; if an + * option character is followed by a colon, the option is expected to have + * an argument that may or may not be separated from it by white space. + * The external variable optarg is set to point to the start of the option + * argument on return from getopt(). + * + * The getopt() function places in optind the argv index of the next argument + * to be processed. The system initializes the external variable optind to + * 1 before the first call to getopt(). + * + * When all options have been processed (that is, up to the first nonoption + * argument), getopt() returns EOF. The special option "--" may be used to + * delimit the end of the options; EOF will be returned, and "--" will be + * skipped. + * + * The getopt() function returns a question mark (?) when it encounters an + * option character not included in opstring. This error message can be + * disabled by setting opterr to zero. Otherwise, it returns the option + * character that was detected. + * + * If the special option "--" is detected, or all options have been + * processed, EOF is returned. + * + * Options are marked by either a minus sign (-) or a slash (/). + * + * No errors are defined. + *****************************************************************************/ + +#include /* for EOF */ +#include /* for strchr() */ + +/* static (global) variables that are specified as exported by getopt() */ +extern char *optarg; /* pointer to the start of the option argument */ +extern int optind; /* number of the next argv[] to be evaluated */ +extern int opterr; /* non-zero if a question mark should be returned + when a non-valid option character is detected */ + +/* handle possible future character set concerns by putting this in a macro */ +#define _next_char(string) (char)(*(string+1)) + +int getopt(int argc, char *argv[], char *opstring) +{ + static char *pIndexPosition = NULL; /* place inside current argv string */ + char *pArgString = NULL; /* where to start from next */ + char *pOptString; /* the string in our program */ + + + if (pIndexPosition != NULL) { + /* we last left off inside an argv string */ + if (*(++pIndexPosition)) { + /* there is more to come in the most recent argv */ + pArgString = pIndexPosition; + } + } + + if (pArgString == NULL) { + /* we didn't leave off in the middle of an argv string */ + if (optind >= argc) { + /* more command-line arguments than the argument count */ + pIndexPosition = NULL; /* not in the middle of anything */ + return EOF; /* used up all command-line arguments */ + } + + /*--------------------------------------------------------------------- + * If the next argv[] is not an option, there can be no more options. + *-------------------------------------------------------------------*/ + pArgString = argv[optind++]; /* set this to the next argument ptr */ + + if (('/' != *pArgString) && /* doesn't start with a slash or a dash? */ + ('-' != *pArgString)) { + --optind; /* point to current arg once we're done */ + optarg = NULL; /* no argument follows the option */ + pIndexPosition = NULL; /* not in the middle of anything */ + return EOF; /* used up all the command-line flags */ + } + + /* check for special end-of-flags markers */ + if ((strcmp(pArgString, "-") == 0) || + (strcmp(pArgString, "--") == 0)) { + optarg = NULL; /* no argument follows the option */ + pIndexPosition = NULL; /* not in the middle of anything */ + return EOF; /* encountered the special flag */ + } + + pArgString++; /* look past the / or - */ + } + + if (':' == *pArgString) { /* is it a colon? */ + /*--------------------------------------------------------------------- + * Rare case: if opterr is non-zero, return a question mark; + * otherwise, just return the colon we're on. + *-------------------------------------------------------------------*/ + return (opterr ? (int)'?' : (int)':'); + } + else if ((pOptString = strchr(opstring, *pArgString)) == 0) { + /*--------------------------------------------------------------------- + * The letter on the command-line wasn't any good. + *-------------------------------------------------------------------*/ + optarg = NULL; /* no argument follows the option */ + pIndexPosition = NULL; /* not in the middle of anything */ + return (opterr ? (int)'?' : (int)*pArgString); + } + else { + /*--------------------------------------------------------------------- + * The letter on the command-line matches one we expect to see + *-------------------------------------------------------------------*/ + if (':' == _next_char(pOptString)) { /* is the next letter a colon? */ + /* It is a colon. Look for an argument string. */ + if ('\0' != _next_char(pArgString)) { /* argument in this argv? */ + optarg = &pArgString[1]; /* Yes, it is */ + } + else { + /*------------------------------------------------------------- + * The argument string must be in the next argv. + * But, what if there is none (bad input from the user)? + * In that case, return the letter, and optarg as NULL. + *-----------------------------------------------------------*/ + if (optind < argc) + optarg = argv[optind++]; + else { + optarg = NULL; + return (opterr ? (int)'?' : (int)*pArgString); + } + } + pIndexPosition = NULL; /* not in the middle of anything */ + } + else { + /* it's not a colon, so just return the letter */ + optarg = NULL; /* no argument follows the option */ + pIndexPosition = pArgString; /* point to the letter we're on */ + } + return (int)*pArgString; /* return the letter that matched */ + } +} + +#endif //WIN32 diff --git a/cmph/wingetopt.h b/cmph/wingetopt.h new file mode 100644 index 000000000..9596853d9 --- /dev/null +++ b/cmph/wingetopt.h @@ -0,0 +1,25 @@ +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef WIN32 + #include +#else + #ifndef _GETOPT_ + #define _GETOPT_ + + #include /* for EOF */ + #include /* for strchr() */ + + char *optarg = NULL; /* pointer to the start of the option argument */ + int optind = 1; /* number of the next argv[] to be evaluated */ + int opterr = 1; /* non-zero if a question mark should be returned */ + + int getopt(int argc, char *argv[], char *opstring); + #endif //_GETOPT_ +#endif //WIN32 + +#ifdef __cplusplus +} +#endif + From 9aadb1d58304f6b6ff6bf9e2beb86a5915ace842 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 11 Nov 2010 15:03:20 -0500 Subject: [PATCH 414/692] cmph: Modify types to use GLib types The 64 bit #ifdefs is just hackish and broken; e.g. it will fail on ppc64/linux and WIN64. Use the GLib typedefs, which I know are more correct. --- cmph/cmph_types.h | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/cmph/cmph_types.h b/cmph/cmph_types.h index 40f43329a..288323587 100644 --- a/cmph/cmph_types.h +++ b/cmph/cmph_types.h @@ -1,36 +1,19 @@ +#include + #ifndef __CMPH_TYPES_H__ #define __CMPH_TYPES_H__ -typedef char cmph_int8; -typedef unsigned char cmph_uint8; +typedef gint8 cmph_int8; +typedef guint8 cmph_uint8; -typedef short cmph_int16; -typedef unsigned short cmph_uint16; +typedef gint16 cmph_int16; +typedef guint16 cmph_uint16; -typedef int cmph_int32; -typedef unsigned int cmph_uint32; +typedef gint32 cmph_int32; +typedef guint32 cmph_uint32; -#if defined(__ia64) || defined(__x86_64__) - /** \typedef long cmph_int64; - * \brief 64-bit integer for a 64-bit achitecture. - */ - typedef long cmph_int64; - - /** \typedef unsigned long cmph_uint64; - * \brief Unsigned 64-bit integer for a 64-bit achitecture. - */ - typedef unsigned long cmph_uint64; -#else - /** \typedef long long cmph_int64; - * \brief 64-bit integer for a 32-bit achitecture. - */ - typedef long long cmph_int64; - - /** \typedef unsigned long long cmph_uint64; - * \brief Unsigned 64-bit integer for a 32-bit achitecture. - */ - typedef unsigned long long cmph_uint64; -#endif +typedef gint64 cmph_int64; +typedef guint64 cmph_uint64; typedef enum { CMPH_HASH_JENKINS, CMPH_HASH_COUNT } CMPH_HASH; extern const char *cmph_hash_names[]; From f9ba4520815de835c93918be340dd4313c8ea7ed Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 2 Dec 2010 11:34:46 -0500 Subject: [PATCH 415/692] cmph: Squash a lot of gcc -Wall compiler warnings * Functions taking no parameters need to explicitly say (void). * Mark some functions as static that are * Comment out an unused function in bdz.c * Change loop indicies "i" to be unsigned if our limit is unsigned --- cmph/bdz.c | 8 +++++--- cmph/bdz.h | 2 +- cmph/bdz_ph.c | 4 ++-- cmph/bdz_ph.h | 2 +- cmph/bmz.c | 2 +- cmph/bmz.h | 2 +- cmph/bmz8.c | 2 +- cmph/bmz8.h | 2 +- cmph/brz.c | 2 +- cmph/brz.h | 2 +- cmph/buffer_entry.c | 2 +- cmph/chd_ph.c | 4 ++-- cmph/chd_ph.h | 2 +- cmph/chm.c | 2 +- cmph/chm.h | 2 +- cmph/fch.h | 2 +- cmph/fch_buckets.c | 2 +- cmph/jenkins_hash.c | 4 ++-- cmph/jenkins_hash.h | 2 +- cmph/vstack.c | 2 +- cmph/vstack.h | 2 +- 21 files changed, 28 insertions(+), 26 deletions(-) diff --git a/cmph/bdz.c b/cmph/bdz.c index f422c8f91..a57f70f84 100755 --- a/cmph/bdz.c +++ b/cmph/bdz.c @@ -107,7 +107,7 @@ static void bdz_add_edge(bdz_graph3_t * graph3, cmph_uint32 v0, cmph_uint32 v1, static void bdz_dump_graph(bdz_graph3_t* graph3, cmph_uint32 nedges, cmph_uint32 nvertices) { - int i; + cmph_uint32 i; for(i=0;iedges[i].vertices[0], graph3->edges[i].vertices[1],graph3->edges[i].vertices[2]); @@ -216,7 +216,7 @@ static void assigning(bdz_config_data_t *bdz, bdz_graph3_t* graph3, bdz_queue_t static void ranking(bdz_config_data_t *bdz); static cmph_uint32 rank(cmph_uint32 b, cmph_uint32 * ranktable, cmph_uint8 * g, cmph_uint32 vertex); -bdz_config_data_t *bdz_config_new() +bdz_config_data_t *bdz_config_new(void) { bdz_config_data_t *bdz; bdz = (bdz_config_data_t *)malloc(sizeof(bdz_config_data_t)); @@ -560,7 +560,8 @@ void bdz_load(FILE *f, cmph_t *mphf) } -cmph_uint32 bdz_search_ph(cmph_t *mphf, const char *key, cmph_uint32 keylen) +/* +static cmph_uint32 bdz_search_ph(cmph_t *mphf, const char *key, cmph_uint32 keylen) { bdz_data_t *bdz = mphf->data; cmph_uint32 hl[3]; @@ -572,6 +573,7 @@ cmph_uint32 bdz_search_ph(cmph_t *mphf, const char *key, cmph_uint32 keylen) vertex = hl[(GETVALUE(bdz->g, hl[0]) + GETVALUE(bdz->g, hl[1]) + GETVALUE(bdz->g, hl[2])) % 3]; return vertex; } +*/ static inline cmph_uint32 rank(cmph_uint32 b, cmph_uint32 * ranktable, cmph_uint8 * g, cmph_uint32 vertex) { diff --git a/cmph/bdz.h b/cmph/bdz.h index f2b7b89c2..7116933b4 100755 --- a/cmph/bdz.h +++ b/cmph/bdz.h @@ -6,7 +6,7 @@ typedef struct __bdz_data_t bdz_data_t; typedef struct __bdz_config_data_t bdz_config_data_t; -bdz_config_data_t *bdz_config_new(); +bdz_config_data_t *bdz_config_new(void); void bdz_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); void bdz_config_destroy(cmph_config_t *mph); void bdz_config_set_b(cmph_config_t *mph, cmph_uint32 b); diff --git a/cmph/bdz_ph.c b/cmph/bdz_ph.c index 49cf56463..16257c0f4 100755 --- a/cmph/bdz_ph.c +++ b/cmph/bdz_ph.c @@ -94,7 +94,7 @@ static void bdz_ph_add_edge(bdz_ph_graph3_t * graph3, cmph_uint32 v0, cmph_uint3 static void bdz_ph_dump_graph(bdz_ph_graph3_t* graph3, cmph_uint32 nedges, cmph_uint32 nvertices) { - int i; + cmph_uint32 i; for(i=0;iedges[i].vertices[0], graph3->edges[i].vertices[1],graph3->edges[i].vertices[2]); @@ -202,7 +202,7 @@ static int bdz_ph_mapping(cmph_config_t *mph, bdz_ph_graph3_t* graph3, bdz_ph_qu static void assigning(bdz_ph_config_data_t *bdz_ph, bdz_ph_graph3_t* graph3, bdz_ph_queue_t queue); static void bdz_ph_optimization(bdz_ph_config_data_t *bdz_ph); -bdz_ph_config_data_t *bdz_ph_config_new() +bdz_ph_config_data_t *bdz_ph_config_new(void) { bdz_ph_config_data_t *bdz_ph; bdz_ph = (bdz_ph_config_data_t *)malloc(sizeof(bdz_ph_config_data_t)); diff --git a/cmph/bdz_ph.h b/cmph/bdz_ph.h index 73cce2ed1..67b1facbe 100755 --- a/cmph/bdz_ph.h +++ b/cmph/bdz_ph.h @@ -6,7 +6,7 @@ typedef struct __bdz_ph_data_t bdz_ph_data_t; typedef struct __bdz_ph_config_data_t bdz_ph_config_data_t; -bdz_ph_config_data_t *bdz_ph_config_new(); +bdz_ph_config_data_t *bdz_ph_config_new(void); void bdz_ph_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); void bdz_ph_config_destroy(cmph_config_t *mph); cmph_t *bdz_ph_new(cmph_config_t *mph, double c); diff --git a/cmph/bmz.c b/cmph/bmz.c index 51798a189..3eabfb7f2 100644 --- a/cmph/bmz.c +++ b/cmph/bmz.c @@ -20,7 +20,7 @@ static cmph_uint8 bmz_traverse_critical_nodes(bmz_config_data_t *bmz, cmph_uint3 static cmph_uint8 bmz_traverse_critical_nodes_heuristic(bmz_config_data_t *bmz, cmph_uint32 v, cmph_uint32 * biggest_g_value, cmph_uint32 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited); static void bmz_traverse_non_critical_nodes(bmz_config_data_t *bmz, cmph_uint8 * used_edges, cmph_uint8 * visited); -bmz_config_data_t *bmz_config_new() +bmz_config_data_t *bmz_config_new(void) { bmz_config_data_t *bmz = NULL; bmz = (bmz_config_data_t *)malloc(sizeof(bmz_config_data_t)); diff --git a/cmph/bmz.h b/cmph/bmz.h index ee5f61dda..9821aa88c 100644 --- a/cmph/bmz.h +++ b/cmph/bmz.h @@ -6,7 +6,7 @@ typedef struct __bmz_data_t bmz_data_t; typedef struct __bmz_config_data_t bmz_config_data_t; -bmz_config_data_t *bmz_config_new(); +bmz_config_data_t *bmz_config_new(void); void bmz_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); void bmz_config_destroy(cmph_config_t *mph); cmph_t *bmz_new(cmph_config_t *mph, double c); diff --git a/cmph/bmz8.c b/cmph/bmz8.c index 203f4fc19..4db4dfce8 100644 --- a/cmph/bmz8.c +++ b/cmph/bmz8.c @@ -19,7 +19,7 @@ static cmph_uint8 bmz8_traverse_critical_nodes(bmz8_config_data_t *bmz8, cmph_ui static cmph_uint8 bmz8_traverse_critical_nodes_heuristic(bmz8_config_data_t *bmz8, cmph_uint32 v, cmph_uint8 * biggest_g_value, cmph_uint8 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited); static void bmz8_traverse_non_critical_nodes(bmz8_config_data_t *bmz8, cmph_uint8 * used_edges, cmph_uint8 * visited); -bmz8_config_data_t *bmz8_config_new() +bmz8_config_data_t *bmz8_config_new(void) { bmz8_config_data_t *bmz8; bmz8 = (bmz8_config_data_t *)malloc(sizeof(bmz8_config_data_t)); diff --git a/cmph/bmz8.h b/cmph/bmz8.h index 5456759ef..99f7e30d6 100644 --- a/cmph/bmz8.h +++ b/cmph/bmz8.h @@ -6,7 +6,7 @@ typedef struct __bmz8_data_t bmz8_data_t; typedef struct __bmz8_config_data_t bmz8_config_data_t; -bmz8_config_data_t *bmz8_config_new(); +bmz8_config_data_t *bmz8_config_new(void); void bmz8_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); void bmz8_config_destroy(cmph_config_t *mph); cmph_t *bmz8_new(cmph_config_t *mph, double c); diff --git a/cmph/brz.c b/cmph/brz.c index eb89ac06c..f9c48ef7c 100755 --- a/cmph/brz.c +++ b/cmph/brz.c @@ -24,7 +24,7 @@ static cmph_uint32 brz_min_index(cmph_uint32 * vector, cmph_uint32 n); static void brz_destroy_keys_vd(cmph_uint8 ** keys_vd, cmph_uint32 nkeys); static char * brz_copy_partial_fch_mphf(brz_config_data_t *brz, fch_data_t * fchf, cmph_uint32 index, cmph_uint32 *buflen); static char * brz_copy_partial_bmz8_mphf(brz_config_data_t *brz, bmz8_data_t * bmzf, cmph_uint32 index, cmph_uint32 *buflen); -brz_config_data_t *brz_config_new() +brz_config_data_t *brz_config_new(void) { brz_config_data_t *brz = NULL; brz = (brz_config_data_t *)malloc(sizeof(brz_config_data_t)); diff --git a/cmph/brz.h b/cmph/brz.h index ac07ed762..648f174b5 100644 --- a/cmph/brz.h +++ b/cmph/brz.h @@ -6,7 +6,7 @@ typedef struct __brz_data_t brz_data_t; typedef struct __brz_config_data_t brz_config_data_t; -brz_config_data_t *brz_config_new(); +brz_config_data_t *brz_config_new(void); void brz_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); void brz_config_set_tmp_dir(cmph_config_t *mph, cmph_uint8 *tmp_dir); void brz_config_set_mphf_fd(cmph_config_t *mph, FILE *mphf_fd); diff --git a/cmph/buffer_entry.c b/cmph/buffer_entry.c index 7f82aae13..5dcc4d577 100644 --- a/cmph/buffer_entry.c +++ b/cmph/buffer_entry.c @@ -43,7 +43,7 @@ cmph_uint32 buffer_entry_get_capacity(buffer_entry_t * buffer_entry) return buffer_entry->capacity; } -void buffer_entry_load(buffer_entry_t * buffer_entry) +static void buffer_entry_load(buffer_entry_t * buffer_entry) { free(buffer_entry->buff); buffer_entry->buff = (cmph_uint8 *)calloc((size_t)buffer_entry->capacity, sizeof(cmph_uint8)); diff --git a/cmph/chd_ph.c b/cmph/chd_ph.c index b34415b93..71f83fbd3 100644 --- a/cmph/chd_ph.c +++ b/cmph/chd_ph.c @@ -77,7 +77,7 @@ void chd_ph_bucket_clean(chd_ph_bucket_t * buckets, cmph_uint32 nbuckets) for(i = 0; i < nbuckets; i++) buckets[i].size = 0; } -cmph_uint8 chd_ph_bucket_insert(chd_ph_bucket_t * buckets,chd_ph_map_item_t * map_items, chd_ph_item_t * items, +static cmph_uint8 chd_ph_bucket_insert(chd_ph_bucket_t * buckets,chd_ph_map_item_t * map_items, chd_ph_item_t * items, cmph_uint32 nbuckets,cmph_uint32 item_idx) { register cmph_uint32 i = 0; @@ -141,7 +141,7 @@ static inline double chd_ph_get_entropy(cmph_uint32 * disp_table, cmph_uint32 n, return entropy; }; -chd_ph_config_data_t *chd_ph_config_new() +chd_ph_config_data_t *chd_ph_config_new(void) { chd_ph_config_data_t *chd_ph; chd_ph = (chd_ph_config_data_t *)malloc(sizeof(chd_ph_config_data_t)); diff --git a/cmph/chd_ph.h b/cmph/chd_ph.h index d2bdb0286..03e4087c9 100644 --- a/cmph/chd_ph.h +++ b/cmph/chd_ph.h @@ -7,7 +7,7 @@ typedef struct __chd_ph_data_t chd_ph_data_t; typedef struct __chd_ph_config_data_t chd_ph_config_data_t; /* Config API */ -chd_ph_config_data_t *chd_ph_config_new(); +chd_ph_config_data_t *chd_ph_config_new(void); void chd_ph_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); /** \fn void chd_ph_config_set_keys_per_bin(cmph_config_t *mph, cmph_uint32 keys_per_bin); diff --git a/cmph/chm.c b/cmph/chm.c index e03cca80e..9cdbf41bc 100644 --- a/cmph/chm.c +++ b/cmph/chm.c @@ -17,7 +17,7 @@ static int chm_gen_edges(cmph_config_t *mph); static void chm_traverse(chm_config_data_t *chm, cmph_uint8 *visited, cmph_uint32 v); -chm_config_data_t *chm_config_new() +chm_config_data_t *chm_config_new(void) { chm_config_data_t *chm = NULL; chm = (chm_config_data_t *)malloc(sizeof(chm_config_data_t)); diff --git a/cmph/chm.h b/cmph/chm.h index 341be29ea..392d23aaf 100644 --- a/cmph/chm.h +++ b/cmph/chm.h @@ -6,7 +6,7 @@ typedef struct __chm_data_t chm_data_t; typedef struct __chm_config_data_t chm_config_data_t; -chm_config_data_t *chm_config_new(); +chm_config_data_t *chm_config_new(void); void chm_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); void chm_config_destroy(cmph_config_t *mph); cmph_t *chm_new(cmph_config_t *mph, double c); diff --git a/cmph/fch.h b/cmph/fch.h index ec4f0f5b0..9d13a1c1b 100644 --- a/cmph/fch.h +++ b/cmph/fch.h @@ -12,7 +12,7 @@ double fch_calc_p1(cmph_uint32 m); double fch_calc_p2(cmph_uint32 b); cmph_uint32 mixh10h11h12(cmph_uint32 b, double p1, double p2, cmph_uint32 initial_index); -fch_config_data_t *fch_config_new(); +fch_config_data_t *fch_config_new(void); void fch_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs); void fch_config_destroy(cmph_config_t *mph); cmph_t *fch_new(cmph_config_t *mph, double c); diff --git a/cmph/fch_buckets.c b/cmph/fch_buckets.c index 24b98e672..a588f147e 100644 --- a/cmph/fch_buckets.c +++ b/cmph/fch_buckets.c @@ -172,7 +172,7 @@ cmph_uint32 fch_buckets_get_nbuckets(fch_buckets_t * buckets) cmph_uint32 * fch_buckets_get_indexes_sorted_by_size(fch_buckets_t * buckets) { - int i = 0; + cmph_uint32 i = 0; cmph_uint32 sum = 0, value; cmph_uint32 *nbuckets_size = (cmph_uint32 *) calloc((size_t)buckets->max_size + 1, sizeof(cmph_uint32)); cmph_uint32 * sorted_indexes = (cmph_uint32 *) calloc((size_t)buckets->nbuckets, sizeof(cmph_uint32)); diff --git a/cmph/jenkins_hash.c b/cmph/jenkins_hash.c index f5233a5a5..65cdff959 100644 --- a/cmph/jenkins_hash.c +++ b/cmph/jenkins_hash.c @@ -97,7 +97,7 @@ void jenkins_state_destroy(jenkins_state_t *state) } -inline void __jenkins_hash_vector(cmph_uint32 seed, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes) +static inline void __jenkins_hash_vector(cmph_uint32 seed, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes) { register cmph_uint32 len, length; @@ -266,7 +266,7 @@ void jenkins_state_pack(jenkins_state_t *state, void *jenkins_packed) * \brief Return the amount of space needed to pack a jenkins function. * \return the size of the packed function or zero for failures */ -cmph_uint32 jenkins_state_packed_size() +cmph_uint32 jenkins_state_packed_size(void) { return sizeof(cmph_uint32); } diff --git a/cmph/jenkins_hash.h b/cmph/jenkins_hash.h index 8e8b9173e..39626e204 100644 --- a/cmph/jenkins_hash.h +++ b/cmph/jenkins_hash.h @@ -43,7 +43,7 @@ void jenkins_state_pack(jenkins_state_t *state, void *jenkins_packed); * \brief Return the amount of space needed to pack a jenkins function. * \return the size of the packed function or zero for failures */ -cmph_uint32 jenkins_state_packed_size(); +cmph_uint32 jenkins_state_packed_size(void); /** \fn cmph_uint32 jenkins_hash_packed(void *jenkins_packed, const char *k, cmph_uint32 keylen); diff --git a/cmph/vstack.c b/cmph/vstack.c index 24555cd6e..96f5380ab 100644 --- a/cmph/vstack.c +++ b/cmph/vstack.c @@ -13,7 +13,7 @@ struct __vstack_t cmph_uint32 capacity; }; -vstack_t *vstack_new() +vstack_t *vstack_new(void) { vstack_t *stack = (vstack_t *)malloc(sizeof(vstack_t)); assert(stack); diff --git a/cmph/vstack.h b/cmph/vstack.h index 1cefaaffb..fecc7d55d 100644 --- a/cmph/vstack.h +++ b/cmph/vstack.h @@ -4,7 +4,7 @@ #include "cmph_types.h" typedef struct __vstack_t vstack_t; -vstack_t *vstack_new(); +vstack_t *vstack_new(void); void vstack_destroy(vstack_t *stack); void vstack_push(vstack_t *stack, cmph_uint32 val); From abb1b39ce9e1e4d6e02753cc4bdce2bf490217f4 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 11 Nov 2010 15:34:11 -0500 Subject: [PATCH 416/692] cmph-bdz-test: New test Add a basic test of CMPH (without any layers on top). --- cmph-bdz-test.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 cmph-bdz-test.c diff --git a/cmph-bdz-test.c b/cmph-bdz-test.c new file mode 100644 index 000000000..fdff9d179 --- /dev/null +++ b/cmph-bdz-test.c @@ -0,0 +1,141 @@ +/* GObject introspection: Test cmph hashing + * + * Copyright (C) 2010 Red Hat, Inc. + * + * 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 "cmph.h" + +static cmph_t * +build (void) +{ + cmph_config_t *config; + cmph_io_adapter_t *io; + char **strings; + cmph_t *c; + guint32 size; + + strings = g_strsplit ("foo,bar,baz", ",", -1); + + io = cmph_io_vector_adapter (strings, g_strv_length (strings)); + config = cmph_config_new (io); + cmph_config_set_algo (config, CMPH_BDZ); + + c = cmph_new (config); + size = cmph_size (c); + g_assert (size == g_strv_length (strings)); + + return c; +} + +static void +assert_hashes_unique (guint n_hashes, + guint32* hashes) +{ + guint i; + + for (i = 0; i < n_hashes; i++) + { + guint j = 0; + for (j = 0; j < n_hashes; j++) + { + if (j != i) + g_assert (hashes[i] != hashes[j]); + } + } +} + +static void +test_search (void) +{ + cmph_t *c = build(); + guint i; + guint32 hash; + guint32 hashes[3]; + guint32 size; + + size = cmph_size (c); + + i = 0; + hash = cmph_search (c, "foo", 3); + g_assert (hash >= 0 && hash < size); + hashes[i++] = hash; + + hash = cmph_search (c, "bar", 3); + g_assert (hash >= 0 && hash < size); + hashes[i++] = hash; + + hash = cmph_search (c, "baz", 3); + g_assert (hash >= 0 && hash < size); + hashes[i++] = hash; + + assert_hashes_unique (G_N_ELEMENTS (hashes), &hashes[0]); +} + +static void +test_search_packed (void) +{ + cmph_t *c = build(); + guint32 bufsize; + guint i; + guint32 hash; + guint32 hashes[3]; + guint32 size; + guint8 *buf; + + bufsize = cmph_packed_size (c); + buf = g_malloc (bufsize); + cmph_pack (c, buf); + + size = cmph_size (c); + + cmph_destroy (c); + c = NULL; + + i = 0; + hash = cmph_search_packed (buf, "foo", 3); + g_assert (hash >= 0 && hash < size); + hashes[i++] = hash; + + hash = cmph_search_packed (buf, "bar", 3); + g_assert (hash >= 0 && hash < size); + hashes[i++] = hash; + + hash = cmph_search_packed (buf, "baz", 3); + g_assert (hash >= 0 && hash < size); + hashes[i++] = hash; + + assert_hashes_unique (G_N_ELEMENTS (hashes), &hashes[0]); +} + +int +main(int argc, char **argv) +{ + gint ret; + + g_type_init (); + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/cmph-bdz/search", test_search); + g_test_add_func ("/cmph-bdz/search-packed", test_search_packed); + + ret = g_test_run (); + + return ret; +} + From 409c40f663b0be8fe561d7c9f3624698edae6d65 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 25 Oct 2010 07:56:05 -0400 Subject: [PATCH 417/692] Add internal hashing API designed for the typelib In multiple places in the typelib, but most importantly the directory, we need some fast indexing. Perfect hashing, as implemented by CMPH (previous commit), is an exact fit for the problem domain. Add an API built on top of CMPH which maps strings->guint16 (we just need a guint16 for the typelib index). https://bugzilla.gnome.org/show_bug.cgi?id=554943 --- gitypelib-internal.h | 17 ++++ gthash-test.c | 65 ++++++++++++++ gthash.c | 210 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 292 insertions(+) create mode 100644 gthash-test.c create mode 100644 gthash.c diff --git a/gitypelib-internal.h b/gitypelib-internal.h index de2f131b6..227d6da29 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -1145,6 +1145,23 @@ gboolean g_typelib_validate (GITypelib *typelib, AttributeBlob *_attribute_blob_find_first (GIBaseInfo *info, guint32 blob_offset); +typedef struct _GITypelibHashBuilder GITypelibHashBuilder; + +GITypelibHashBuilder * _gi_typelib_hash_builder_new (void); + +void _gi_typelib_hash_builder_add_string (GITypelibHashBuilder *builder, const char *str, guint16 value); + +gboolean _gi_typelib_hash_builder_prepare (GITypelibHashBuilder *builder); + +guint32 _gi_typelib_hash_builder_get_buffer_size (GITypelibHashBuilder *builder); + +void _gi_typelib_hash_builder_pack (GITypelibHashBuilder *builder, guint8* mem, guint32 size); + +void _gi_typelib_hash_builder_destroy (GITypelibHashBuilder *builder); + +guint16 _gi_typelib_hash_search (guint8* memory, const char *str); + + G_END_DECLS #endif /* __G_TYPELIB_H__ */ diff --git a/gthash-test.c b/gthash-test.c new file mode 100644 index 000000000..a2e3cf82b --- /dev/null +++ b/gthash-test.c @@ -0,0 +1,65 @@ +/* GObject introspection: Test typelib hashing + * + * Copyright (C) 2010 Red Hat, Inc. + * + * 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 "gitypelib-internal.h" + +static void +test_build_retrieve (void) +{ + GITypelibHashBuilder *builder; + guint32 bufsize; + guint8* buf; + + builder = _gi_typelib_hash_builder_new (); + + _gi_typelib_hash_builder_add_string (builder, "Action", 0); + _gi_typelib_hash_builder_add_string (builder, "ZLibDecompressor", 42); + _gi_typelib_hash_builder_add_string (builder, "VolumeMonitor", 9); + _gi_typelib_hash_builder_add_string (builder, "FileMonitorFlags", 31); + + if (!_gi_typelib_hash_builder_prepare (builder)) + g_assert_not_reached (); + + bufsize = _gi_typelib_hash_builder_get_buffer_size (builder); + + buf = g_malloc (bufsize); + + _gi_typelib_hash_builder_pack (builder, buf, bufsize); + + _gi_typelib_hash_builder_destroy (builder); + + g_assert (_gi_typelib_hash_search (buf, "Action") == 0); + g_assert (_gi_typelib_hash_search (buf, "ZLibDecompressor") == 42); + g_assert (_gi_typelib_hash_search (buf, "VolumeMonitor") == 9); + g_assert (_gi_typelib_hash_search (buf, "FileMonitorFlags") == 31); +} + +int +main(int argc, char **argv) +{ + g_type_init (); + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/gthash/build-retrieve", test_build_retrieve); + + return g_test_run (); +} + diff --git a/gthash.c b/gthash.c new file mode 100644 index 000000000..5042ebe3e --- /dev/null +++ b/gthash.c @@ -0,0 +1,210 @@ +/* GObject introspection: Typelib hashing + * + * Copyright (C) 2010 Red Hat, Inc. + * + * 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 "cmph/cmph.h" +#include "gitypelib-internal.h" + +#define ALIGN_VALUE(this, boundary) \ + (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) + +/** + * String hashing in the typelib. We have a set of static (fixed) strings, + * and given one, we need to find its index number. This problem is perfect + * hashing: http://en.wikipedia.org/wiki/Perfect_hashing + * + * I chose CMPH (http://cmph.sourceforge.net/) as it seemed high + * quality, well documented, and easy to embed. + * + * CMPH provides a number of algorithms; I chose BDZ, because while CHD + * appears to be the "best", the simplicitly of BDZ appealed, and really, + * we're only talking about thousands of strings here, not millions, so + * a few microseconds is no big deal. + * + * In memory, the format is: + * INT32 mph_size + * MPH (mph_size bytes) + * (padding for alignment to uint32 if necessary) + * INDEX (array of guint16) + * + * Because BDZ is not order preserving, we need a lookaside table which + * maps the hash value into the directory index. + */ + +struct _GITypelibHashBuilder { + gboolean prepared; + gboolean buildable; + cmph_t *c; + GHashTable *strings; + guint32 dirmap_offset; + guint32 packed_size; +}; + +GITypelibHashBuilder * +_gi_typelib_hash_builder_new (void) +{ + GITypelibHashBuilder *builder = g_slice_new0 (GITypelibHashBuilder); + builder->c = NULL; + builder->strings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + return builder; +} + +void +_gi_typelib_hash_builder_add_string (GITypelibHashBuilder *builder, + const char *str, + guint16 value) +{ + g_return_if_fail (builder->c == NULL); + g_hash_table_insert (builder->strings, g_strdup (str), GUINT_TO_POINTER ((guint) value)); +} + +gboolean +_gi_typelib_hash_builder_prepare (GITypelibHashBuilder *builder) +{ + char **strs; + GHashTableIter hashiter; + gpointer key, value; + cmph_io_adapter_t *io; + cmph_config_t *config; + guint32 num_elts; + guint32 offset; + guint i; + + if (builder->prepared) + return builder->buildable; + g_assert (builder->c == NULL); + + num_elts = g_hash_table_size (builder->strings); + g_assert (num_elts <= 65536); + + strs = (char**) g_new (char *, num_elts + 1); + + i = 0; + g_hash_table_iter_init (&hashiter, builder->strings); + while (g_hash_table_iter_next (&hashiter, &key, &value)) + { + const char *str = key; + + strs[i++] = g_strdup (str); + } + strs[i++] = NULL; + + io = cmph_io_vector_adapter (strs, num_elts); + config = cmph_config_new (io); + cmph_config_set_algo (config, CMPH_BDZ); + + builder->c = cmph_new (config); + builder->prepared = TRUE; + if (!builder->c) + { + builder->buildable = FALSE; + goto out; + } + builder->buildable = TRUE; + g_assert (cmph_size (builder->c) == num_elts); + + /* Pack a size counter at front */ + offset = sizeof(guint32) + cmph_packed_size (builder->c); + builder->dirmap_offset = ALIGN_VALUE (offset, 4); + builder->packed_size = builder->dirmap_offset + (num_elts * sizeof(guint16)); + out: + return builder->buildable; +} + +guint32 +_gi_typelib_hash_builder_get_buffer_size (GITypelibHashBuilder *builder) +{ + g_return_val_if_fail (builder != NULL, 0); + g_return_val_if_fail (builder->prepared, 0); + g_return_val_if_fail (builder->buildable, 0 ); + + return builder->packed_size; +} + +void +_gi_typelib_hash_builder_pack (GITypelibHashBuilder *builder, guint8* mem, guint32 len) +{ + guint16 *table; + GHashTableIter hashiter; + gpointer key, value; + guint32 num_elts; + guint8 *packed_mem; + + g_return_if_fail (builder != NULL); + g_return_if_fail (builder->prepared); + g_return_if_fail (builder->buildable); + + g_assert (len >= builder->packed_size); + g_assert ((((unsigned long)mem) & 0x3) == 0); + + *((guint32*) mem) = builder->dirmap_offset; + packed_mem = (guint8*)(mem + sizeof(guint32)); + cmph_pack (builder->c, packed_mem); + + table = (guint16*) (mem + builder->dirmap_offset); + + num_elts = g_hash_table_size (builder->strings); + g_hash_table_iter_init (&hashiter, builder->strings); + while (g_hash_table_iter_next (&hashiter, &key, &value)) + { + const char *str = key; + guint16 strval = (guint16)GPOINTER_TO_UINT(value); + guint32 hashv; + + hashv = cmph_search_packed (packed_mem, str, strlen (str)); + g_assert (hashv >= 0 && hashv < num_elts); + table[hashv] = strval; + } +} + +void +_gi_typelib_hash_builder_destroy (GITypelibHashBuilder *builder) +{ + if (builder->c) + { + cmph_destroy (builder->c); + builder->c = NULL; + } + g_hash_table_destroy (builder->strings); + g_slice_free (GITypelibHashBuilder, builder); +} + +guint16 +_gi_typelib_hash_search (guint8* memory, const char *str) +{ + guint32 *mph; + guint16 *table; + guint32 dirmap_offset; + guint32 offset; + + g_assert ((((unsigned long)memory) & 0x3) == 0); + mph = ((guint32*)memory)+1; + + offset = cmph_search_packed (mph, str, strlen (str)); + + dirmap_offset = *((guint32*)memory); + table = (guint16*) (memory + dirmap_offset); + + return table[offset]; +} + From a1d7beda01d2f9a8211aecfc9f0f6b1b4b0d2182 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 25 Oct 2010 13:33:01 -0400 Subject: [PATCH 418/692] Add directory index section Use the internal perfect hashing API to add an index to the directory. To support this, add the notion of additional "sections" to the typelib. A section index is inserted between the header and the directory. https://bugzilla.gnome.org/show_bug.cgi?id=554943 --- girmodule.c | 95 +++++++++++++++++++++++++++++++++++++++++++- gitypelib-internal.h | 29 +++++++++++++- gitypelib.c | 56 +++++++++++++++++++++----- 3 files changed, 166 insertions(+), 14 deletions(-) diff --git a/girmodule.c b/girmodule.c index d15b940f6..49daaa620 100644 --- a/girmodule.c +++ b/girmodule.c @@ -23,11 +23,13 @@ #include #include "girmodule.h" +#include "gitypelib-internal.h" #include "girnode.h" #define ALIGN_VALUE(this, boundary) \ (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) +#define NUM_SECTIONS 2 GIrModule * _g_ir_module_new (const gchar *name, @@ -220,6 +222,73 @@ node_cmp_offset_func (gconstpointer a, return na->offset - nb->offset; } +static void +alloc_section (guint8 *data, SectionType section_id, guint32 offset) +{ + int i; + Header *header = (Header*)data; + Section *section_data = (Section*)&data[header->sections]; + + g_assert (section_id != GI_SECTION_END); + + for (i = 0; i < NUM_SECTIONS; i++) + { + if (section_data->id == GI_SECTION_END) + { + section_data->id = section_id; + section_data->offset = offset; + return; + } + section_data++; + } + g_assert_not_reached (); +} + +static guint8* +add_directory_index_section (guint8 *data, GIrModule *module, guint32 *offset2) +{ + DirEntry *entry; + Header *header = (Header*)data; + GITypelibHashBuilder *dirindex_builder; + guint i, n_interfaces; + guint16 required_size; + guint32 new_offset; + + dirindex_builder = _gi_typelib_hash_builder_new (); + + n_interfaces = ((Header *)data)->n_local_entries; + + for (i = 0; i < n_interfaces; i++) + { + entry = (DirEntry *)&data[header->directory + (i * header->entry_blob_size)]; + const char *str = (const char *) (&data[entry->name]); + _gi_typelib_hash_builder_add_string (dirindex_builder, str, i); + } + + if (!_gi_typelib_hash_builder_prepare (dirindex_builder)) + { + /* This happens if CMPH couldn't create a perfect hash. So + * we just punt and leave no directory index section. + */ + _gi_typelib_hash_builder_destroy (dirindex_builder); + return data; + } + + alloc_section (data, GI_SECTION_DIRECTORY_INDEX, *offset2); + + required_size = _gi_typelib_hash_builder_get_buffer_size (dirindex_builder); + + new_offset = *offset2 + ALIGN_VALUE (required_size, 4); + + data = g_realloc (data, new_offset); + + _gi_typelib_hash_builder_pack (dirindex_builder, ((guint8*)data) + *offset2, required_size); + + *offset2 = new_offset; + + _gi_typelib_hash_builder_destroy (dirindex_builder); + return data; +} GITypelib * _g_ir_module_build_typelib (GIrModule *module) @@ -241,6 +310,7 @@ _g_ir_module_build_typelib (GIrModule *module) GList *nodes_with_attributes; char *dependencies; guchar *data; + Section *section; header_size = ALIGN_VALUE (sizeof (Header), 4); n_local_entries = g_list_length (module->entries); @@ -301,6 +371,8 @@ _g_ir_module_build_typelib (GIrModule *module) if (module->c_prefix != NULL) size += ALIGN_VALUE (strlen (module->c_prefix) + 1, 4); + size += sizeof (Section) * NUM_SECTIONS; + g_message ("allocating %d bytes (%d header, %d directory, %d entries)\n", size, header_size, dir_size, size - header_size - dir_size); @@ -333,7 +405,6 @@ _g_ir_module_build_typelib (GIrModule *module) header->c_prefix = _g_ir_write_string (module->c_prefix, strings, data, &header_size); else header->c_prefix = 0; - header->directory = ALIGN_VALUE (header_size, 4); header->entry_blob_size = sizeof (DirEntry); header->function_blob_size = sizeof (FunctionBlob); header->callback_blob_size = sizeof (CallbackBlob); @@ -353,10 +424,26 @@ _g_ir_module_build_typelib (GIrModule *module) header->interface_blob_size = sizeof (InterfaceBlob); header->union_blob_size = sizeof (UnionBlob); + offset2 = ALIGN_VALUE (header_size, 4); + header->sections = offset2; + + /* Initialize all the sections to _END/0; we fill them in later using + * alloc_section(). (Right now there's just the directory index + * though, note) + */ + for (i = 0; i < NUM_SECTIONS; i++) + { + section = (Section*) &data[offset2]; + section->id = GI_SECTION_END; + section->offset = 0; + offset2 += sizeof(Section); + } + header->directory = offset2; + /* fill in directory and content */ entry = (DirEntry *)&data[header->directory]; - offset2 = header->directory + dir_size; + offset2 += dir_size; for (e = module->entries, i = 0; e; e = e->next, i++) { @@ -452,6 +539,10 @@ _g_ir_module_build_typelib (GIrModule *module) data = g_realloc (data, offset2); header = (Header*) data; + + data = add_directory_index_section (data, module, &offset2); + header = (Header *)data; + length = header->size = offset2; typelib = g_typelib_new_from_memory (data, length, &error); if (!typelib) diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 227d6da29..e8f5c0250 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -52,7 +52,7 @@ G_BEGIN_DECLS * * The typelib has the following general format. * - * typelib ::= header, directory, blobs, attributes, attributedata + * typelib ::= header, section-index, directory, blobs, attributes, attributedata * * directory ::= list of entries * @@ -233,6 +233,7 @@ typedef enum { * write parser which continue to work if the format is extended by * adding new fields before the first flexible array member in * variable-size blobs. + * @sections: Offset of section blob array * * The header structure appears exactly once at the beginning of a typelib. It is a * collection of meta-information, such as the number of entries and dependencies. @@ -278,10 +279,34 @@ typedef struct { guint16 interface_blob_size; guint16 union_blob_size; + guint32 sections; + /* */ - guint16 padding[7]; + guint16 padding[5]; } Header; +typedef enum { + GI_SECTION_END = 0, + GI_SECTION_DIRECTORY_INDEX = 1 +} SectionType; + +/** + * Section: + * @id: A #SectionType + * @offset: Integer offset for this section + * + * A section is a blob of data that's (at least theoretically) optional, + * and may or may not be present in the typelib. Presently, just used + * for the directory index. This allows a form of dynamic extensibility + * with different tradeoffs from the format minor version. + * + */ +typedef struct { + guint32 id; + guint32 offset; +} Section; + + /** * DirEntry: * @blob_type: A #GTypelibBlobType diff --git a/gitypelib.c b/gitypelib.c index a0b74d3d6..90f2c1bbb 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -139,25 +139,61 @@ g_typelib_get_dir_entry (GITypelib *typelib, return (DirEntry *)&typelib->data[header->directory + (index - 1) * header->entry_blob_size]; } -DirEntry * -g_typelib_get_dir_entry_by_name (GITypelib *typelib, - const char *name) +static Section * +get_section_by_id (GITypelib *typelib, + SectionType section_type) { Header *header = (Header *)typelib->data; - guint n_entries = header->n_local_entries; - DirEntry *entry; - guint i; + Section *section; - for (i = 1; i <= n_entries; i++) + if (header->sections == 0) + return NULL; + + for (section = (Section*)&typelib->data[header->sections]; + section->id != GI_SECTION_END; + section++) { - const char *entry_name; + if (section->id == section_type) + return section; + } + return NULL; +} - entry = g_typelib_get_dir_entry (typelib, i); +DirEntry * +g_typelib_get_dir_entry_by_name (GITypelib *typelib, + const char *name) +{ + Section *dirindex; + gint i; + const char *entry_name; + DirEntry *entry; + + dirindex = get_section_by_id (typelib, GI_SECTION_DIRECTORY_INDEX); + + if (dirindex == NULL) + { + gint n_entries = ((Header *)typelib->data)->n_local_entries; + for (i = 1; i <= n_entries; i++) + { + entry = g_typelib_get_dir_entry (typelib, i); + entry_name = g_typelib_get_string (typelib, entry->name); + if (strcmp (name, entry_name) == 0) + return entry; + } + return NULL; + } + else + { + guint8 *hash = (guint8*) &typelib->data[dirindex->offset]; + guint16 index; + + index = _gi_typelib_hash_search (hash, name); + entry = g_typelib_get_dir_entry (typelib, index + 1); entry_name = g_typelib_get_string (typelib, entry->name); if (strcmp (name, entry_name) == 0) return entry; + return NULL; } - return NULL; } DirEntry * From eb153575a4290b1779157bf05586b65c248e9e1f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 22 Oct 2010 14:22:19 -0400 Subject: [PATCH 419/692] g_object_info_find_method_using_interfaces: New function Pull this down into introspection from gjs; this will allow us to cache this better in the future (for example, by caching the infos for interfaces in the info for the object). https://bugzilla.gnome.org/show_bug.cgi?id=632924 --- giobjectinfo.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ giobjectinfo.h | 5 +++++ 2 files changed, 62 insertions(+) diff --git a/giobjectinfo.c b/giobjectinfo.c index e1f0bc1df..d6bdce66a 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -413,6 +413,63 @@ g_object_info_find_method (GIObjectInfo *info, return _g_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_methods, name); } +/** + * g_object_info_find_method_using_interfaces: + * @info: a #GIObjectInfo + * @name: name of method to obtain + * @implementor: (out) (transfer full): The implementor of the interface + * + * Obtain a method of the object given a @name, searching both the + * object @info and any interfaces it implements. %NULL will be + * returned if there's no method available with that name. + * + * Note that this function does *not* search parent classes; you will have + * to chain up if that's desired. + * + * Returns: (transfer full): the #GIFunctionInfo. Free the struct by calling + * g_base_info_unref() when done. + */ +GIFunctionInfo * +g_object_info_find_method_using_interfaces (GIObjectInfo *info, + const gchar *name, + GIObjectInfo **implementor) +{ + GIFunctionInfo *result = NULL; + GIObjectInfo *implementor_result = NULL; + + result = g_object_info_find_method (info, name); + if (result) + implementor_result = g_base_info_ref ((GIBaseInfo*) info); + + if (result == NULL) + { + int n_interfaces; + int i; + + n_interfaces = g_object_info_get_n_interfaces (info); + for (i = 0; i < n_interfaces; ++i) + { + GIInterfaceInfo *iface_info; + + iface_info = g_object_info_get_interface (info, i); + + result = g_interface_info_find_method (iface_info, name); + + if (result != NULL) + { + implementor_result = iface_info; + break; + } + g_base_info_unref ((GIBaseInfo*) iface_info); + } + } + if (implementor) + *implementor = implementor_result; + else + g_base_info_unref ((GIBaseInfo*) implementor_result); + return result; +} + /** * g_object_info_get_n_signals: * @info: a #GIObjectInfo diff --git a/giobjectinfo.h b/giobjectinfo.h index 09e4bec98..fd35ef8f0 100644 --- a/giobjectinfo.h +++ b/giobjectinfo.h @@ -91,6 +91,11 @@ GIFunctionInfo * g_object_info_get_method (GIObjectInfo *info, gint n); GIFunctionInfo * g_object_info_find_method (GIObjectInfo *info, const gchar *name); + +GIFunctionInfo * g_object_info_find_method_using_interfaces (GIObjectInfo *info, + const gchar *name, + GIObjectInfo **implementor); + gint g_object_info_get_n_signals (GIObjectInfo *info); GISignalInfo * g_object_info_get_signal (GIObjectInfo *info, gint n); From d01de67d0253ab81011a857f3451162fea983d94 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 6 Dec 2010 11:14:53 -0500 Subject: [PATCH 420/692] g_object_info_find_method_using_interfaces: Fix crash if not found If a method wasn't found, we'd try to unref NULL. --- giobjectinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/giobjectinfo.c b/giobjectinfo.c index d6bdce66a..fbf5d8ab2 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -465,7 +465,7 @@ g_object_info_find_method_using_interfaces (GIObjectInfo *info, } if (implementor) *implementor = implementor_result; - else + else if (implementor_result != NULL) g_base_info_unref ((GIBaseInfo*) implementor_result); return result; } From 732911c70359e6ed13a9fd41677cc345f9d9adab Mon Sep 17 00:00:00 2001 From: Andreas Rottmann Date: Tue, 7 Dec 2010 00:07:08 +0100 Subject: [PATCH 421/692] Don't emit shadowed methods into the typelib Ignore shadowed methods when parsing the GIR. --- girparser.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index 0b0583929..03ab6d2e6 100644 --- a/girparser.c +++ b/girparser.c @@ -688,12 +688,15 @@ introspectable_prelude (GMarkupParseContext *context, ParseState new_state) { const gchar *introspectable_arg; + const gchar *shadowed_by; gboolean introspectable; g_assert (ctx->state != STATE_PASSTHROUGH); introspectable_arg = find_attribute ("introspectable", attribute_names, attribute_values); - introspectable = !(introspectable_arg && atoi (introspectable_arg) == 0); + shadowed_by = find_attribute ("shadowed-by", attribute_names, attribute_values); + + introspectable = !(introspectable_arg && atoi (introspectable_arg) == 0) && shadowed_by == NULL; if (introspectable) state_switch (ctx, new_state); From 0e05b14044db9e86954b72fcd87d22a6f8b2cf3e Mon Sep 17 00:00:00 2001 From: Kristian Rietveld Date: Tue, 28 Dec 2010 10:41:16 +0100 Subject: [PATCH 422/692] Avoid using namespace as identifier in public header files --- girepository.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girepository.h b/girepository.h index 476f183b8..f14b1ad77 100644 --- a/girepository.h +++ b/girepository.h @@ -110,7 +110,7 @@ GITypelib * g_irepository_require (GIRepository *repository, GError **error); GITypelib * g_irepository_require_private (GIRepository *repository, const gchar *typelib_dir, - const gchar *namespace, + const gchar *namespace_, const gchar *version, GIRepositoryLoadFlags flags, GError **error); From 66f164c0ea4013e1970f3bafb1960beed0d2d860 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 11 Jan 2011 14:26:29 +0100 Subject: [PATCH 423/692] scanner: Rename g_irepository_dump when included from the dumper This avoids a naming conflict when compiling GiRepository.gir, where g_irepository_dump() was defined in an included header. --- gdump.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gdump.c b/gdump.c index cdede612b..1b9ffd4f8 100644 --- a/gdump.c +++ b/gdump.c @@ -381,10 +381,12 @@ dump_type (GType type, const char *symbol, GOutputStream *out) * Returns: %TRUE on success, %FALSE on error */ #ifndef G_IREPOSITORY_COMPILATION -static -#endif +static gboolean +dump_irepository (const char *arg, GError **error) +#else gboolean g_irepository_dump (const char *arg, GError **error) +#endif { GHashTable *output_types; char **args; From 95cf1ef4d69a70592d342de7391d478f174017ed Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 13 Dec 2010 13:53:55 +0100 Subject: [PATCH 424/692] Add g_vfunc_info_invoke and g_vfunc_info_get_address for calling the native implementation of a virtual function. Refactors the code common with g_function_info_invoke in _g_callable_info_invoke. https://bugzilla.gnome.org/show_bug.cgi?id=637145 --- gicallableinfo.c | 172 +++++++++++++++++++++++++++++++++++++++++ gifunctioninfo.c | 167 +++------------------------------------ girepository-private.h | 11 +++ givfuncinfo.c | 119 ++++++++++++++++++++++++++++ givfuncinfo.h | 11 +++ 5 files changed, 323 insertions(+), 157 deletions(-) diff --git a/gicallableinfo.c b/gicallableinfo.c index 6b79e62cc..1d439683e 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -26,6 +26,7 @@ #include #include "girepository-private.h" #include "gitypelib-internal.h" +#include "girffi.h" /* GICallableInfo functions */ @@ -335,3 +336,174 @@ g_callable_info_iterate_return_attributes (GICallableInfo *info, return TRUE; } + +gboolean +_g_callable_info_invoke (GIFunctionInfo *info, + gpointer function, + const GIArgument *in_args, + int n_in_args, + const GIArgument *out_args, + int n_out_args, + GIArgument *return_value, + gboolean is_method, + gboolean throws, + GError **error) +{ + ffi_cif cif; + ffi_type *rtype; + ffi_type **atypes; + GITypeInfo *tinfo; + GIArgInfo *ainfo; + gint n_args, n_invoke_args, in_pos, out_pos, i; + gpointer *args; + gboolean success = FALSE; + GError *local_error = NULL; + gpointer error_address = &local_error; + + tinfo = g_callable_info_get_return_type ((GICallableInfo *)info); + rtype = g_type_info_get_ffi_type (tinfo); + g_base_info_unref ((GIBaseInfo *)tinfo); + + in_pos = 0; + out_pos = 0; + + n_args = g_callable_info_get_n_args ((GICallableInfo *)info); + if (is_method) + { + if (n_in_args == 0) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too few \"in\" arguments (handling this)"); + goto out; + } + n_invoke_args = n_args+1; + in_pos++; + } + else + n_invoke_args = n_args; + + if (throws) + /* Add an argument for the GError */ + n_invoke_args ++; + + atypes = g_alloca (sizeof (ffi_type*) * n_invoke_args); + args = g_alloca (sizeof (gpointer) * n_invoke_args); + + if (is_method) + { + atypes[0] = &ffi_type_pointer; + args[0] = (gpointer) &in_args[0]; + } + for (i = 0; i < n_args; i++) + { + int offset = (is_method ? 1 : 0); + ainfo = g_callable_info_get_arg ((GICallableInfo *)info, i); + switch (g_arg_info_get_direction (ainfo)) + { + case GI_DIRECTION_IN: + tinfo = g_arg_info_get_type (ainfo); + atypes[i+offset] = g_type_info_get_ffi_type (tinfo); + g_base_info_unref ((GIBaseInfo *)tinfo); + + if (in_pos >= n_in_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too few \"in\" arguments (handling in)"); + goto out; + } + + args[i+offset] = (gpointer)&in_args[in_pos]; + in_pos++; + + break; + case GI_DIRECTION_OUT: + atypes[i+offset] = &ffi_type_pointer; + + if (out_pos >= n_out_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too few \"out\" arguments (handling out)"); + goto out; + } + + args[i+offset] = (gpointer)&out_args[out_pos]; + out_pos++; + break; + case GI_DIRECTION_INOUT: + atypes[i+offset] = &ffi_type_pointer; + + if (in_pos >= n_in_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too few \"in\" arguments (handling inout)"); + goto out; + } + + if (out_pos >= n_out_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too few \"out\" arguments (handling inout)"); + goto out; + } + + args[i+offset] = (gpointer)&in_args[in_pos]; + in_pos++; + out_pos++; + break; + default: + g_assert_not_reached (); + } + g_base_info_unref ((GIBaseInfo *)ainfo); + } + + if (throws) + { + args[n_invoke_args - 1] = &error_address; + atypes[n_invoke_args - 1] = &ffi_type_pointer; + } + + if (in_pos < n_in_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too many \"in\" arguments (at end)"); + goto out; + } + if (out_pos < n_out_args) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_ARGUMENT_MISMATCH, + "Too many \"out\" arguments (at end)"); + goto out; + } + + if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_invoke_args, rtype, atypes) != FFI_OK) + goto out; + + g_return_val_if_fail (return_value, FALSE); + ffi_call (&cif, function, return_value, args); + + if (local_error) + { + g_propagate_error (error, local_error); + success = FALSE; + } + else + { + success = TRUE; + } + out: + return success; +} diff --git a/gifunctioninfo.c b/gifunctioninfo.c index 2f8920de6..2544cc3f1 100644 --- a/gifunctioninfo.c +++ b/gifunctioninfo.c @@ -26,7 +26,6 @@ #include #include "girepository-private.h" #include "gitypelib-internal.h" -#include "girffi.h" /** * SECTION:gifunctioninfo @@ -249,20 +248,10 @@ g_function_info_invoke (GIFunctionInfo *info, GIArgument *return_value, GError **error) { - ffi_cif cif; - ffi_type *rtype; - ffi_type **atypes; const gchar *symbol; gpointer func; - GITypeInfo *tinfo; - GIArgInfo *ainfo; gboolean is_method; gboolean throws; - gint n_args, n_invoke_args, in_pos, out_pos, i; - gpointer *args; - gboolean success = FALSE; - GError *local_error = NULL; - gpointer error_address = &local_error; symbol = g_function_info_get_symbol (info); @@ -281,150 +270,14 @@ g_function_info_invoke (GIFunctionInfo *info, && (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR) == 0; throws = g_function_info_get_flags (info) & GI_FUNCTION_THROWS; - tinfo = g_callable_info_get_return_type ((GICallableInfo *)info); - rtype = g_type_info_get_ffi_type (tinfo); - g_base_info_unref ((GIBaseInfo *)tinfo); - - in_pos = 0; - out_pos = 0; - - n_args = g_callable_info_get_n_args ((GICallableInfo *)info); - if (is_method) - { - if (n_in_args == 0) - { - g_set_error (error, - G_INVOKE_ERROR, - G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too few \"in\" arguments (handling this)"); - goto out; - } - n_invoke_args = n_args+1; - in_pos++; - } - else - n_invoke_args = n_args; - - if (throws) - /* Add an argument for the GError */ - n_invoke_args ++; - - atypes = g_alloca (sizeof (ffi_type*) * n_invoke_args); - args = g_alloca (sizeof (gpointer) * n_invoke_args); - - if (is_method) - { - atypes[0] = &ffi_type_pointer; - args[0] = (gpointer) &in_args[0]; - } - for (i = 0; i < n_args; i++) - { - int offset = (is_method ? 1 : 0); - ainfo = g_callable_info_get_arg ((GICallableInfo *)info, i); - switch (g_arg_info_get_direction (ainfo)) - { - case GI_DIRECTION_IN: - tinfo = g_arg_info_get_type (ainfo); - atypes[i+offset] = g_type_info_get_ffi_type (tinfo); - g_base_info_unref ((GIBaseInfo *)tinfo); - - if (in_pos >= n_in_args) - { - g_set_error (error, - G_INVOKE_ERROR, - G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too few \"in\" arguments (handling in)"); - goto out; - } - - args[i+offset] = (gpointer)&in_args[in_pos]; - in_pos++; - - break; - case GI_DIRECTION_OUT: - atypes[i+offset] = &ffi_type_pointer; - - if (out_pos >= n_out_args) - { - g_set_error (error, - G_INVOKE_ERROR, - G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too few \"out\" arguments (handling out)"); - goto out; - } - - args[i+offset] = (gpointer)&out_args[out_pos]; - out_pos++; - break; - case GI_DIRECTION_INOUT: - atypes[i+offset] = &ffi_type_pointer; - - if (in_pos >= n_in_args) - { - g_set_error (error, - G_INVOKE_ERROR, - G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too few \"in\" arguments (handling inout)"); - goto out; - } - - if (out_pos >= n_out_args) - { - g_set_error (error, - G_INVOKE_ERROR, - G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too few \"out\" arguments (handling inout)"); - goto out; - } - - args[i+offset] = (gpointer)&in_args[in_pos]; - in_pos++; - out_pos++; - break; - default: - g_assert_not_reached (); - } - g_base_info_unref ((GIBaseInfo *)ainfo); - } - - if (throws) - { - args[n_invoke_args - 1] = &error_address; - atypes[n_invoke_args - 1] = &ffi_type_pointer; - } - - if (in_pos < n_in_args) - { - g_set_error (error, - G_INVOKE_ERROR, - G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too many \"in\" arguments (at end)"); - goto out; - } - if (out_pos < n_out_args) - { - g_set_error (error, - G_INVOKE_ERROR, - G_INVOKE_ERROR_ARGUMENT_MISMATCH, - "Too many \"out\" arguments (at end)"); - goto out; - } - - if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, n_invoke_args, rtype, atypes) != FFI_OK) - goto out; - - g_return_val_if_fail (return_value, FALSE); - ffi_call (&cif, func, return_value, args); - - if (local_error) - { - g_propagate_error (error, local_error); - success = FALSE; - } - else - { - success = TRUE; - } - out: - return success; + return _g_callable_info_invoke ((GICallableInfo*) info, + func, + in_args, + n_in_args, + out_args, + n_out_args, + return_value, + is_method, + throws, + error); } diff --git a/girepository-private.h b/girepository-private.h index 897c52c4c..52d65b2bd 100644 --- a/girepository-private.h +++ b/girepository-private.h @@ -108,6 +108,17 @@ GIVFuncInfo * _g_base_info_find_vfunc (GIRealInfo *rinfo, gint n_vfuncs, const gchar *name); +gboolean _g_callable_info_invoke (GICallableInfo *info, + gpointer function, + const GIArgument *in_args, + int n_in_args, + const GIArgument *out_args, + int n_out_args, + GIArgument *return_value, + gboolean is_method, + gboolean throws, + GError **error); + extern ffi_status ffi_prep_closure_loc (ffi_closure *, ffi_cif *, void (*fun)(ffi_cif *, void *, void **, void *), diff --git a/givfuncinfo.c b/givfuncinfo.c index 98ac94539..332655a05 100644 --- a/givfuncinfo.c +++ b/givfuncinfo.c @@ -196,3 +196,122 @@ g_vfunc_info_get_invoker (GIVFuncInfo *info) g_assert_not_reached (); } +/** + * g_vfunc_info_get_address: + * @info: a #GIVFuncInfo + * @implementor_gtype: #GType implementing this virtual function + * @error: return location for a #GError + * + * This method will look up where inside the type struct of @implementor_gtype + * is the implementation for @info. + * + * Returns: address to a function or %NULL if an error happened + */ +gpointer +g_vfunc_info_get_address (GIVFuncInfo *vfunc_info, + GType implementor_gtype, + GError **error) +{ + GIObjectInfo *object_info; + GIStructInfo *struct_info; + GIFieldInfo *field_info = NULL; + int length, i, offset; + gpointer implementor_vtable, func; + + object_info = (GIObjectInfo *) g_base_info_get_container (vfunc_info); + struct_info = g_object_info_get_class_struct (object_info); + + length = g_struct_info_get_n_fields (struct_info); + for (i = 0; i < length; i++) + { + field_info = g_struct_info_get_field (struct_info, i); + + if (strcmp (g_base_info_get_name ( (GIBaseInfo*) field_info), + g_base_info_get_name ( (GIBaseInfo*) vfunc_info)) != 0) { + g_base_info_unref (field_info); + field_info = NULL; + continue; + } + + break; + } + + if (field_info == NULL) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_SYMBOL_NOT_FOUND, + "Couldn't find struct field for this vfunc"); + return NULL; + } + + implementor_vtable = g_type_class_ref (implementor_gtype); + offset = g_field_info_get_offset (field_info); + func = *(gpointer*) G_STRUCT_MEMBER_P (implementor_vtable, offset); + g_type_class_unref (implementor_vtable); + + if (func == NULL) + { + g_set_error (error, + G_INVOKE_ERROR, + G_INVOKE_ERROR_SYMBOL_NOT_FOUND, + "Class %s doesn't implement %s", + g_type_name (implementor_gtype), + g_base_info_get_name ( (GIBaseInfo*) vfunc_info)); + return NULL; + } + + return func; +} + +/** + * g_vfunc_info_invoke: (skip) + * @info: a #GIVFuncInfo describing the virtual function to invoke + * @implementor: #GType of the type that implements this virtual function + * @in_args: an array of #GIArguments, one for each in + * parameter of @info. If there are no in parameter, @in_args + * can be %NULL + * @n_in_args: the length of the @in_args array + * @out_args: an array of #GIArguments, one for each out + * parameter of @info. If there are no out parameters, @out_args + * may be %NULL + * @n_out_args: the length of the @out_args array + * @return_value: return location for the return value of the + * function. If the function returns void, @return_value may be + * %NULL + * @error: return location for detailed error information, or %NULL + * + * Invokes the function described in @info with the given + * arguments. Note that inout parameters must appear in both + * argument lists. + * + * Returns: %TRUE if the function has been invoked, %FALSE if an + * error occurred. + */ +gboolean +g_vfunc_info_invoke (GIVFuncInfo *info, + GType implementor, + const GIArgument *in_args, + int n_in_args, + const GIArgument *out_args, + int n_out_args, + GIArgument *return_value, + GError **error) +{ + gpointer func; + + func = g_vfunc_info_get_address (info, implementor, error); + if (*error != NULL) + return FALSE; + + return _g_callable_info_invoke ((GICallableInfo*) info, + func, + in_args, + n_in_args, + out_args, + n_out_args, + return_value, + TRUE, + FALSE, + error); +} diff --git a/givfuncinfo.h b/givfuncinfo.h index 6629cad81..3c556cbe3 100644 --- a/givfuncinfo.h +++ b/givfuncinfo.h @@ -37,6 +37,17 @@ GIVFuncInfoFlags g_vfunc_info_get_flags (GIVFuncInfo *info); gint g_vfunc_info_get_offset (GIVFuncInfo *info); GISignalInfo * g_vfunc_info_get_signal (GIVFuncInfo *info); GIFunctionInfo * g_vfunc_info_get_invoker (GIVFuncInfo *info); +gpointer g_vfunc_info_get_address (GIVFuncInfo *info, + GType implementor_gtype, + GError **error); +gboolean g_vfunc_info_invoke (GIVFuncInfo *info, + GType implementor, + const GIArgument *in_args, + int n_in_args, + const GIArgument *out_args, + int n_out_args, + GIArgument *return_value, + GError **error); G_END_DECLS From 5857d9c231f9ad3725b4de3e0340dd5eed236a7b Mon Sep 17 00:00:00 2001 From: Pavel Holejsovsky Date: Tue, 14 Dec 2010 16:28:01 +0100 Subject: [PATCH 425/692] Add support for g[u]intptr in scanner and girwriter. https://bugzilla.gnome.org/show_bug.cgi?id=634838 --- girparser.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/girparser.c b/girparser.c index 03ab6d2e6..96761ace5 100644 --- a/girparser.c +++ b/girparser.c @@ -366,8 +366,10 @@ static IntegerAliasInfo integer_aliases[] = { { "guint", SIZEOF_INT, 0 }, { "glong", SIZEOF_LONG, 1 }, { "gulong", SIZEOF_LONG, 0 }, - { "gsize", GLIB_SIZEOF_SIZE_T, 0 }, { "gssize", GLIB_SIZEOF_SIZE_T, 1 }, + { "gsize", GLIB_SIZEOF_SIZE_T, 0 }, + { "gintptr", GLIB_SIZEOF_SIZE_T, 1 }, + { "guintptr", GLIB_SIZEOF_SIZE_T, 0 }, }; typedef struct { @@ -407,12 +409,12 @@ parse_basic (const char *str) for (i = 0; i < n_basic; i++) { - if (g_str_has_prefix (str, basic_types[i].str)) + if (strcmp (str, basic_types[i].str) == 0) return &(basic_types[i]); } for (i = 0; i < G_N_ELEMENTS (integer_aliases); i++) { - if (g_str_has_prefix (str, integer_aliases[i].str)) + if (strcmp (str, integer_aliases[i].str) == 0) { switch (integer_aliases[i].size) { From 04c822609a75bc7beb55a92414e4f553deced9fc Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Wed, 19 Jan 2011 16:48:47 +0100 Subject: [PATCH 426/692] Pass shared-library as-is to g_module_open Because it already has the lib prefix and the .so postfix https://bugzilla.gnome.org/show_bug.cgi?id=639961 --- gitypelib.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gitypelib.c b/gitypelib.c index 90f2c1bbb..3ecfb16b6 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -2129,10 +2129,6 @@ _g_typelib_do_dlopen (GITypelib *typelib) { GString *shlib_full = g_string_new (shlibs[i]); - /* Prefix with "lib", try both .la and .so */ - if (!g_str_has_prefix (shlib_full->str, "lib")) - g_string_prepend (shlib_full, "lib"); - g_string_append (shlib_full, ".la"); module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); if (module == NULL) { From 5debbc28a92922a9476e903d5e33d234ceaebc14 Mon Sep 17 00:00:00 2001 From: Jonathan Matthew Date: Sun, 6 Feb 2011 14:48:58 +1000 Subject: [PATCH 427/692] Account for arg direction in g_callable_info_get_ffi_arg_types https://bugzilla.gnome.org/show_bug.cgi?id=641647 --- girffi.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/girffi.c b/girffi.c index d2afca0a5..b7c1ceae2 100644 --- a/girffi.c +++ b/girffi.c @@ -130,7 +130,18 @@ g_callable_info_get_ffi_arg_types (GICallableInfo *callable_info) { GIArgInfo *arg_info = g_callable_info_get_arg (callable_info, i); GITypeInfo *arg_type = g_arg_info_get_type (arg_info); - arg_types[i] = g_type_info_get_ffi_type (arg_type); + switch (g_arg_info_get_direction (arg_info)) + { + case GI_DIRECTION_IN: + arg_types[i] = g_type_info_get_ffi_type (arg_type); + break; + case GI_DIRECTION_OUT: + case GI_DIRECTION_INOUT: + arg_types[i] = &ffi_type_pointer; + break; + default: + g_assert_not_reached (); + } g_base_info_unref ((GIBaseInfo *)arg_info); g_base_info_unref ((GIBaseInfo *)arg_type); } From f478da144f539944d9b26a432ead6bc441c3ade1 Mon Sep 17 00:00:00 2001 From: Laszlo Pandy Date: Thu, 17 Feb 2011 18:01:31 +0100 Subject: [PATCH 428/692] Fix argument name of MISSING_ATTRIBUTE macro ('ctx' => 'context'). The argument was called 'ctx' but the macro was using 'context'. This wasn't causing the build to fail because the variable 'context' was already defined in all the scopes where this macro was used. --- girparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index 96761ace5..be74e0bbd 100644 --- a/girparser.c +++ b/girparser.c @@ -293,7 +293,7 @@ locate_gir (GIrParser *parser, return NULL; } -#define MISSING_ATTRIBUTE(ctx,error,element,attribute) \ +#define MISSING_ATTRIBUTE(context,error,element,attribute) \ do { \ int line_number, char_number; \ g_markup_parse_context_get_position (context, &line_number, &char_number); \ From a0890f3d8f9c2008302c86ac39f65694789101eb Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Fri, 18 Feb 2011 18:14:25 +0100 Subject: [PATCH 429/692] GIrNode: fix lookup of cached type nodes Different types of array have different type nodes, so they should produce different keys in the cache of already seen type nodes, to avoid turning a GByteArray into a reference to a GPtrArray. https://bugzilla.gnome.org/show_bug.cgi?id=642300 --- girnode.c | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/girnode.c b/girnode.c index fe45503d7..fe10e543b 100644 --- a/girnode.c +++ b/girnode.c @@ -1227,19 +1227,42 @@ serialize_type (GIrTypelibBuild *build, } else if (node->tag == GI_TYPE_TAG_ARRAY) { - serialize_type (build, node->parameter_type1, str); - g_string_append (str, "["); + if (node->array_type == GI_ARRAY_TYPE_C) + { + serialize_type (build, node->parameter_type1, str); + g_string_append (str, "["); - if (node->has_length) - g_string_append_printf (str, "length=%d", node->length); - else if (node->has_size) - g_string_append_printf (str, "fixed-size=%d", node->size); + if (node->has_length) + g_string_append_printf (str, "length=%d", node->length); + else if (node->has_size) + g_string_append_printf (str, "fixed-size=%d", node->size); - if (node->zero_terminated) - g_string_append_printf (str, "%szero-terminated=1", - node->has_length ? "," : ""); + if (node->zero_terminated) + g_string_append_printf (str, "%szero-terminated=1", + node->has_length ? "," : ""); - g_string_append (str, "]"); + g_string_append (str, "]"); + } + else if (node->array_type == GI_ARRAY_TYPE_BYTE_ARRAY) + { + /* We on purpose skip serializing parameter_type1, which should + always be void* + */ + g_string_append (str, "GByteArray"); + } + else + { + if (node->array_type == GI_ARRAY_TYPE_ARRAY) + g_string_append (str, "GArray"); + else + g_string_append (str, "GPtrArray"); + if (node->parameter_type1) + { + g_string_append (str, "<"); + serialize_type (build, node->parameter_type1, str); + g_string_append (str, ">"); + } + } } else if (node->tag == GI_TYPE_TAG_INTERFACE) { @@ -1284,7 +1307,7 @@ serialize_type (GIrTypelibBuild *build, } else if (node->tag == GI_TYPE_TAG_GHASH) { - g_string_append (str, "GHashTable<"); + g_string_append (str, "GHashTable"); if (node->parameter_type1) { g_string_append (str, "<"); From 8304598583fd80f0bbc7d3c4b21d53581478985c Mon Sep 17 00:00:00 2001 From: Laszlo Pandy Date: Tue, 22 Feb 2011 16:02:12 +0100 Subject: [PATCH 430/692] Add "c:identifier" attribute to GIrNodeValue (for flags and enum values). Flags and enums with a GType have a value_nick and value_name strings available in the class struct. But for flags and enums without GType, we need to get this information from introspection. g_base_info_get_name() gives the string for value_nick. In the GIR, the attribute "c:identifier" is the string neede for value_name. This patch adds the "c:identifier" from GIR to the typelib for all flags and enum values. It can be retireved using g_base_info_get_attribute(info, "c:identifier"). https://bugzilla.gnome.org/show_bug.cgi?id=642757 --- girparser.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/girparser.c b/girparser.c index be74e0bbd..e32acc0dc 100644 --- a/girparser.c +++ b/girparser.c @@ -1480,6 +1480,7 @@ start_member (GMarkupParseContext *context, const gchar *name; const gchar *value; const gchar *deprecated; + const gchar *c_identifier; GIrNodeEnum *enum_; GIrNodeValue *value_; @@ -1490,6 +1491,7 @@ start_member (GMarkupParseContext *context, name = find_attribute ("name", attribute_names, attribute_values); value = find_attribute ("value", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); + c_identifier = find_attribute ("c:identifier", attribute_names, attribute_values); if (name == NULL) { @@ -1509,6 +1511,10 @@ start_member (GMarkupParseContext *context, else value_->deprecated = FALSE; + g_hash_table_insert (((GIrNode *)value_)->attributes, + g_strdup ("c:identifier"), + g_strdup (c_identifier)); + enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx); enum_->values = g_list_append (enum_->values, value_); From feedce80290fef993629bd16cb28169c2b85a99d Mon Sep 17 00:00:00 2001 From: "John (J5) Palmieri" Date: Mon, 14 Mar 2011 14:18:22 -0400 Subject: [PATCH 431/692] support setting gobjects and ginterfaces in struct fields https://bugzilla.gnome.org/show_bug.cgi?id=644749 --- gifieldinfo.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/gifieldinfo.c b/gifieldinfo.c index d4fd14e2a..cf5c23326 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -512,6 +512,23 @@ g_field_info_set_field (GIFieldInfo *field_info, } break; } + } else { + switch (g_type_info_get_tag (type_info)) + { + case GI_TYPE_TAG_INTERFACE: + { + GIBaseInfo *interface = g_type_info_get_interface (type_info); + switch (g_base_info_get_type (interface)) + { + case GI_INFO_TYPE_OBJECT: + case GI_INFO_TYPE_INTERFACE: + G_STRUCT_MEMBER (gpointer, mem, offset) = (gpointer)value->v_pointer; + result = TRUE; + break; + } + g_base_info_unref ((GIBaseInfo *)interface); + } + } } g_base_info_unref ((GIBaseInfo *)type_info); From 1611ff77df5941a4cd19c1a3372a6358624115e8 Mon Sep 17 00:00:00 2001 From: Serkan Kaba Date: Sun, 20 Mar 2011 03:00:22 +0200 Subject: [PATCH 432/692] girparser: use c:identifier-prefixes instead of c:prefix This bug was introduced with http://git.gnome.org/browse/gobject-introspection/commit/?id=36aa515f1036978ced8d4ffb808260844f7229e0 due to rename of c:prefix to c:identifier-prefixes. https://bugzilla.gnome.org/show_bug.cgi?id=640264 --- girparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index e32acc0dc..f7269b92c 100644 --- a/girparser.c +++ b/girparser.c @@ -2884,7 +2884,7 @@ start_element_handler (GMarkupParseContext *context, name = find_attribute ("name", attribute_names, attribute_values); version = find_attribute ("version", attribute_names, attribute_values); shared_library = find_attribute ("shared-library", attribute_names, attribute_values); - cprefix = find_attribute ("c:prefix", attribute_names, attribute_values); + cprefix = find_attribute ("c:identifier-prefixes", attribute_names, attribute_values); if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); From eeddf775677b2df9927643d064b78e9776ced494 Mon Sep 17 00:00:00 2001 From: Maxim Ermilov Date: Thu, 17 Feb 2011 23:27:09 +0300 Subject: [PATCH 433/692] g_field_info_get_field: return correct pointer for C array Also add a test case. https://bugzilla.gnome.org/show_bug.cgi?id=640468 --- gifieldinfo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gifieldinfo.c b/gifieldinfo.c index cf5c23326..b9b56a4de 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -193,7 +193,10 @@ g_field_info_get_field (GIFieldInfo *field_info, if (g_type_info_is_pointer (type_info)) { - value->v_pointer = G_STRUCT_MEMBER (gpointer, mem, offset); + if (g_type_info_get_array_type (type_info) == GI_ARRAY_TYPE_C) + value->v_pointer = G_STRUCT_MEMBER_P ((mem), (offset)); + else + value->v_pointer = G_STRUCT_MEMBER (gpointer, mem, offset); result = TRUE; } else From b35c985e15a5f6fda879f5643cfc1bdfd4fa9ff7 Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Fri, 13 May 2011 12:20:05 -0400 Subject: [PATCH 434/692] Add support for the (skip) annotation on parameters or return values This was discussed in bug 649657. https://bugzilla.gnome.org/show_bug.cgi?id=649657 Signed-off-by: David Zeuthen --- giarginfo.c | 22 ++++++++++++++++++++++ giarginfo.h | 1 + gicallableinfo.c | 22 ++++++++++++++++++++++ gicallableinfo.h | 1 + girnode.c | 2 ++ girnode.h | 1 + girparser.c | 14 ++++++++++++++ girwriter.c | 6 ++++++ gitypelib-internal.h | 8 ++++++-- 9 files changed, 75 insertions(+), 2 deletions(-) diff --git a/giarginfo.c b/giarginfo.c index dc1d1162e..069ecce0e 100644 --- a/giarginfo.c +++ b/giarginfo.c @@ -164,6 +164,28 @@ g_arg_info_may_be_null (GIArgInfo *info) return blob->allow_none; } +/** + * g_arg_info_is_skip: + * @info: a #GIArgInfo + * + * Obtain if an argument is only useful in C. + * + * Returns: %TRUE if argument is only useful in C. + */ +gboolean +g_arg_info_is_skip (GIArgInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ArgBlob *blob; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE); + + blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->skip; +} + /** * g_arg_info_get_ownership_transfer: * @info: a #GIArgInfo diff --git a/giarginfo.h b/giarginfo.h index e38d16fe1..9daafa270 100644 --- a/giarginfo.h +++ b/giarginfo.h @@ -38,6 +38,7 @@ gboolean g_arg_info_is_return_value (GIArgInfo *info); gboolean g_arg_info_is_optional (GIArgInfo *info); gboolean g_arg_info_is_caller_allocates (GIArgInfo *info); gboolean g_arg_info_may_be_null (GIArgInfo *info); +gboolean g_arg_info_is_skip (GIArgInfo *info); GITransfer g_arg_info_get_ownership_transfer (GIArgInfo *info); GIScopeType g_arg_info_get_scope (GIArgInfo *info); gint g_arg_info_get_closure (GIArgInfo *info); diff --git a/gicallableinfo.c b/gicallableinfo.c index 1d439683e..475346e22 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -152,6 +152,28 @@ g_callable_info_may_return_null (GICallableInfo *info) return blob->may_return_null; } +/** + * g_callable_info_skip_return: + * @info: a #GICallableInfo + * + * See if a callable's return value is only useful in C. + * + * Returns: %TRUE if return value is only useful in C. + */ +gboolean +g_callable_info_skip_return (GICallableInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + SignatureBlob *blob; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), FALSE); + + blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)]; + + return blob->skip_return; +} + /** * g_callable_info_get_caller_owns: * @info: a #GICallableInfo diff --git a/gicallableinfo.h b/gicallableinfo.h index 54d2cacb7..a1d22c749 100644 --- a/gicallableinfo.h +++ b/gicallableinfo.h @@ -47,6 +47,7 @@ gboolean g_callable_info_iterate_return_attributes (GICallableInfo char **value); GITransfer g_callable_info_get_caller_owns (GICallableInfo *info); gboolean g_callable_info_may_return_null (GICallableInfo *info); +gboolean g_callable_info_skip_return (GICallableInfo *info); gint g_callable_info_get_n_args (GICallableInfo *info); GIArgInfo * g_callable_info_get_arg (GICallableInfo *info, gint n); diff --git a/girnode.c b/girnode.c index fe10e543b..9998d8e5b 100644 --- a/girnode.c +++ b/girnode.c @@ -1685,6 +1685,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob2->may_return_null = function->result->allow_none; blob2->caller_owns_return_value = function->result->transfer; blob2->caller_owns_return_container = function->result->shallow_transfer; + blob2->skip_return = function->result->skip; blob2->reserved = 0; blob2->n_arguments = n; @@ -1869,6 +1870,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob->out = param->out; blob->caller_allocates = param->caller_allocates; blob->allow_none = param->allow_none; + blob->skip = param->skip; blob->optional = param->optional; blob->transfer_ownership = param->transfer; blob->transfer_container_ownership = param->shallow_transfer; diff --git a/girnode.h b/girnode.h index e215e2cde..1f9102fd2 100644 --- a/girnode.h +++ b/girnode.h @@ -147,6 +147,7 @@ struct _GIrNodeParam gboolean optional; gboolean retval; gboolean allow_none; + gboolean skip; gboolean transfer; gboolean shallow_transfer; GIScopeType scope; diff --git a/girparser.c b/girparser.c index f7269b92c..02c044279 100644 --- a/girparser.c +++ b/girparser.c @@ -1030,6 +1030,7 @@ start_parameter (GMarkupParseContext *context, const gchar *scope; const gchar *closure; const gchar *destroy; + const gchar *skip; GIrNodeParam *param; if (!(strcmp (element_name, "parameter") == 0 && @@ -1046,6 +1047,7 @@ start_parameter (GMarkupParseContext *context, scope = find_attribute ("scope", attribute_names, attribute_values); closure = find_attribute ("closure", attribute_names, attribute_values); destroy = find_attribute ("destroy", attribute_names, attribute_values); + skip = find_attribute ("skip", attribute_names, attribute_values); if (name == NULL) name = "unknown"; @@ -1095,6 +1097,11 @@ start_parameter (GMarkupParseContext *context, else param->allow_none = FALSE; + if (skip && strcmp (skip, "1") == 0) + param->skip = TRUE; + else + param->skip = FALSE; + if (!parse_param_transfer (param, transfer, name, error)) return FALSE; @@ -2200,6 +2207,7 @@ start_return_value (GMarkupParseContext *context, { GIrNodeParam *param; const gchar *transfer; + const gchar *skip; if (!(strcmp (element_name, "return-value") == 0 && ctx->state == STATE_FUNCTION)) @@ -2215,6 +2223,12 @@ start_return_value (GMarkupParseContext *context, state_switch (ctx, STATE_FUNCTION_RETURN); + skip = find_attribute ("skip", attribute_names, attribute_values); + if (skip && strcmp (skip, "1") == 0) + param->skip = TRUE; + else + param->skip = FALSE; + transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); if (!parse_param_transfer (param, transfer, NULL, error)) return FALSE; diff --git a/girwriter.c b/girwriter.c index e90799c13..f6ab34ebd 100644 --- a/girwriter.c +++ b/girwriter.c @@ -482,6 +482,9 @@ write_callable_info (const gchar *namespace, if (g_callable_info_may_return_null (info)) xml_printf (file, " allow-none=\"1\""); + if (g_callable_info_skip_return (info)) + xml_printf (file, " skip=\"1\""); + write_return_value_attributes (file, info); write_type_info (namespace, type, file); @@ -545,6 +548,9 @@ write_callable_info (const gchar *namespace, if (g_arg_info_get_destroy (arg) >= 0) xml_printf (file, " destroy=\"%d\"", g_arg_info_get_destroy (arg)); + if (g_arg_info_is_skip (arg)) + xml_printf (file, " skip=\"1\""); + write_attributes (file, (GIBaseInfo*) arg); type = g_arg_info_get_type (arg); diff --git a/gitypelib-internal.h b/gitypelib-internal.h index e8f5c0250..593c9876c 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -409,6 +409,7 @@ typedef union * @destroy: Index of the destroy notfication callback parameter associated with * the callback, or -1. * @arg_type: Describes the type of the parameter. See details below. + * @skip: Indicates that the parameter is only useful in C and should be skipped. * * Types are specified by four bytes. If the three high bytes are zero, * the low byte describes a basic type, otherwise the 32bit number is an @@ -426,8 +427,9 @@ typedef struct { guint transfer_container_ownership : 1; guint return_value : 1; guint scope : 3; + guint skip : 1; /* */ - guint reserved :21; + guint reserved :20; /* */ gint8 closure; gint8 destroy; @@ -445,6 +447,7 @@ typedef struct { * @caller_owns_return_container: This flag is only relevant if the return type is a container type. * If the flag is set, the caller is resonsible for freeing the * container, but not its contents. + * @skip_return: Indicates that the return value is only useful in C and should be skipped. * @n_arguments: The number of arguments that this function expects, also the length * of the array of ArgBlobs. * @arguments: An array of ArgBlob for the arguments of the function. @@ -455,7 +458,8 @@ typedef struct { guint16 may_return_null : 1; guint16 caller_owns_return_value : 1; guint16 caller_owns_return_container : 1; - guint16 reserved :13; + guint16 skip_return : 1; + guint16 reserved :12; guint16 n_arguments; From 0c5d8c1aa91444872acd95ed734511b26d7e9cbb Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 13 May 2011 14:23:05 -0400 Subject: [PATCH 435/692] Add Since: for g_arg_info_is_skip() --- giarginfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/giarginfo.c b/giarginfo.c index 069ecce0e..0d1f0bbf6 100644 --- a/giarginfo.c +++ b/giarginfo.c @@ -171,6 +171,7 @@ g_arg_info_may_be_null (GIArgInfo *info) * Obtain if an argument is only useful in C. * * Returns: %TRUE if argument is only useful in C. + * Since: 1.29.0 */ gboolean g_arg_info_is_skip (GIArgInfo *info) From 9948f518dcbcbfbb76f665d2f9cc47ece33d6ff2 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 23 May 2011 09:59:02 -0400 Subject: [PATCH 436/692] gifieldinfo.c: Quiet some compiler warnings --- gifieldinfo.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gifieldinfo.c b/gifieldinfo.c index b9b56a4de..eb0b6b2b7 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -528,9 +528,13 @@ g_field_info_set_field (GIFieldInfo *field_info, G_STRUCT_MEMBER (gpointer, mem, offset) = (gpointer)value->v_pointer; result = TRUE; break; + default: + break; } g_base_info_unref ((GIBaseInfo *)interface); } + default: + break; } } From 343c76431ab6b74b42a0fac659992cb5eb65e06e Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Mon, 6 Jun 2011 20:06:54 +0200 Subject: [PATCH 437/692] Assume only that an array is embedded in a struct if it's fixed size --- gifieldinfo.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gifieldinfo.c b/gifieldinfo.c index eb0b6b2b7..106fc1ce9 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -193,8 +193,12 @@ g_field_info_get_field (GIFieldInfo *field_info, if (g_type_info_is_pointer (type_info)) { - if (g_type_info_get_array_type (type_info) == GI_ARRAY_TYPE_C) - value->v_pointer = G_STRUCT_MEMBER_P ((mem), (offset)); + if (g_type_info_get_array_type (type_info) == GI_ARRAY_TYPE_C && + g_type_info_get_array_fixed_size (type_info) >= 0) + { + /* Consider fixed-size arrays as embedded inside the struct */ + value->v_pointer = G_STRUCT_MEMBER_P ((mem), (offset)); + } else value->v_pointer = G_STRUCT_MEMBER (gpointer, mem, offset); result = TRUE; From fef2a7b8dd313dcf107d1cbb5791e150d700fd4d Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Sun, 5 Jun 2011 20:57:01 +0200 Subject: [PATCH 438/692] Fix accessing structure fields that are arrays We need to distinguish inline arrays inside structures, and arrays that are pointers and annotations, and we can do it with g_type_info_is_pointer(), setting it to FALSE for fixed size arrays. As a side effect, (array fixed-size=N) on a pointer type has no longer the expected result. https://bugzilla.gnome.org/show_bug.cgi?id=646635 --- gifieldinfo.c | 16 +++++++--------- girnode.c | 4 +++- gitypelib.c | 13 ------------- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/gifieldinfo.c b/gifieldinfo.c index 106fc1ce9..17491a80a 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -193,14 +193,7 @@ g_field_info_get_field (GIFieldInfo *field_info, if (g_type_info_is_pointer (type_info)) { - if (g_type_info_get_array_type (type_info) == GI_ARRAY_TYPE_C && - g_type_info_get_array_fixed_size (type_info) >= 0) - { - /* Consider fixed-size arrays as embedded inside the struct */ - value->v_pointer = G_STRUCT_MEMBER_P ((mem), (offset)); - } - else - value->v_pointer = G_STRUCT_MEMBER (gpointer, mem, offset); + value->v_pointer = G_STRUCT_MEMBER (gpointer, mem, offset); result = TRUE; } else @@ -248,9 +241,14 @@ g_field_info_get_field (GIFieldInfo *field_info, value->v_double = G_STRUCT_MEMBER (gdouble, mem, offset); result = TRUE; break; + case GI_TYPE_TAG_ARRAY: + /* We don't check the array type and that it is fixed-size, + we trust g-ir-compiler to do the right thing */ + value->v_pointer = G_STRUCT_MEMBER_P (mem, offset); + result = TRUE; + break; case GI_TYPE_TAG_UTF8: case GI_TYPE_TAG_FILENAME: - case GI_TYPE_TAG_ARRAY: case GI_TYPE_TAG_GLIST: case GI_TYPE_TAG_GSLIST: case GI_TYPE_TAG_GHASH: diff --git a/girnode.c b/girnode.c index 9998d8e5b..a56471e52 100644 --- a/girnode.c +++ b/girnode.c @@ -1242,6 +1242,8 @@ serialize_type (GIrTypelibBuild *build, node->has_length ? "," : ""); g_string_append (str, "]"); + if (node->is_pointer) + g_string_append (str, "*"); } else if (node->array_type == GI_ARRAY_TYPE_BYTE_ARRAY) { @@ -1476,7 +1478,7 @@ _g_ir_node_build_typelib (GIrNode *node, ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2]; guint32 pos; - array->pointer = 1; + array->pointer = type->is_pointer; array->reserved = 0; array->tag = type->tag; array->zero_terminated = type->zero_terminated; diff --git a/gitypelib.c b/gitypelib.c index 3ecfb16b6..6d1333ba0 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -523,19 +523,6 @@ validate_array_type_blob (GITypelib *typelib, gboolean return_type, GError **error) { - ArrayTypeBlob *blob; - - blob = (ArrayTypeBlob*)&typelib->data[offset]; - - if (!blob->pointer) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Pointer type exected for tag %d", blob->tag); - return FALSE; - } - /* FIXME validate length */ if (!validate_type_blob (typelib, From a1b527c79f001e371341a8dd7b877629e7765a99 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Wed, 25 May 2011 19:26:49 +0200 Subject: [PATCH 439/692] Rework how fundamental GObject types are introspected Change the special code for handling GObject and GInitiallyUnowned so that it exposes GParamSpec as a class, and it allows GVariant to have a GType without using the deprecate g_variant_get_gtype. It is a sort of ABI break, in that new typelibs won't work with previous versions of libgirepository. https://bugzilla.gnome.org/show_bug.cgi?id=646635 --- gdump.c | 2 +- giregisteredtypeinfo.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/gdump.c b/gdump.c index 1b9ffd4f8..cb6e74197 100644 --- a/gdump.c +++ b/gdump.c @@ -177,7 +177,7 @@ dump_object_type (GType type, const char *symbol, GOutputStream *out) parent = g_type_parent (type); parent_str = g_string_new (""); - while (parent != G_TYPE_OBJECT && parent != G_TYPE_INVALID) + while (parent != G_TYPE_INVALID) { if (first) first = FALSE; diff --git a/giregisteredtypeinfo.c b/giregisteredtypeinfo.c index ca06b9f83..6c1b93217 100644 --- a/giregisteredtypeinfo.c +++ b/giregisteredtypeinfo.c @@ -136,7 +136,9 @@ g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info) if (type_init == NULL) return G_TYPE_NONE; else if (!strcmp (type_init, "intern")) - return G_TYPE_OBJECT; + /* The special string "intern" is used for some types exposed by libgobject + (that therefore should be always available) */ + return g_type_from_name (g_registered_type_info_get_type_name (info)); get_type_func = NULL; if (!g_typelib_symbol (rinfo->typelib, From 98067194d63294c280c8893e4bd6b935376936e9 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Mon, 20 Jun 2011 21:17:55 +0200 Subject: [PATCH 440/692] Free allocated ffi_types in g_callable_info_free_closure() g_callable_info_prepare_closure() allocates memory for the argument types in the ffi_cif, so we need to free it. https://bugzilla.gnome.org/show_bug.cgi?id=652954 --- girffi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/girffi.c b/girffi.c index b7c1ceae2..b5d359732 100644 --- a/girffi.c +++ b/girffi.c @@ -366,5 +366,6 @@ g_callable_info_free_closure (GICallableInfo *callable_info, { GIClosureWrapper *wrapper = (GIClosureWrapper *)closure; + g_free (wrapper->ffi_closure.cif->arg_types); ffi_closure_free (wrapper->writable_self); } From a9b2dfd09a632161e8f4d9ec353286cacd7c8dcd Mon Sep 17 00:00:00 2001 From: Jasper Lievisse Adriaanse Date: Tue, 21 Jun 2011 13:44:56 +0200 Subject: [PATCH 441/692] Rename ALIGN to GI_ALIGN to prevent redefining this macro on some platforms https://bugzilla.gnome.org/show_bug.cgi?id=652625 --- giroffsets.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/giroffsets.c b/giroffsets.c index 7b30809c2..2c84b7071 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -350,7 +350,7 @@ get_field_size_alignment (GIrTypelibBuild *build, return success; } -#define ALIGN(n, align) (((n) + (align) - 1) & ~((align) - 1)) +#define GI_ALIGN(n, align) (((n) + (align) - 1) & ~((align) - 1)) static gboolean compute_struct_field_offsets (GIrTypelibBuild *build, @@ -382,7 +382,7 @@ compute_struct_field_offsets (GIrTypelibBuild *build, if (get_field_size_alignment (build, field, node, &member_size, &member_alignment)) { - size = ALIGN (size, member_alignment); + size = GI_ALIGN (size, member_alignment); alignment = MAX (alignment, member_alignment); field->offset = size; size += member_size; @@ -396,14 +396,14 @@ compute_struct_field_offsets (GIrTypelibBuild *build, } else if (member->type == G_IR_NODE_CALLBACK) { - size = ALIGN (size, ffi_type_pointer.alignment); + size = GI_ALIGN (size, ffi_type_pointer.alignment); alignment = MAX (alignment, ffi_type_pointer.alignment); size += ffi_type_pointer.size; } } /* Structs are tail-padded out to a multiple of their alignment */ - size = ALIGN (size, alignment); + size = GI_ALIGN (size, alignment); if (!have_error) { @@ -459,7 +459,7 @@ compute_union_field_offsets (GIrTypelibBuild *build, } /* Unions are tail-padded out to a multiple of their alignment */ - size = ALIGN (size, alignment); + size = GI_ALIGN (size, alignment); if (!have_error) { From 2c0d8843305e882b395f407b157e5c1c751e8fc8 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Fri, 12 Aug 2011 11:10:06 -0400 Subject: [PATCH 442/692] girepository: fix some doc comment syntax --- girepository.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/girepository.c b/girepository.c index f7f55e5a6..c5c464bd7 100644 --- a/girepository.c +++ b/girepository.c @@ -382,7 +382,7 @@ register_internal (GIRepository *repository, * form namespace-version. * * Note: The namespace must have already been loaded using a function - * such as #g_irepository_require before calling this function. + * such as g_irepository_require() before calling this function. * * Returns: (transfer full): Zero-terminated string array of versioned dependencies */ @@ -447,7 +447,7 @@ g_irepository_load_typelib (GIRepository *repository, * Check whether a particular namespace (and optionally, a specific * version thereof) is currently loaded. This function is likely to * only be useful in unusual circumstances; in order to act upon - * metadata in the namespace, you should call #g_irepository_require + * metadata in the namespace, you should call g_irepository_require() * instead which will ensure the namespace is loaded, and return as * quickly as this function will if it has already been loaded. * @@ -648,7 +648,7 @@ g_irepository_find_by_gtype (GIRepository *repository, * * Searches for a particular entry in a namespace. Before calling * this function for a particular namespace, you must call - * #g_irepository_require once to load the namespace, or otherwise + * g_irepository_require() once to load the namespace, or otherwise * ensure the namespace has already been loaded. * * Returns: (transfer full): #GIBaseInfo representing metadata about @name, or %NULL @@ -723,7 +723,7 @@ g_irepository_get_loaded_namespaces (GIRepository *repository) * namespace @namespace_. * * Note: The namespace must have already been loaded using a function - * such as #g_irepository_require before calling this function. + * such as g_irepository_require() before calling this function. * * Returns: Loaded version */ @@ -757,7 +757,7 @@ g_irepository_get_version (GIRepository *repository, * return %NULL. * * Note: The namespace must have already been loaded using a function - * such as #g_irepository_require before calling this function. + * such as g_irepository_require() before calling this function. * * Returns: Full path to shared library, or %NULL if none associated */ @@ -793,7 +793,7 @@ g_irepository_get_shared_library (GIRepository *repository, * starts with this prefix, as well each #GType in the library. * * Note: The namespace must have already been loaded using a function - * such as #g_irepository_require before calling this function. + * such as g_irepository_require() before calling this function. * * Returns: C namespace prefix, or %NULL if none associated */ From f9ebb4e99d672f7f48debbefc203c8d431a63cd4 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 19 May 2011 16:12:03 -0400 Subject: [PATCH 443/692] Deprecate ErrorDomain The previous ErrorDomain blob was never actually scanned or used, and it was kind of a lame API conceptually. To keep some compatibility, rather than removing the enumeration values, rename them to _INVALID, and don't bump the typelib version. This should in theory allow a new libgirepository to read an old typelib. Based on a patch from Colin Walters https://bugzilla.gnome.org/show_bug.cgi?id=602516 --- gibaseinfo.c | 5 +-- gierrordomaininfo.c | 95 -------------------------------------------- gierrordomaininfo.h | 44 -------------------- gifieldinfo.c | 4 +- girepository.c | 2 - girepository.h | 1 - girmodule.c | 2 +- girnode.c | 70 ++------------------------------ girnode.h | 15 +------ girparser.c | 81 ++----------------------------------- girwriter.c | 40 ------------------- gitypeinfo.c | 69 -------------------------------- gitypeinfo.h | 3 -- gitypelib-internal.h | 29 ++------------ gitypelib.c | 40 ------------------- gitypes.h | 10 +---- 16 files changed, 17 insertions(+), 493 deletions(-) delete mode 100644 gierrordomaininfo.c delete mode 100644 gierrordomaininfo.h diff --git a/gibaseinfo.c b/gibaseinfo.c index 057cde729..bfb774360 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -202,7 +202,6 @@ _g_type_info_init (GIBaseInfo *info, * +----GIArgInfo * +----GICallableInfo * +----GIConstantInfo - * +----GIErrorDomainInfo * +----GIFieldInfo * +----GIPropertyInfo * +----GIRegisteredTypeInfo @@ -299,7 +298,7 @@ g_base_info_get_name (GIBaseInfo *info) case GI_INFO_TYPE_OBJECT: case GI_INFO_TYPE_INTERFACE: case GI_INFO_TYPE_CONSTANT: - case GI_INFO_TYPE_ERROR_DOMAIN: + case GI_INFO_TYPE_INVALID_0: case GI_INFO_TYPE_UNION: { CommonBlob *blob = (CommonBlob *)&rinfo->typelib->data[rinfo->offset]; @@ -421,7 +420,7 @@ g_base_info_is_deprecated (GIBaseInfo *info) case GI_INFO_TYPE_OBJECT: case GI_INFO_TYPE_INTERFACE: case GI_INFO_TYPE_CONSTANT: - case GI_INFO_TYPE_ERROR_DOMAIN: + case GI_INFO_TYPE_INVALID_0: { CommonBlob *blob = (CommonBlob *)&rinfo->typelib->data[rinfo->offset]; diff --git a/gierrordomaininfo.c b/gierrordomaininfo.c deleted file mode 100644 index 86e40c59b..000000000 --- a/gierrordomaininfo.c +++ /dev/null @@ -1,95 +0,0 @@ -/* GObject introspection: ErrorDomain implementation - * - * Copyright (C) 2005 Matthias Clasen - * Copyright (C) 2008,2009 Red Hat, Inc. - * - * 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 "girepository-private.h" -#include "gitypelib-internal.h" - -/** - * SECTION:gierrordomaininfo - * @Short_description: Struct representing an error domain - * @Title: GIErrorDomainInfo - * - * A GIErrorDomainInfo struct represents a domain of a #GError. - * An error domain is associated with a #GQuark and contains a pointer - * to an enum with all the error codes. - * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GIErrorDomainInfo - * - * - */ - -/** - * g_error_domain_info_get_quark: - * @info: a #GIErrorDomainInfo - * - * Obtain a string representing the quark for this error domain. - * %NULL will be returned if the type tag is wrong or if a quark is - * missing in the typelib. - * - * Returns: the quark represented as a string or %NULL - */ -const gchar * -g_error_domain_info_get_quark (GIErrorDomainInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ErrorDomainBlob *blob; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_ERROR_DOMAIN_INFO (info), NULL); - - blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset]; - - return g_typelib_get_string (rinfo->typelib, blob->get_quark); -} - -/** - * g_error_domain_info_get_codes: - * @info: a #GIErrorDomainInfo - * - * Obtain the enum containing all the error codes for this error domain. - * The return value will have a #GIInfoType of %GI_INFO_TYPE_ERROR_DOMAIN - * - * Returns: (transfer full): the error domain or %NULL if type tag is wrong, - * free the struct with g_base_info_unref() when done. - */ -GIInterfaceInfo * -g_error_domain_info_get_codes (GIErrorDomainInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ErrorDomainBlob *blob; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_ERROR_DOMAIN_INFO (info), NULL); - - blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset]; - - return (GIInterfaceInfo *) _g_info_from_entry (rinfo->repository, - rinfo->typelib, blob->error_codes); -} - - diff --git a/gierrordomaininfo.h b/gierrordomaininfo.h deleted file mode 100644 index 9c2968bc1..000000000 --- a/gierrordomaininfo.h +++ /dev/null @@ -1,44 +0,0 @@ -/* GObject introspection: Error Domain - * - * Copyright (C) 2005 Matthias Clasen - * Copyright (C) 2008,2009 Red Hat, Inc. - * - * 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 __GIERRORDOMAININFO_H__ -#define __GIERRORDOMAININFO_H__ - -#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -G_BEGIN_DECLS - -#define GI_IS_ERROR_DOMAIN_INFO(info) \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ERROR_DOMAIN) - -const gchar * g_error_domain_info_get_quark (GIErrorDomainInfo *info); -GIInterfaceInfo * g_error_domain_info_get_codes (GIErrorDomainInfo *info); - - -G_END_DECLS - - -#endif /* __GIERRORDOMAININFO_H__ */ - diff --git a/gifieldinfo.c b/gifieldinfo.c index 17491a80a..41976855d 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -322,7 +322,7 @@ g_field_info_get_field (GIFieldInfo *field_info, case GI_INFO_TYPE_INTERFACE: case GI_INFO_TYPE_FUNCTION: case GI_INFO_TYPE_CONSTANT: - case GI_INFO_TYPE_ERROR_DOMAIN: + case GI_INFO_TYPE_INVALID_0: case GI_INFO_TYPE_VALUE: case GI_INFO_TYPE_SIGNAL: case GI_INFO_TYPE_PROPERTY: @@ -498,7 +498,7 @@ g_field_info_set_field (GIFieldInfo *field_info, case GI_INFO_TYPE_INTERFACE: case GI_INFO_TYPE_FUNCTION: case GI_INFO_TYPE_CONSTANT: - case GI_INFO_TYPE_ERROR_DOMAIN: + case GI_INFO_TYPE_INVALID_0: case GI_INFO_TYPE_VALUE: case GI_INFO_TYPE_SIGNAL: case GI_INFO_TYPE_PROPERTY: diff --git a/girepository.c b/girepository.c index c5c464bd7..1afba0c80 100644 --- a/girepository.c +++ b/girepository.c @@ -1466,8 +1466,6 @@ g_info_type_to_string (GIInfoType type) return "interface"; case GI_INFO_TYPE_CONSTANT: return "constant"; - case GI_INFO_TYPE_ERROR_DOMAIN: - return "error domain"; case GI_INFO_TYPE_UNION: return "union"; case GI_INFO_TYPE_VALUE: diff --git a/girepository.h b/girepository.h index f14b1ad77..fddcf8c16 100644 --- a/girepository.h +++ b/girepository.h @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/girmodule.c b/girmodule.c index 49daaa620..f438a193b 100644 --- a/girmodule.c +++ b/girmodule.c @@ -415,7 +415,7 @@ _g_ir_module_build_typelib (GIrModule *module) header->field_blob_size = sizeof (FieldBlob); header->value_blob_size = sizeof (ValueBlob); header->constant_blob_size = sizeof (ConstantBlob); - header->error_domain_blob_size = sizeof (ErrorDomainBlob); + header->error_domain_blob_size = 16; /* No longer used */ header->attribute_blob_size = sizeof (AttributeBlob); header->signature_blob_size = sizeof (SignatureBlob); header->enum_blob_size = sizeof (EnumBlob); diff --git a/girnode.c b/girnode.c index a56471e52..1c51bfd4b 100644 --- a/girnode.c +++ b/girnode.c @@ -101,8 +101,6 @@ _g_ir_node_type_to_string (GIrNodeTypeId type) return "value"; case G_IR_NODE_CONSTANT: return "constant"; - case G_IR_NODE_ERROR_DOMAIN: - return "error-domain"; case G_IR_NODE_XREF: return "xref"; case G_IR_NODE_UNION: @@ -175,10 +173,6 @@ _g_ir_node_new (GIrNodeTypeId type, node = g_malloc0 (sizeof (GIrNodeConstant)); break; - case G_IR_NODE_ERROR_DOMAIN: - node = g_malloc0 (sizeof (GIrNodeErrorDomain)); - break; - case G_IR_NODE_XREF: node = g_malloc0 (sizeof (GIrNodeXRef)); break; @@ -379,16 +373,6 @@ _g_ir_node_free (GIrNode *node) } break; - case G_IR_NODE_ERROR_DOMAIN: - { - GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node; - - g_free (node->name); - g_free (domain->getquark); - g_free (domain->codes); - } - break; - case G_IR_NODE_XREF: { GIrNodeXRef *xref = (GIrNodeXRef *)node; @@ -535,10 +519,6 @@ _g_ir_node_get_size (GIrNode *node) size = sizeof (ConstantBlob); break; - case G_IR_NODE_ERROR_DOMAIN: - size = sizeof (ErrorDomainBlob); - break; - case G_IR_NODE_XREF: size = 0; break; @@ -665,16 +645,7 @@ _g_ir_node_get_full_size_internal (GIrNode *parent, size += _g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type2); break; case GI_TYPE_TAG_ERROR: - { - gint n; - - if (type->errors) - n = g_strv_length (type->errors); - else - n = 0; - - size += sizeof (ErrorTypeBlob) + 2 * (n + n % 2); - } + size += sizeof (ErrorTypeBlob); break; default: g_error ("Unknown type tag %d\n", type->tag); @@ -844,16 +815,6 @@ _g_ir_node_get_full_size_internal (GIrNode *parent, } break; - case G_IR_NODE_ERROR_DOMAIN: - { - GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node; - - size = sizeof (ErrorDomainBlob); - size += ALIGN_VALUE (strlen (node->name) + 1, 4); - size += ALIGN_VALUE (strlen (domain->getquark) + 1, 4); - } - break; - case G_IR_NODE_XREF: { GIrNodeXRef *xref = (GIrNodeXRef *)node; @@ -935,7 +896,7 @@ _g_ir_node_can_have_member (GIrNode *node) case G_IR_NODE_ENUM: case G_IR_NODE_FLAGS: case G_IR_NODE_CONSTANT: - case G_IR_NODE_ERROR_DOMAIN: + case G_IR_NODE_INVALID_0: case G_IR_NODE_PARAM: case G_IR_NODE_TYPE: case G_IR_NODE_PROPERTY: @@ -1559,21 +1520,14 @@ _g_ir_node_build_typelib (GIrNode *node, case GI_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; + blob->n_domains = 0; - *offset2 = ALIGN_VALUE (*offset2 + G_STRUCT_OFFSET (ErrorTypeBlob, domains) - + 2 * blob->n_domains, 4); - for (i = 0; i < blob->n_domains; i++) - blob->domains[i] = find_entry (build, type->errors[i]); + *offset2 += sizeof (ErrorTypeBlob); } break; @@ -2234,22 +2188,6 @@ _g_ir_node_build_typelib (GIrNode *node, } break; - case G_IR_NODE_ERROR_DOMAIN: - { - GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node; - ErrorDomainBlob *blob = (ErrorDomainBlob *)&data[*offset]; - *offset += sizeof (ErrorDomainBlob); - - blob->blob_type = BLOB_TYPE_ERROR_DOMAIN; - blob->deprecated = domain->deprecated; - blob->reserved = 0; - blob->name = _g_ir_write_string (node->name, strings, data, offset2); - blob->get_quark = _g_ir_write_string (domain->getquark, strings, data, offset2); - blob->error_codes = find_entry (build, domain->codes); - blob->reserved2 = 0; - } - break; - case G_IR_NODE_CONSTANT: { GIrNodeConstant *constant = (GIrNodeConstant *)node; diff --git a/girnode.h b/girnode.h index 1f9102fd2..fb2616b1e 100644 --- a/girnode.h +++ b/girnode.h @@ -41,7 +41,6 @@ typedef struct _GIrNodeEnum GIrNodeEnum; typedef struct _GIrNodeBoxed GIrNodeBoxed; typedef struct _GIrNodeStruct GIrNodeStruct; typedef struct _GIrNodeConstant GIrNodeConstant; -typedef struct _GIrNodeErrorDomain GIrNodeErrorDomain; typedef struct _GIrNodeXRef GIrNodeXRef; typedef struct _GIrNodeUnion GIrNodeUnion; @@ -57,7 +56,7 @@ typedef enum G_IR_NODE_OBJECT = 7, G_IR_NODE_INTERFACE = 8, G_IR_NODE_CONSTANT = 9, - G_IR_NODE_ERROR_DOMAIN = 10, + G_IR_NODE_INVALID_0 = 10, /* DELETED - used to be ERROR_DOMAIN */ G_IR_NODE_UNION = 11, G_IR_NODE_PARAM = 12, G_IR_NODE_TYPE = 13, @@ -343,18 +342,6 @@ struct _GIrNodeUnion }; -struct _GIrNodeErrorDomain -{ - GIrNode node; - - gboolean deprecated; - - gchar *name; - gchar *getquark; - gchar *codes; -}; - - GIrNode * _g_ir_node_new (GIrNodeTypeId type, GIrModule *module); void _g_ir_node_free (GIrNode *node); diff --git a/girparser.c b/girparser.c index 02c044279..4e5527259 100644 --- a/girparser.c +++ b/girparser.c @@ -68,13 +68,12 @@ typedef enum STATE_BOXED_FIELD, STATE_STRUCT, STATE_STRUCT_FIELD, - STATE_ERRORDOMAIN, /* 25 */ - STATE_UNION, + STATE_UNION, /* 25 */ STATE_UNION_FIELD, STATE_NAMESPACE_CONSTANT, STATE_CLASS_CONSTANT, - STATE_INTERFACE_CONSTANT, /* 30 */ - STATE_ALIAS, + STATE_INTERFACE_CONSTANT, + STATE_ALIAS, /* 30 */ STATE_TYPE, STATE_ATTRIBUTE, STATE_DOC, @@ -1614,68 +1613,6 @@ start_constant (GMarkupParseContext *context, return TRUE; } -static gboolean -start_errordomain (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseContext *ctx, - GError **error) -{ - const gchar *name; - const gchar *getquark; - const gchar *codes; - const gchar *deprecated; - GIrNodeErrorDomain *domain; - - if (!(strcmp (element_name, "errordomain") == 0 && - ctx->state == STATE_NAMESPACE)) - return FALSE; - - if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_ERRORDOMAIN)) - return TRUE; - - - name = find_attribute ("name", attribute_names, attribute_values); - getquark = find_attribute ("get-quark", attribute_names, attribute_values); - codes = find_attribute ("codes", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "name"); - return FALSE; - } - else if (getquark == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "getquark"); - return FALSE; - } - else if (codes == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "codes"); - return FALSE; - } - - domain = (GIrNodeErrorDomain *) _g_ir_node_new (G_IR_NODE_ERROR_DOMAIN, - ctx->current_module); - - ((GIrNode *)domain)->name = g_strdup (name); - domain->getquark = g_strdup (getquark); - domain->codes = g_strdup (codes); - - if (deprecated) - domain->deprecated = TRUE; - else - domain->deprecated = FALSE; - - push_node (ctx, (GIrNode *) domain); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, domain); - - return TRUE; -} - static gboolean start_interface (GMarkupParseContext *context, const gchar *element_name, @@ -2788,10 +2725,6 @@ start_element_handler (GMarkupParseContext *context, attribute_names, attribute_values, ctx, error)) goto out; - else if (start_errordomain (context, element_name, - attribute_names, attribute_values, - ctx, error)) - goto out; break; case 'f': @@ -3290,14 +3223,6 @@ end_element_handler (GMarkupParseContext *context, } break; - case STATE_ERRORDOMAIN: - if (require_end_element (context, ctx, "errordomain", element_name, error)) - { - pop_node (ctx); - state_switch (ctx, STATE_NAMESPACE); - } - break; - case STATE_INTERFACE_PROPERTY: if (strcmp ("type", element_name) == 0) break; diff --git a/girwriter.c b/girwriter.c index f6ab34ebd..2cdc9a11f 100644 --- a/girwriter.c +++ b/girwriter.c @@ -212,7 +212,6 @@ write_type_info (const gchar *namespace, Xml *file) { gint tag; - gint i; GITypeInfo *type; gboolean is_pointer; @@ -329,24 +328,8 @@ write_type_info (const gchar *namespace, } else if (tag == GI_TYPE_TAG_ERROR) { - gint n; - xml_start_element (file, "type"); xml_printf (file, " name=\"GLib.Error\""); - - n = g_type_info_get_n_error_domains (info); - if (n > 0) - { - for (i = 0; i < n; i++) - { - GIErrorDomainInfo *ed = g_type_info_get_error_domain (info, i); - xml_start_element (file, "type"); - write_type_name_attribute (namespace, (GIBaseInfo *)ed, "name", file); - xml_end_element (file, "type"); - g_base_info_unref ((GIBaseInfo *)ed); - } - } - xml_end_element (file, "type"); } else @@ -1193,25 +1176,6 @@ write_interface_info (const gchar *namespace, xml_end_element (file, "interface"); } -static void -write_error_domain_info (const gchar *namespace, - GIErrorDomainInfo *info, - Xml *file) -{ - GIBaseInfo *enum_; - const gchar *name, *quark; - - name = g_base_info_get_name ((GIBaseInfo *)info); - quark = g_error_domain_info_get_quark (info); - enum_ = (GIBaseInfo *)g_error_domain_info_get_codes (info); - xml_start_element (file, "errordomain"); - xml_printf (file, " name=\"%s\" get-quark=\"%s\"", - name, quark); - write_type_name_attribute (namespace, enum_, "codes", file); - xml_end_element (file, "errordomain"); - g_base_info_unref (enum_); -} - static void write_union_info (const gchar *namespace, GIUnionInfo *info, @@ -1411,10 +1375,6 @@ gir_writer_write (const char *filename, write_interface_info (ns, (GIInterfaceInfo *)info, xml); break; - case GI_INFO_TYPE_ERROR_DOMAIN: - write_error_domain_info (ns, (GIErrorDomainInfo *)info, xml); - break; - default: g_error ("unknown info type %d\n", g_base_info_get_type (info)); } diff --git a/gitypeinfo.c b/gitypeinfo.c index 1bc9b0a13..5864f82fe 100644 --- a/gitypeinfo.c +++ b/gitypeinfo.c @@ -340,72 +340,3 @@ g_type_info_get_array_type (GITypeInfo *info) return -1; } - -/** - * g_type_info_get_n_error_domains: - * @info: a #GITypeInfo - * - * Obtain the number of error domains for this type. The type tag - * must be a #GI_TYPE_TAG_ERROR or -1 will be returned. - * - * Returns: number of error domains or -1 - */ -gint -g_type_info_get_n_error_domains (GITypeInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type; - - g_return_val_if_fail (info != NULL, 0); - g_return_val_if_fail (GI_IS_TYPE_INFO (info), 0); - - type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) - { - ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->tag == GI_TYPE_TAG_ERROR) - return blob->n_domains; - } - - return 0; -} - -/** - * g_type_info_get_error_domain: - * @info: a #GITypeInfo - * @n: index of error domain - * - * Obtain the error domains at index @n for this type. The type tag - * must be a #GI_TYPE_TAG_ERROR or -1 will be returned. - * - * Returns: (transfer full): the error domain or %NULL if type tag is wrong, - * free the struct with g_base_info_unref() when done. - */ -GIErrorDomainInfo * -g_type_info_get_error_domain (GITypeInfo *info, - gint n) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_TYPE_INFO (info), NULL); - - type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) - { - ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->tag == GI_TYPE_TAG_ERROR) - return (GIErrorDomainInfo *) _g_info_from_entry (rinfo->repository, - rinfo->typelib, - blob->domains[n]); - } - - return NULL; -} - - diff --git a/gitypeinfo.h b/gitypeinfo.h index 5c4fc8351..56e7309aa 100644 --- a/gitypeinfo.h +++ b/gitypeinfo.h @@ -48,9 +48,6 @@ gint g_type_info_get_array_fixed_size(GITypeInfo *info); gboolean g_type_info_is_zero_terminated (GITypeInfo *info); GIArrayType g_type_info_get_array_type (GITypeInfo *info); -gint g_type_info_get_n_error_domains (GITypeInfo *info); -GIErrorDomainInfo *g_type_info_get_error_domain (GITypeInfo *info, - gint n); G_END_DECLS diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 593c9876c..2bda8d9d0 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -57,7 +57,7 @@ G_BEGIN_DECLS * directory ::= list of entries * * entry ::= blob type, name, namespace, offset - * blob ::= function|callback|struct|boxed|enum|flags|object|interface|constant|errordomain|union + * blob ::= function|callback|struct|boxed|enum|flags|object|interface|constant|union * attributes ::= list of attributes, sorted by offset * attribute ::= offset, key, value * attributedata ::= string data for attributes @@ -156,7 +156,6 @@ Changes since 0.1: * @BLOB_TYPE_OBJECT: An #ObjectBlob * @BLOB_TYPE_INTERFACE: An #InterfaceBlob * @BLOB_TYPE_CONSTANT: A #ConstantBlob - * @BLOB_TYPE_ERROR_DOMAIN: A #ErrorDomainBlob * @BLOB_TYPE_UNION: A #UnionBlob * * The integral value of this enumeration appears in each "Blob" @@ -173,7 +172,7 @@ typedef enum { BLOB_TYPE_OBJECT, BLOB_TYPE_INTERFACE, BLOB_TYPE_CONSTANT, - BLOB_TYPE_ERROR_DOMAIN, + BLOB_TYPE_INVALID_0, /* DELETED - used to be ErrorDomain */ BLOB_TYPE_UNION } GTypelibBlobType; @@ -624,8 +623,6 @@ typedef struct { /** * ErrorTypeBlob: - * @n_domains: The number of domains to follow - * @domains: Indices of the directory entries for the error domains */ typedef struct { guint8 pointer :1; @@ -633,31 +630,11 @@ typedef struct { guint8 tag :5; guint8 reserved2; - guint16 n_domains; + guint16 n_domains; /* Must be 0 */ guint16 domains[]; } ErrorTypeBlob; -/** - * ErrorDomainBlob: - * @get_quark: The symbol name of the function which must be called to obtain the - * GQuark for the error domain. - * @error_codes: Index of the InterfaceBlob describing the enumeration which lists - * the possible error codes. - */ -typedef struct { - guint16 blob_type; /* 10 */ - - guint16 deprecated : 1; - guint16 reserved :15; - - guint32 name; - - guint32 get_quark; - guint16 error_codes; - guint16 reserved2; -} ErrorDomainBlob; - /** * ValueBlob: * @deprecated: Whether this value is deprecated diff --git a/gitypelib.c b/gitypelib.c index 6d1333ba0..3869a6d25 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -284,7 +284,6 @@ g_typelib_check_sanity (void) CHECK_SIZE (ArrayTypeBlob, 8); CHECK_SIZE (ParamTypeBlob, 4); CHECK_SIZE (ErrorTypeBlob, 4); - CHECK_SIZE (ErrorDomainBlob, 16); CHECK_SIZE (ValueBlob, 12); CHECK_SIZE (FieldBlob, 16); CHECK_SIZE (RegisteredTypeBlob, 16); @@ -446,7 +445,6 @@ validate_header_basic (const guint8 *memory, header->field_blob_size != sizeof (FieldBlob) || header->value_blob_size != sizeof (ValueBlob) || header->constant_blob_size != sizeof (ConstantBlob) || - header->error_domain_blob_size != sizeof (ErrorDomainBlob) || header->attribute_blob_size != sizeof (AttributeBlob) || header->signature_blob_size != sizeof (SignatureBlob) || header->enum_blob_size != sizeof (EnumBlob) || @@ -607,8 +605,6 @@ validate_error_type_blob (GITypelib *typelib, { ErrorTypeBlob *blob; Header *header; - gint i; - DirEntry *entry; blob = (ErrorTypeBlob*)&typelib->data[offset]; @@ -623,30 +619,6 @@ validate_error_type_blob (GITypelib *typelib, return FALSE; } - for (i = 0; i < blob->n_domains; i++) - { - if (blob->domains[i] == 0 || blob->domains[i] > header->n_entries) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid directory index %d", blob->domains[i]); - return FALSE; - } - - entry = g_typelib_get_dir_entry (typelib, blob->domains[i]); - - if (entry->blob_type != BLOB_TYPE_ERROR_DOMAIN && - (entry->local || entry->blob_type != BLOB_TYPE_INVALID)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Wrong blob type"); - return FALSE; - } - } - return TRUE; } @@ -1824,14 +1796,6 @@ validate_interface_blob (ValidateContext *ctx, return TRUE; } -static gboolean -validate_errordomain_blob (GITypelib *typelib, - guint32 offset, - GError **error) -{ - return TRUE; -} - static gboolean validate_union_blob (GITypelib *typelib, guint32 offset, @@ -1891,10 +1855,6 @@ validate_blob (ValidateContext *ctx, if (!validate_constant_blob (typelib, offset, error)) return FALSE; break; - case BLOB_TYPE_ERROR_DOMAIN: - if (!validate_errordomain_blob (typelib, offset, error)) - return FALSE; - break; case BLOB_TYPE_UNION: if (!validate_union_blob (typelib, offset, error)) return FALSE; diff --git a/gitypes.h b/gitypes.h index d15b121a3..cbe43168b 100644 --- a/gitypes.h +++ b/gitypes.h @@ -150,13 +150,6 @@ typedef GIBaseInfo GIArgInfo; */ typedef GIBaseInfo GITypeInfo; -/** - * GIErrorDomainInfo: - * - * Represents a #GError error domain. - */ -typedef GIBaseInfo GIErrorDomainInfo; - /** * GIUnresolvedInfo: * @@ -202,7 +195,6 @@ typedef union _GIArgument GIArgument; * @GI_INFO_TYPE_OBJECT: object, see #GIObjectInfo * @GI_INFO_TYPE_INTERFACE: interface, see #GIInterfaceInfo * @GI_INFO_TYPE_CONSTANT: contant, see #GIConstantInfo - * @GI_INFO_TYPE_ERROR_DOMAIN: error domain for a #GError, see #GIErrorDomainInfo * @GI_INFO_TYPE_UNION: union, see #GIUnionInfo * @GI_INFO_TYPE_VALUE: enum value, see #GIValueInfo * @GI_INFO_TYPE_SIGNAL: signal, see #GISignalInfo @@ -228,7 +220,7 @@ typedef enum GI_INFO_TYPE_OBJECT, GI_INFO_TYPE_INTERFACE, GI_INFO_TYPE_CONSTANT, - GI_INFO_TYPE_ERROR_DOMAIN, /* 10 */ + GI_INFO_TYPE_INVALID_0, /* 10 */ /** DELETED - used to be ERROR_DOMAIN **/ GI_INFO_TYPE_UNION, GI_INFO_TYPE_VALUE, GI_INFO_TYPE_SIGNAL, From 57554d4b2d7253efd0dc8ec7dcf0855c76b6b0e6 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 19 May 2011 16:21:13 -0400 Subject: [PATCH 444/692] Switch to storing string form of error quarks Instead of storing the name of the function to call to get the error quark, store the string form of the error quark, which we derive from the introspection binary during scanning. Update EnumBlob and GIEnumInfo to include the new information. This will allow determining a back-mapping from error quark to error domain without having to dlsym() and call all the known error quark functions. Based on earlier patches from Owen Taylor and Maxim Ermilov. https://bugzilla.gnome.org/show_bug.cgi?id=602516 --- gdump.c | 83 +++++++++++++++++++++++++++++++++++--------- gienuminfo.c | 17 +++++++++ gienuminfo.h | 1 + girnode.c | 7 ++++ girnode.h | 1 + girparser.c | 4 +++ girwriter.c | 4 +++ gitypelib-internal.h | 4 ++- 8 files changed, 104 insertions(+), 17 deletions(-) diff --git a/gdump.c b/gdump.c index cb6e74197..e607f3237 100644 --- a/gdump.c +++ b/gdump.c @@ -70,6 +70,7 @@ goutput_write (GOutputStream *out, const char *str) } typedef GType (*GetTypeFunc)(void); +typedef GQuark (*ErrorQuarkFunc)(void); static GType invoke_get_type (GModule *self, const char *symbol, GError **error) @@ -97,6 +98,23 @@ invoke_get_type (GModule *self, const char *symbol, GError **error) return ret; } +static GQuark +invoke_error_quark (GModule *self, const char *symbol, GError **error) +{ + ErrorQuarkFunc sym; + + if (!g_module_symbol (self, symbol, (void**)&sym)) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Failed to find symbol '%s'", symbol); + return G_TYPE_INVALID; + } + + return sym (); +} + static void dump_properties (GType type, GOutputStream *out) { @@ -365,6 +383,13 @@ dump_type (GType type, const char *symbol, GOutputStream *out) } } +static void +dump_error_quark (GQuark quark, const char *symbol, GOutputStream *out) +{ + escaped_printf (out, " \n", + symbol, g_quark_to_string (quark)); +} + /** * g_irepository_dump: * @arg: Comma-separated pair of input and output filenames @@ -437,29 +462,55 @@ g_irepository_dump (const char *arg, GError **error) { gsize len; char *line = g_data_input_stream_read_line (in, &len, NULL, NULL); - GType type; + const char *function; if (line == NULL || *line == '\0') - { - g_free (line); - break; - } + { + g_free (line); + break; + } g_strchomp (line); - type = invoke_get_type (self, line, error); - if (type == G_TYPE_INVALID) - { - caught_error = TRUE; - g_free (line); - break; - } + if (strncmp (line, "get-type:", strlen ("get-type:")) == 0) + { + GType type; - if (g_hash_table_lookup (output_types, (gpointer) type)) - goto next; - g_hash_table_insert (output_types, (gpointer) type, (gpointer) type); + function = line + strlen ("get-type:"); + + type = invoke_get_type (self, function, error); + + if (type == G_TYPE_INVALID) + { + g_printerr ("Invalid GType function: '%s'\n", function); + caught_error = TRUE; + g_free (line); + break; + } + + if (g_hash_table_lookup (output_types, (gpointer) type)) + goto next; + g_hash_table_insert (output_types, (gpointer) type, (gpointer) type); + + dump_type (type, function, G_OUTPUT_STREAM (output)); + } + else if (strncmp (line, "error-quark:", strlen ("error-quark:")) == 0) + { + GQuark quark; + function = line + strlen ("error-quark:"); + quark = invoke_error_quark (self, function, error); + + if (quark == 0) + { + g_printerr ("Invalid error quark function: '%s'\n", function); + caught_error = TRUE; + g_free (line); + break; + } + + dump_error_quark (quark, function, G_OUTPUT_STREAM (output)); + } - dump_type (type, line, G_OUTPUT_STREAM (output)); next: g_free (line); diff --git a/gienuminfo.c b/gienuminfo.c index 062f3abf2..338a46ee0 100644 --- a/gienuminfo.c +++ b/gienuminfo.c @@ -66,6 +66,23 @@ g_enum_info_get_n_values (GIEnumInfo *info) return blob->n_values; } +const gchar * +g_enum_info_get_error_domain (GIEnumInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + EnumBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_ENUM_INFO (info), 0); + + blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->error_domain) + return g_typelib_get_string (rinfo->typelib, blob->error_domain); + else + return NULL; +} + /** * g_enum_info_get_value: * @info: a #GIEnumInfo diff --git a/gienuminfo.h b/gienuminfo.h index 6b24fe7ef..fc0f3c842 100644 --- a/gienuminfo.h +++ b/gienuminfo.h @@ -41,6 +41,7 @@ gint g_enum_info_get_n_values (GIEnumInfo *info); GIValueInfo * g_enum_info_get_value (GIEnumInfo *info, gint n); GITypeTag g_enum_info_get_storage_type (GIEnumInfo *info); +const gchar * g_enum_info_get_error_domain (GIEnumInfo *info); gint64 g_value_info_get_value (GIValueInfo *info); diff --git a/girnode.c b/girnode.c index 1c51bfd4b..166ca30a3 100644 --- a/girnode.c +++ b/girnode.c @@ -328,6 +328,7 @@ _g_ir_node_free (GIrNode *node) g_free (node->name); g_free (enum_->gtype_name); g_free (enum_->gtype_init); + g_free (enum_->error_domain); for (l = enum_->values; l; l = l->next) _g_ir_node_free ((GIrNode *)l->data); @@ -712,6 +713,8 @@ _g_ir_node_get_full_size_internal (GIrNode *parent, size += ALIGN_VALUE (strlen (enum_->gtype_name) + 1, 4); size += ALIGN_VALUE (strlen (enum_->gtype_init) + 1, 4); } + if (enum_->error_domain) + size += ALIGN_VALUE (strlen (enum_->error_domain) + 1, 4); for (l = enum_->values; l; l = l->next) size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); @@ -2021,6 +2024,10 @@ _g_ir_node_build_typelib (GIrNode *node, blob->gtype_name = 0; blob->gtype_init = 0; } + if (enum_->error_domain) + blob->error_domain = _g_ir_write_string (enum_->error_domain, strings, data, offset2); + else + blob->error_domain = 0; blob->n_values = 0; blob->reserved2 = 0; diff --git a/girnode.h b/girnode.h index fb2616b1e..6e03821ba 100644 --- a/girnode.h +++ b/girnode.h @@ -285,6 +285,7 @@ struct _GIrNodeEnum gchar *gtype_name; gchar *gtype_init; + gchar *error_domain; GList *values; }; diff --git a/girparser.c b/girparser.c index 4e5527259..c9b7d6292 100644 --- a/girparser.c +++ b/girparser.c @@ -1332,6 +1332,7 @@ start_enum (GMarkupParseContext *context, const gchar *typename; const gchar *typeinit; const gchar *deprecated; + const gchar *error_domain; GIrNodeEnum *enum_; if (!((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) || @@ -1344,6 +1345,7 @@ start_enum (GMarkupParseContext *context, name = find_attribute ("name", attribute_names, attribute_values); typename = find_attribute ("glib:type-name", attribute_names, attribute_values); typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + error_domain = find_attribute ("glib:error-domain", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); if (name == NULL) @@ -1361,6 +1363,8 @@ start_enum (GMarkupParseContext *context, ((GIrNode *)enum_)->name = g_strdup (name); enum_->gtype_name = g_strdup (typename); enum_->gtype_init = g_strdup (typeinit); + enum_->error_domain = g_strdup (error_domain); + if (deprecated) enum_->deprecated = TRUE; else diff --git a/girwriter.c b/girwriter.c index 2cdc9a11f..d9f916c55 100644 --- a/girwriter.c +++ b/girwriter.c @@ -805,6 +805,7 @@ write_enum_info (const gchar *namespace, const gchar *name; const gchar *type_name; const gchar *type_init; + const gchar *error_domain; gboolean deprecated; gint i; @@ -813,6 +814,7 @@ write_enum_info (const gchar *namespace, type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); + error_domain = g_enum_info_get_error_domain (info); if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_ENUM) xml_start_element (file, "enumeration"); @@ -822,6 +824,8 @@ write_enum_info (const gchar *namespace, if (type_init) xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init); + if (error_domain) + xml_printf (file, " glib:error-domain=\"%s\"", error_domain); if (deprecated) xml_printf (file, " deprecated=\"1\""); diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 2bda8d9d0..49fbe4e3e 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -798,6 +798,8 @@ typedef struct { * (will be a signed or unsigned integral type) * @gtype_name: String name of the associated #GType * @gtype_init: String naming the symbol which gets the runtime #GType + * @error_domain: String naming the #GError domain this enum is + * associated with * @n_values: The lengths of the values arrays. * @values: Describes the enum values. */ @@ -817,7 +819,7 @@ typedef struct { guint16 n_values; guint16 reserved2; - guint32 reserved3; + guint32 error_domain; ValueBlob values[]; } EnumBlob; From bf9c31f49c961bff1d27d24ca9d6a2d1a6e882c0 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 19 May 2011 17:46:36 -0400 Subject: [PATCH 445/692] Add g_irepository_find_by_error_domain() Add a method to look up a GIEnumInfo given its associated error quark. Based on a patch from Colin Walters. https://bugzilla.gnome.org/show_bug.cgi?id=602516 --- girepository.c | 83 ++++++++++++++++++++++++++++++++++++++++++++ girepository.h | 2 ++ gitypelib-internal.h | 3 ++ gitypelib.c | 30 ++++++++++++++++ 4 files changed, 118 insertions(+) diff --git a/girepository.c b/girepository.c index 1afba0c80..a2a778d91 100644 --- a/girepository.c +++ b/girepository.c @@ -45,6 +45,7 @@ struct _GIRepositoryPrivate GHashTable *typelibs; /* (string) namespace -> GITypelib */ GHashTable *lazy_typelibs; /* (string) namespace-version -> GITypelib */ GHashTable *info_by_gtype; /* GType -> GIBaseInfo */ + GHashTable *info_by_error_domain; /* GQuark -> GIBaseInfo */ }; G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT); @@ -64,6 +65,10 @@ g_irepository_init (GIRepository *repository) = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) NULL, (GDestroyNotify) g_base_info_unref); + repository->priv->info_by_error_domain + = g_hash_table_new_full (g_direct_hash, g_direct_equal, + (GDestroyNotify) NULL, + (GDestroyNotify) g_base_info_unref); } static void @@ -74,6 +79,7 @@ g_irepository_finalize (GObject *object) g_hash_table_destroy (repository->priv->typelibs); g_hash_table_destroy (repository->priv->lazy_typelibs); g_hash_table_destroy (repository->priv->info_by_gtype); + g_hash_table_destroy (repository->priv->info_by_error_domain); (* G_OBJECT_CLASS (g_irepository_parent_class)->finalize) (G_OBJECT (repository)); } @@ -675,6 +681,83 @@ g_irepository_find_by_name (GIRepository *repository, NULL, typelib, entry->offset); } +typedef struct { + GIRepository *repository; + GQuark domain; + + GITypelib *result_typelib; + DirEntry *result; +} FindByErrorDomainData; + +static void +find_by_error_domain_foreach (gpointer key, + gpointer value, + gpointer datap) +{ + GITypelib *typelib = (GITypelib*)value; + FindByErrorDomainData *data = datap; + + if (data->result != NULL) + return; + + data->result = g_typelib_get_dir_entry_by_error_domain (typelib, data->domain); + if (data->result) + data->result_typelib = typelib; +} + +/** + * g_irepository_find_by_error_domain: + * @repository: (allow-none): A #GIRepository, may be %NULL for the default + * @domain: a #GError domain + * + * Searches for the enum type corresponding to the given #GError + * domain. Before calling this function for a particular namespace, + * you must call g_irepository_require() once to load the namespace, or + * otherwise ensure the namespace has already been loaded. + * + * Returns: (transfer full): #GIEnumInfo representing metadata about @domain's + * enum type, or %NULL + * + * Since: 1.29.17 + */ +GIEnumInfo * +g_irepository_find_by_error_domain (GIRepository *repository, + GQuark domain) +{ + FindByErrorDomainData data; + GIEnumInfo *cached; + + repository = get_repository (repository); + + cached = g_hash_table_lookup (repository->priv->info_by_error_domain, + GUINT_TO_POINTER (domain)); + + if (cached != NULL) + return g_base_info_ref ((GIBaseInfo *)cached); + + data.repository = repository; + data.domain = domain; + data.result_typelib = NULL; + data.result = NULL; + + g_hash_table_foreach (repository->priv->typelibs, find_by_error_domain_foreach, &data); + if (data.result == NULL) + g_hash_table_foreach (repository->priv->lazy_typelibs, find_by_error_domain_foreach, &data); + + if (data.result != NULL) + { + cached = _g_info_new_full (data.result->blob_type, + repository, + NULL, data.result_typelib, data.result->offset); + + g_hash_table_insert (repository->priv->info_by_error_domain, + GUINT_TO_POINTER (domain), + g_base_info_ref (cached)); + return cached; + } + return NULL; +} + static void collect_namespaces (gpointer key, gpointer value, diff --git a/girepository.h b/girepository.h index fddcf8c16..9e99f6e31 100644 --- a/girepository.h +++ b/girepository.h @@ -123,6 +123,8 @@ gint g_irepository_get_n_infos (GIRepository *repository, GIBaseInfo * g_irepository_get_info (GIRepository *repository, const gchar *namespace_, gint index); +GIEnumInfo * g_irepository_find_by_error_domain (GIRepository *repository, + GQuark domain); const gchar * g_irepository_get_typelib_path (GIRepository *repository, const gchar *namespace_); const gchar * g_irepository_get_shared_library (GIRepository *repository, diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 49fbe4e3e..1dde5163b 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -1117,6 +1117,9 @@ DirEntry *g_typelib_get_dir_entry_by_gtype (GITypelib *typelib, gboolean fastpass, GType gtype); +DirEntry *g_typelib_get_dir_entry_by_error_domain (GITypelib *typelib, + GQuark error_domain); + void g_typelib_check_sanity (void); #define g_typelib_get_string(typelib,offset) ((const gchar*)&(typelib->data)[(offset)]) diff --git a/gitypelib.c b/gitypelib.c index 3869a6d25..f610d4586 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -249,6 +249,36 @@ g_typelib_get_dir_entry_by_gtype (GITypelib *typelib, return NULL; } +DirEntry * +g_typelib_get_dir_entry_by_error_domain (GITypelib *typelib, + GQuark error_domain) +{ + Header *header = (Header *)typelib->data; + guint n_entries = header->n_local_entries; + const char *domain_string = g_quark_to_string (error_domain); + DirEntry *entry; + guint i; + + for (i = 1; i <= n_entries; i++) + { + EnumBlob *blob; + const char *enum_domain_string; + + entry = g_typelib_get_dir_entry (typelib, i); + if (entry->blob_type != BLOB_TYPE_ENUM) + continue; + + blob = (EnumBlob *)(&typelib->data[entry->offset]); + if (!blob->error_domain) + continue; + + enum_domain_string = g_typelib_get_string (typelib, blob->error_domain); + if (strcmp (domain_string, enum_domain_string) == 0) + return entry; + } + return NULL; +} + void g_typelib_check_sanity (void) { From 34c298a51e621b26df5126bcbca1d5d5724381ec Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Fri, 12 Aug 2011 11:10:06 -0400 Subject: [PATCH 446/692] girepository: fix some doc comment syntax --- girepository.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/girepository.c b/girepository.c index f7f55e5a6..c5c464bd7 100644 --- a/girepository.c +++ b/girepository.c @@ -382,7 +382,7 @@ register_internal (GIRepository *repository, * form namespace-version. * * Note: The namespace must have already been loaded using a function - * such as #g_irepository_require before calling this function. + * such as g_irepository_require() before calling this function. * * Returns: (transfer full): Zero-terminated string array of versioned dependencies */ @@ -447,7 +447,7 @@ g_irepository_load_typelib (GIRepository *repository, * Check whether a particular namespace (and optionally, a specific * version thereof) is currently loaded. This function is likely to * only be useful in unusual circumstances; in order to act upon - * metadata in the namespace, you should call #g_irepository_require + * metadata in the namespace, you should call g_irepository_require() * instead which will ensure the namespace is loaded, and return as * quickly as this function will if it has already been loaded. * @@ -648,7 +648,7 @@ g_irepository_find_by_gtype (GIRepository *repository, * * Searches for a particular entry in a namespace. Before calling * this function for a particular namespace, you must call - * #g_irepository_require once to load the namespace, or otherwise + * g_irepository_require() once to load the namespace, or otherwise * ensure the namespace has already been loaded. * * Returns: (transfer full): #GIBaseInfo representing metadata about @name, or %NULL @@ -723,7 +723,7 @@ g_irepository_get_loaded_namespaces (GIRepository *repository) * namespace @namespace_. * * Note: The namespace must have already been loaded using a function - * such as #g_irepository_require before calling this function. + * such as g_irepository_require() before calling this function. * * Returns: Loaded version */ @@ -757,7 +757,7 @@ g_irepository_get_version (GIRepository *repository, * return %NULL. * * Note: The namespace must have already been loaded using a function - * such as #g_irepository_require before calling this function. + * such as g_irepository_require() before calling this function. * * Returns: Full path to shared library, or %NULL if none associated */ @@ -793,7 +793,7 @@ g_irepository_get_shared_library (GIRepository *repository, * starts with this prefix, as well each #GType in the library. * * Note: The namespace must have already been loaded using a function - * such as #g_irepository_require before calling this function. + * such as g_irepository_require() before calling this function. * * Returns: C namespace prefix, or %NULL if none associated */ From 6ee82c14e84eefcd9c6273fd046f22a761eabd0f Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 19 May 2011 16:12:03 -0400 Subject: [PATCH 447/692] Deprecate ErrorDomain The previous ErrorDomain blob was never actually scanned or used, and it was kind of a lame API conceptually. To keep some compatibility, rather than removing the enumeration values, rename them to _INVALID, and don't bump the typelib version. This should in theory allow a new libgirepository to read an old typelib. Based on a patch from Colin Walters https://bugzilla.gnome.org/show_bug.cgi?id=602516 --- gibaseinfo.c | 5 +-- gierrordomaininfo.c | 95 -------------------------------------------- gierrordomaininfo.h | 44 -------------------- gifieldinfo.c | 4 +- girepository.c | 2 - girepository.h | 1 - girmodule.c | 2 +- girnode.c | 70 ++------------------------------ girnode.h | 15 +------ girparser.c | 81 ++----------------------------------- girwriter.c | 40 ------------------- gitypeinfo.c | 69 -------------------------------- gitypeinfo.h | 3 -- gitypelib-internal.h | 29 ++------------ gitypelib.c | 40 ------------------- gitypes.h | 10 +---- 16 files changed, 17 insertions(+), 493 deletions(-) delete mode 100644 gierrordomaininfo.c delete mode 100644 gierrordomaininfo.h diff --git a/gibaseinfo.c b/gibaseinfo.c index 057cde729..bfb774360 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -202,7 +202,6 @@ _g_type_info_init (GIBaseInfo *info, * +----GIArgInfo * +----GICallableInfo * +----GIConstantInfo - * +----GIErrorDomainInfo * +----GIFieldInfo * +----GIPropertyInfo * +----GIRegisteredTypeInfo @@ -299,7 +298,7 @@ g_base_info_get_name (GIBaseInfo *info) case GI_INFO_TYPE_OBJECT: case GI_INFO_TYPE_INTERFACE: case GI_INFO_TYPE_CONSTANT: - case GI_INFO_TYPE_ERROR_DOMAIN: + case GI_INFO_TYPE_INVALID_0: case GI_INFO_TYPE_UNION: { CommonBlob *blob = (CommonBlob *)&rinfo->typelib->data[rinfo->offset]; @@ -421,7 +420,7 @@ g_base_info_is_deprecated (GIBaseInfo *info) case GI_INFO_TYPE_OBJECT: case GI_INFO_TYPE_INTERFACE: case GI_INFO_TYPE_CONSTANT: - case GI_INFO_TYPE_ERROR_DOMAIN: + case GI_INFO_TYPE_INVALID_0: { CommonBlob *blob = (CommonBlob *)&rinfo->typelib->data[rinfo->offset]; diff --git a/gierrordomaininfo.c b/gierrordomaininfo.c deleted file mode 100644 index 86e40c59b..000000000 --- a/gierrordomaininfo.c +++ /dev/null @@ -1,95 +0,0 @@ -/* GObject introspection: ErrorDomain implementation - * - * Copyright (C) 2005 Matthias Clasen - * Copyright (C) 2008,2009 Red Hat, Inc. - * - * 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 "girepository-private.h" -#include "gitypelib-internal.h" - -/** - * SECTION:gierrordomaininfo - * @Short_description: Struct representing an error domain - * @Title: GIErrorDomainInfo - * - * A GIErrorDomainInfo struct represents a domain of a #GError. - * An error domain is associated with a #GQuark and contains a pointer - * to an enum with all the error codes. - * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GIErrorDomainInfo - * - * - */ - -/** - * g_error_domain_info_get_quark: - * @info: a #GIErrorDomainInfo - * - * Obtain a string representing the quark for this error domain. - * %NULL will be returned if the type tag is wrong or if a quark is - * missing in the typelib. - * - * Returns: the quark represented as a string or %NULL - */ -const gchar * -g_error_domain_info_get_quark (GIErrorDomainInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ErrorDomainBlob *blob; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_ERROR_DOMAIN_INFO (info), NULL); - - blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset]; - - return g_typelib_get_string (rinfo->typelib, blob->get_quark); -} - -/** - * g_error_domain_info_get_codes: - * @info: a #GIErrorDomainInfo - * - * Obtain the enum containing all the error codes for this error domain. - * The return value will have a #GIInfoType of %GI_INFO_TYPE_ERROR_DOMAIN - * - * Returns: (transfer full): the error domain or %NULL if type tag is wrong, - * free the struct with g_base_info_unref() when done. - */ -GIInterfaceInfo * -g_error_domain_info_get_codes (GIErrorDomainInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - ErrorDomainBlob *blob; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_ERROR_DOMAIN_INFO (info), NULL); - - blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset]; - - return (GIInterfaceInfo *) _g_info_from_entry (rinfo->repository, - rinfo->typelib, blob->error_codes); -} - - diff --git a/gierrordomaininfo.h b/gierrordomaininfo.h deleted file mode 100644 index 9c2968bc1..000000000 --- a/gierrordomaininfo.h +++ /dev/null @@ -1,44 +0,0 @@ -/* GObject introspection: Error Domain - * - * Copyright (C) 2005 Matthias Clasen - * Copyright (C) 2008,2009 Red Hat, Inc. - * - * 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 __GIERRORDOMAININFO_H__ -#define __GIERRORDOMAININFO_H__ - -#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -G_BEGIN_DECLS - -#define GI_IS_ERROR_DOMAIN_INFO(info) \ - (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ERROR_DOMAIN) - -const gchar * g_error_domain_info_get_quark (GIErrorDomainInfo *info); -GIInterfaceInfo * g_error_domain_info_get_codes (GIErrorDomainInfo *info); - - -G_END_DECLS - - -#endif /* __GIERRORDOMAININFO_H__ */ - diff --git a/gifieldinfo.c b/gifieldinfo.c index 17491a80a..41976855d 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -322,7 +322,7 @@ g_field_info_get_field (GIFieldInfo *field_info, case GI_INFO_TYPE_INTERFACE: case GI_INFO_TYPE_FUNCTION: case GI_INFO_TYPE_CONSTANT: - case GI_INFO_TYPE_ERROR_DOMAIN: + case GI_INFO_TYPE_INVALID_0: case GI_INFO_TYPE_VALUE: case GI_INFO_TYPE_SIGNAL: case GI_INFO_TYPE_PROPERTY: @@ -498,7 +498,7 @@ g_field_info_set_field (GIFieldInfo *field_info, case GI_INFO_TYPE_INTERFACE: case GI_INFO_TYPE_FUNCTION: case GI_INFO_TYPE_CONSTANT: - case GI_INFO_TYPE_ERROR_DOMAIN: + case GI_INFO_TYPE_INVALID_0: case GI_INFO_TYPE_VALUE: case GI_INFO_TYPE_SIGNAL: case GI_INFO_TYPE_PROPERTY: diff --git a/girepository.c b/girepository.c index c5c464bd7..1afba0c80 100644 --- a/girepository.c +++ b/girepository.c @@ -1466,8 +1466,6 @@ g_info_type_to_string (GIInfoType type) return "interface"; case GI_INFO_TYPE_CONSTANT: return "constant"; - case GI_INFO_TYPE_ERROR_DOMAIN: - return "error domain"; case GI_INFO_TYPE_UNION: return "union"; case GI_INFO_TYPE_VALUE: diff --git a/girepository.h b/girepository.h index f14b1ad77..fddcf8c16 100644 --- a/girepository.h +++ b/girepository.h @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/girmodule.c b/girmodule.c index 49daaa620..f438a193b 100644 --- a/girmodule.c +++ b/girmodule.c @@ -415,7 +415,7 @@ _g_ir_module_build_typelib (GIrModule *module) header->field_blob_size = sizeof (FieldBlob); header->value_blob_size = sizeof (ValueBlob); header->constant_blob_size = sizeof (ConstantBlob); - header->error_domain_blob_size = sizeof (ErrorDomainBlob); + header->error_domain_blob_size = 16; /* No longer used */ header->attribute_blob_size = sizeof (AttributeBlob); header->signature_blob_size = sizeof (SignatureBlob); header->enum_blob_size = sizeof (EnumBlob); diff --git a/girnode.c b/girnode.c index a56471e52..1c51bfd4b 100644 --- a/girnode.c +++ b/girnode.c @@ -101,8 +101,6 @@ _g_ir_node_type_to_string (GIrNodeTypeId type) return "value"; case G_IR_NODE_CONSTANT: return "constant"; - case G_IR_NODE_ERROR_DOMAIN: - return "error-domain"; case G_IR_NODE_XREF: return "xref"; case G_IR_NODE_UNION: @@ -175,10 +173,6 @@ _g_ir_node_new (GIrNodeTypeId type, node = g_malloc0 (sizeof (GIrNodeConstant)); break; - case G_IR_NODE_ERROR_DOMAIN: - node = g_malloc0 (sizeof (GIrNodeErrorDomain)); - break; - case G_IR_NODE_XREF: node = g_malloc0 (sizeof (GIrNodeXRef)); break; @@ -379,16 +373,6 @@ _g_ir_node_free (GIrNode *node) } break; - case G_IR_NODE_ERROR_DOMAIN: - { - GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node; - - g_free (node->name); - g_free (domain->getquark); - g_free (domain->codes); - } - break; - case G_IR_NODE_XREF: { GIrNodeXRef *xref = (GIrNodeXRef *)node; @@ -535,10 +519,6 @@ _g_ir_node_get_size (GIrNode *node) size = sizeof (ConstantBlob); break; - case G_IR_NODE_ERROR_DOMAIN: - size = sizeof (ErrorDomainBlob); - break; - case G_IR_NODE_XREF: size = 0; break; @@ -665,16 +645,7 @@ _g_ir_node_get_full_size_internal (GIrNode *parent, size += _g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type2); break; case GI_TYPE_TAG_ERROR: - { - gint n; - - if (type->errors) - n = g_strv_length (type->errors); - else - n = 0; - - size += sizeof (ErrorTypeBlob) + 2 * (n + n % 2); - } + size += sizeof (ErrorTypeBlob); break; default: g_error ("Unknown type tag %d\n", type->tag); @@ -844,16 +815,6 @@ _g_ir_node_get_full_size_internal (GIrNode *parent, } break; - case G_IR_NODE_ERROR_DOMAIN: - { - GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node; - - size = sizeof (ErrorDomainBlob); - size += ALIGN_VALUE (strlen (node->name) + 1, 4); - size += ALIGN_VALUE (strlen (domain->getquark) + 1, 4); - } - break; - case G_IR_NODE_XREF: { GIrNodeXRef *xref = (GIrNodeXRef *)node; @@ -935,7 +896,7 @@ _g_ir_node_can_have_member (GIrNode *node) case G_IR_NODE_ENUM: case G_IR_NODE_FLAGS: case G_IR_NODE_CONSTANT: - case G_IR_NODE_ERROR_DOMAIN: + case G_IR_NODE_INVALID_0: case G_IR_NODE_PARAM: case G_IR_NODE_TYPE: case G_IR_NODE_PROPERTY: @@ -1559,21 +1520,14 @@ _g_ir_node_build_typelib (GIrNode *node, case GI_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; + blob->n_domains = 0; - *offset2 = ALIGN_VALUE (*offset2 + G_STRUCT_OFFSET (ErrorTypeBlob, domains) - + 2 * blob->n_domains, 4); - for (i = 0; i < blob->n_domains; i++) - blob->domains[i] = find_entry (build, type->errors[i]); + *offset2 += sizeof (ErrorTypeBlob); } break; @@ -2234,22 +2188,6 @@ _g_ir_node_build_typelib (GIrNode *node, } break; - case G_IR_NODE_ERROR_DOMAIN: - { - GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node; - ErrorDomainBlob *blob = (ErrorDomainBlob *)&data[*offset]; - *offset += sizeof (ErrorDomainBlob); - - blob->blob_type = BLOB_TYPE_ERROR_DOMAIN; - blob->deprecated = domain->deprecated; - blob->reserved = 0; - blob->name = _g_ir_write_string (node->name, strings, data, offset2); - blob->get_quark = _g_ir_write_string (domain->getquark, strings, data, offset2); - blob->error_codes = find_entry (build, domain->codes); - blob->reserved2 = 0; - } - break; - case G_IR_NODE_CONSTANT: { GIrNodeConstant *constant = (GIrNodeConstant *)node; diff --git a/girnode.h b/girnode.h index 1f9102fd2..fb2616b1e 100644 --- a/girnode.h +++ b/girnode.h @@ -41,7 +41,6 @@ typedef struct _GIrNodeEnum GIrNodeEnum; typedef struct _GIrNodeBoxed GIrNodeBoxed; typedef struct _GIrNodeStruct GIrNodeStruct; typedef struct _GIrNodeConstant GIrNodeConstant; -typedef struct _GIrNodeErrorDomain GIrNodeErrorDomain; typedef struct _GIrNodeXRef GIrNodeXRef; typedef struct _GIrNodeUnion GIrNodeUnion; @@ -57,7 +56,7 @@ typedef enum G_IR_NODE_OBJECT = 7, G_IR_NODE_INTERFACE = 8, G_IR_NODE_CONSTANT = 9, - G_IR_NODE_ERROR_DOMAIN = 10, + G_IR_NODE_INVALID_0 = 10, /* DELETED - used to be ERROR_DOMAIN */ G_IR_NODE_UNION = 11, G_IR_NODE_PARAM = 12, G_IR_NODE_TYPE = 13, @@ -343,18 +342,6 @@ struct _GIrNodeUnion }; -struct _GIrNodeErrorDomain -{ - GIrNode node; - - gboolean deprecated; - - gchar *name; - gchar *getquark; - gchar *codes; -}; - - GIrNode * _g_ir_node_new (GIrNodeTypeId type, GIrModule *module); void _g_ir_node_free (GIrNode *node); diff --git a/girparser.c b/girparser.c index 02c044279..4e5527259 100644 --- a/girparser.c +++ b/girparser.c @@ -68,13 +68,12 @@ typedef enum STATE_BOXED_FIELD, STATE_STRUCT, STATE_STRUCT_FIELD, - STATE_ERRORDOMAIN, /* 25 */ - STATE_UNION, + STATE_UNION, /* 25 */ STATE_UNION_FIELD, STATE_NAMESPACE_CONSTANT, STATE_CLASS_CONSTANT, - STATE_INTERFACE_CONSTANT, /* 30 */ - STATE_ALIAS, + STATE_INTERFACE_CONSTANT, + STATE_ALIAS, /* 30 */ STATE_TYPE, STATE_ATTRIBUTE, STATE_DOC, @@ -1614,68 +1613,6 @@ start_constant (GMarkupParseContext *context, return TRUE; } -static gboolean -start_errordomain (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseContext *ctx, - GError **error) -{ - const gchar *name; - const gchar *getquark; - const gchar *codes; - const gchar *deprecated; - GIrNodeErrorDomain *domain; - - if (!(strcmp (element_name, "errordomain") == 0 && - ctx->state == STATE_NAMESPACE)) - return FALSE; - - if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_ERRORDOMAIN)) - return TRUE; - - - name = find_attribute ("name", attribute_names, attribute_values); - getquark = find_attribute ("get-quark", attribute_names, attribute_values); - codes = find_attribute ("codes", attribute_names, attribute_values); - deprecated = find_attribute ("deprecated", attribute_names, attribute_values); - - if (name == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "name"); - return FALSE; - } - else if (getquark == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "getquark"); - return FALSE; - } - else if (codes == NULL) - { - MISSING_ATTRIBUTE (context, error, element_name, "codes"); - return FALSE; - } - - domain = (GIrNodeErrorDomain *) _g_ir_node_new (G_IR_NODE_ERROR_DOMAIN, - ctx->current_module); - - ((GIrNode *)domain)->name = g_strdup (name); - domain->getquark = g_strdup (getquark); - domain->codes = g_strdup (codes); - - if (deprecated) - domain->deprecated = TRUE; - else - domain->deprecated = FALSE; - - push_node (ctx, (GIrNode *) domain); - ctx->current_module->entries = - g_list_append (ctx->current_module->entries, domain); - - return TRUE; -} - static gboolean start_interface (GMarkupParseContext *context, const gchar *element_name, @@ -2788,10 +2725,6 @@ start_element_handler (GMarkupParseContext *context, attribute_names, attribute_values, ctx, error)) goto out; - else if (start_errordomain (context, element_name, - attribute_names, attribute_values, - ctx, error)) - goto out; break; case 'f': @@ -3290,14 +3223,6 @@ end_element_handler (GMarkupParseContext *context, } break; - case STATE_ERRORDOMAIN: - if (require_end_element (context, ctx, "errordomain", element_name, error)) - { - pop_node (ctx); - state_switch (ctx, STATE_NAMESPACE); - } - break; - case STATE_INTERFACE_PROPERTY: if (strcmp ("type", element_name) == 0) break; diff --git a/girwriter.c b/girwriter.c index f6ab34ebd..2cdc9a11f 100644 --- a/girwriter.c +++ b/girwriter.c @@ -212,7 +212,6 @@ write_type_info (const gchar *namespace, Xml *file) { gint tag; - gint i; GITypeInfo *type; gboolean is_pointer; @@ -329,24 +328,8 @@ write_type_info (const gchar *namespace, } else if (tag == GI_TYPE_TAG_ERROR) { - gint n; - xml_start_element (file, "type"); xml_printf (file, " name=\"GLib.Error\""); - - n = g_type_info_get_n_error_domains (info); - if (n > 0) - { - for (i = 0; i < n; i++) - { - GIErrorDomainInfo *ed = g_type_info_get_error_domain (info, i); - xml_start_element (file, "type"); - write_type_name_attribute (namespace, (GIBaseInfo *)ed, "name", file); - xml_end_element (file, "type"); - g_base_info_unref ((GIBaseInfo *)ed); - } - } - xml_end_element (file, "type"); } else @@ -1193,25 +1176,6 @@ write_interface_info (const gchar *namespace, xml_end_element (file, "interface"); } -static void -write_error_domain_info (const gchar *namespace, - GIErrorDomainInfo *info, - Xml *file) -{ - GIBaseInfo *enum_; - const gchar *name, *quark; - - name = g_base_info_get_name ((GIBaseInfo *)info); - quark = g_error_domain_info_get_quark (info); - enum_ = (GIBaseInfo *)g_error_domain_info_get_codes (info); - xml_start_element (file, "errordomain"); - xml_printf (file, " name=\"%s\" get-quark=\"%s\"", - name, quark); - write_type_name_attribute (namespace, enum_, "codes", file); - xml_end_element (file, "errordomain"); - g_base_info_unref (enum_); -} - static void write_union_info (const gchar *namespace, GIUnionInfo *info, @@ -1411,10 +1375,6 @@ gir_writer_write (const char *filename, write_interface_info (ns, (GIInterfaceInfo *)info, xml); break; - case GI_INFO_TYPE_ERROR_DOMAIN: - write_error_domain_info (ns, (GIErrorDomainInfo *)info, xml); - break; - default: g_error ("unknown info type %d\n", g_base_info_get_type (info)); } diff --git a/gitypeinfo.c b/gitypeinfo.c index 1bc9b0a13..5864f82fe 100644 --- a/gitypeinfo.c +++ b/gitypeinfo.c @@ -340,72 +340,3 @@ g_type_info_get_array_type (GITypeInfo *info) return -1; } - -/** - * g_type_info_get_n_error_domains: - * @info: a #GITypeInfo - * - * Obtain the number of error domains for this type. The type tag - * must be a #GI_TYPE_TAG_ERROR or -1 will be returned. - * - * Returns: number of error domains or -1 - */ -gint -g_type_info_get_n_error_domains (GITypeInfo *info) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type; - - g_return_val_if_fail (info != NULL, 0); - g_return_val_if_fail (GI_IS_TYPE_INFO (info), 0); - - type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) - { - ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->tag == GI_TYPE_TAG_ERROR) - return blob->n_domains; - } - - return 0; -} - -/** - * g_type_info_get_error_domain: - * @info: a #GITypeInfo - * @n: index of error domain - * - * Obtain the error domains at index @n for this type. The type tag - * must be a #GI_TYPE_TAG_ERROR or -1 will be returned. - * - * Returns: (transfer full): the error domain or %NULL if type tag is wrong, - * free the struct with g_base_info_unref() when done. - */ -GIErrorDomainInfo * -g_type_info_get_error_domain (GITypeInfo *info, - gint n) -{ - GIRealInfo *rinfo = (GIRealInfo *)info; - SimpleTypeBlob *type; - - g_return_val_if_fail (info != NULL, NULL); - g_return_val_if_fail (GI_IS_TYPE_INFO (info), NULL); - - type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0)) - { - ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset]; - - if (blob->tag == GI_TYPE_TAG_ERROR) - return (GIErrorDomainInfo *) _g_info_from_entry (rinfo->repository, - rinfo->typelib, - blob->domains[n]); - } - - return NULL; -} - - diff --git a/gitypeinfo.h b/gitypeinfo.h index 5c4fc8351..56e7309aa 100644 --- a/gitypeinfo.h +++ b/gitypeinfo.h @@ -48,9 +48,6 @@ gint g_type_info_get_array_fixed_size(GITypeInfo *info); gboolean g_type_info_is_zero_terminated (GITypeInfo *info); GIArrayType g_type_info_get_array_type (GITypeInfo *info); -gint g_type_info_get_n_error_domains (GITypeInfo *info); -GIErrorDomainInfo *g_type_info_get_error_domain (GITypeInfo *info, - gint n); G_END_DECLS diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 593c9876c..2bda8d9d0 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -57,7 +57,7 @@ G_BEGIN_DECLS * directory ::= list of entries * * entry ::= blob type, name, namespace, offset - * blob ::= function|callback|struct|boxed|enum|flags|object|interface|constant|errordomain|union + * blob ::= function|callback|struct|boxed|enum|flags|object|interface|constant|union * attributes ::= list of attributes, sorted by offset * attribute ::= offset, key, value * attributedata ::= string data for attributes @@ -156,7 +156,6 @@ Changes since 0.1: * @BLOB_TYPE_OBJECT: An #ObjectBlob * @BLOB_TYPE_INTERFACE: An #InterfaceBlob * @BLOB_TYPE_CONSTANT: A #ConstantBlob - * @BLOB_TYPE_ERROR_DOMAIN: A #ErrorDomainBlob * @BLOB_TYPE_UNION: A #UnionBlob * * The integral value of this enumeration appears in each "Blob" @@ -173,7 +172,7 @@ typedef enum { BLOB_TYPE_OBJECT, BLOB_TYPE_INTERFACE, BLOB_TYPE_CONSTANT, - BLOB_TYPE_ERROR_DOMAIN, + BLOB_TYPE_INVALID_0, /* DELETED - used to be ErrorDomain */ BLOB_TYPE_UNION } GTypelibBlobType; @@ -624,8 +623,6 @@ typedef struct { /** * ErrorTypeBlob: - * @n_domains: The number of domains to follow - * @domains: Indices of the directory entries for the error domains */ typedef struct { guint8 pointer :1; @@ -633,31 +630,11 @@ typedef struct { guint8 tag :5; guint8 reserved2; - guint16 n_domains; + guint16 n_domains; /* Must be 0 */ guint16 domains[]; } ErrorTypeBlob; -/** - * ErrorDomainBlob: - * @get_quark: The symbol name of the function which must be called to obtain the - * GQuark for the error domain. - * @error_codes: Index of the InterfaceBlob describing the enumeration which lists - * the possible error codes. - */ -typedef struct { - guint16 blob_type; /* 10 */ - - guint16 deprecated : 1; - guint16 reserved :15; - - guint32 name; - - guint32 get_quark; - guint16 error_codes; - guint16 reserved2; -} ErrorDomainBlob; - /** * ValueBlob: * @deprecated: Whether this value is deprecated diff --git a/gitypelib.c b/gitypelib.c index 6d1333ba0..3869a6d25 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -284,7 +284,6 @@ g_typelib_check_sanity (void) CHECK_SIZE (ArrayTypeBlob, 8); CHECK_SIZE (ParamTypeBlob, 4); CHECK_SIZE (ErrorTypeBlob, 4); - CHECK_SIZE (ErrorDomainBlob, 16); CHECK_SIZE (ValueBlob, 12); CHECK_SIZE (FieldBlob, 16); CHECK_SIZE (RegisteredTypeBlob, 16); @@ -446,7 +445,6 @@ validate_header_basic (const guint8 *memory, header->field_blob_size != sizeof (FieldBlob) || header->value_blob_size != sizeof (ValueBlob) || header->constant_blob_size != sizeof (ConstantBlob) || - header->error_domain_blob_size != sizeof (ErrorDomainBlob) || header->attribute_blob_size != sizeof (AttributeBlob) || header->signature_blob_size != sizeof (SignatureBlob) || header->enum_blob_size != sizeof (EnumBlob) || @@ -607,8 +605,6 @@ validate_error_type_blob (GITypelib *typelib, { ErrorTypeBlob *blob; Header *header; - gint i; - DirEntry *entry; blob = (ErrorTypeBlob*)&typelib->data[offset]; @@ -623,30 +619,6 @@ validate_error_type_blob (GITypelib *typelib, return FALSE; } - for (i = 0; i < blob->n_domains; i++) - { - if (blob->domains[i] == 0 || blob->domains[i] > header->n_entries) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Invalid directory index %d", blob->domains[i]); - return FALSE; - } - - entry = g_typelib_get_dir_entry (typelib, blob->domains[i]); - - if (entry->blob_type != BLOB_TYPE_ERROR_DOMAIN && - (entry->local || entry->blob_type != BLOB_TYPE_INVALID)) - { - g_set_error (error, - G_TYPELIB_ERROR, - G_TYPELIB_ERROR_INVALID_BLOB, - "Wrong blob type"); - return FALSE; - } - } - return TRUE; } @@ -1824,14 +1796,6 @@ validate_interface_blob (ValidateContext *ctx, return TRUE; } -static gboolean -validate_errordomain_blob (GITypelib *typelib, - guint32 offset, - GError **error) -{ - return TRUE; -} - static gboolean validate_union_blob (GITypelib *typelib, guint32 offset, @@ -1891,10 +1855,6 @@ validate_blob (ValidateContext *ctx, if (!validate_constant_blob (typelib, offset, error)) return FALSE; break; - case BLOB_TYPE_ERROR_DOMAIN: - if (!validate_errordomain_blob (typelib, offset, error)) - return FALSE; - break; case BLOB_TYPE_UNION: if (!validate_union_blob (typelib, offset, error)) return FALSE; diff --git a/gitypes.h b/gitypes.h index d15b121a3..cbe43168b 100644 --- a/gitypes.h +++ b/gitypes.h @@ -150,13 +150,6 @@ typedef GIBaseInfo GIArgInfo; */ typedef GIBaseInfo GITypeInfo; -/** - * GIErrorDomainInfo: - * - * Represents a #GError error domain. - */ -typedef GIBaseInfo GIErrorDomainInfo; - /** * GIUnresolvedInfo: * @@ -202,7 +195,6 @@ typedef union _GIArgument GIArgument; * @GI_INFO_TYPE_OBJECT: object, see #GIObjectInfo * @GI_INFO_TYPE_INTERFACE: interface, see #GIInterfaceInfo * @GI_INFO_TYPE_CONSTANT: contant, see #GIConstantInfo - * @GI_INFO_TYPE_ERROR_DOMAIN: error domain for a #GError, see #GIErrorDomainInfo * @GI_INFO_TYPE_UNION: union, see #GIUnionInfo * @GI_INFO_TYPE_VALUE: enum value, see #GIValueInfo * @GI_INFO_TYPE_SIGNAL: signal, see #GISignalInfo @@ -228,7 +220,7 @@ typedef enum GI_INFO_TYPE_OBJECT, GI_INFO_TYPE_INTERFACE, GI_INFO_TYPE_CONSTANT, - GI_INFO_TYPE_ERROR_DOMAIN, /* 10 */ + GI_INFO_TYPE_INVALID_0, /* 10 */ /** DELETED - used to be ERROR_DOMAIN **/ GI_INFO_TYPE_UNION, GI_INFO_TYPE_VALUE, GI_INFO_TYPE_SIGNAL, From 215d83ebb0a7f15b359e9e63fea2715113784ff7 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 19 May 2011 16:21:13 -0400 Subject: [PATCH 448/692] Switch to storing string form of error quarks Instead of storing the name of the function to call to get the error quark, store the string form of the error quark, which we derive from the introspection binary during scanning. Update EnumBlob and GIEnumInfo to include the new information. This will allow determining a back-mapping from error quark to error domain without having to dlsym() and call all the known error quark functions. Based on earlier patches from Owen Taylor and Maxim Ermilov. https://bugzilla.gnome.org/show_bug.cgi?id=602516 --- gdump.c | 83 +++++++++++++++++++++++++++++++++++--------- gienuminfo.c | 17 +++++++++ gienuminfo.h | 1 + girnode.c | 7 ++++ girnode.h | 1 + girparser.c | 4 +++ girwriter.c | 4 +++ gitypelib-internal.h | 4 ++- 8 files changed, 104 insertions(+), 17 deletions(-) diff --git a/gdump.c b/gdump.c index cb6e74197..e607f3237 100644 --- a/gdump.c +++ b/gdump.c @@ -70,6 +70,7 @@ goutput_write (GOutputStream *out, const char *str) } typedef GType (*GetTypeFunc)(void); +typedef GQuark (*ErrorQuarkFunc)(void); static GType invoke_get_type (GModule *self, const char *symbol, GError **error) @@ -97,6 +98,23 @@ invoke_get_type (GModule *self, const char *symbol, GError **error) return ret; } +static GQuark +invoke_error_quark (GModule *self, const char *symbol, GError **error) +{ + ErrorQuarkFunc sym; + + if (!g_module_symbol (self, symbol, (void**)&sym)) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Failed to find symbol '%s'", symbol); + return G_TYPE_INVALID; + } + + return sym (); +} + static void dump_properties (GType type, GOutputStream *out) { @@ -365,6 +383,13 @@ dump_type (GType type, const char *symbol, GOutputStream *out) } } +static void +dump_error_quark (GQuark quark, const char *symbol, GOutputStream *out) +{ + escaped_printf (out, " \n", + symbol, g_quark_to_string (quark)); +} + /** * g_irepository_dump: * @arg: Comma-separated pair of input and output filenames @@ -437,29 +462,55 @@ g_irepository_dump (const char *arg, GError **error) { gsize len; char *line = g_data_input_stream_read_line (in, &len, NULL, NULL); - GType type; + const char *function; if (line == NULL || *line == '\0') - { - g_free (line); - break; - } + { + g_free (line); + break; + } g_strchomp (line); - type = invoke_get_type (self, line, error); - if (type == G_TYPE_INVALID) - { - caught_error = TRUE; - g_free (line); - break; - } + if (strncmp (line, "get-type:", strlen ("get-type:")) == 0) + { + GType type; - if (g_hash_table_lookup (output_types, (gpointer) type)) - goto next; - g_hash_table_insert (output_types, (gpointer) type, (gpointer) type); + function = line + strlen ("get-type:"); + + type = invoke_get_type (self, function, error); + + if (type == G_TYPE_INVALID) + { + g_printerr ("Invalid GType function: '%s'\n", function); + caught_error = TRUE; + g_free (line); + break; + } + + if (g_hash_table_lookup (output_types, (gpointer) type)) + goto next; + g_hash_table_insert (output_types, (gpointer) type, (gpointer) type); + + dump_type (type, function, G_OUTPUT_STREAM (output)); + } + else if (strncmp (line, "error-quark:", strlen ("error-quark:")) == 0) + { + GQuark quark; + function = line + strlen ("error-quark:"); + quark = invoke_error_quark (self, function, error); + + if (quark == 0) + { + g_printerr ("Invalid error quark function: '%s'\n", function); + caught_error = TRUE; + g_free (line); + break; + } + + dump_error_quark (quark, function, G_OUTPUT_STREAM (output)); + } - dump_type (type, line, G_OUTPUT_STREAM (output)); next: g_free (line); diff --git a/gienuminfo.c b/gienuminfo.c index 062f3abf2..338a46ee0 100644 --- a/gienuminfo.c +++ b/gienuminfo.c @@ -66,6 +66,23 @@ g_enum_info_get_n_values (GIEnumInfo *info) return blob->n_values; } +const gchar * +g_enum_info_get_error_domain (GIEnumInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + EnumBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_ENUM_INFO (info), 0); + + blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->error_domain) + return g_typelib_get_string (rinfo->typelib, blob->error_domain); + else + return NULL; +} + /** * g_enum_info_get_value: * @info: a #GIEnumInfo diff --git a/gienuminfo.h b/gienuminfo.h index 6b24fe7ef..fc0f3c842 100644 --- a/gienuminfo.h +++ b/gienuminfo.h @@ -41,6 +41,7 @@ gint g_enum_info_get_n_values (GIEnumInfo *info); GIValueInfo * g_enum_info_get_value (GIEnumInfo *info, gint n); GITypeTag g_enum_info_get_storage_type (GIEnumInfo *info); +const gchar * g_enum_info_get_error_domain (GIEnumInfo *info); gint64 g_value_info_get_value (GIValueInfo *info); diff --git a/girnode.c b/girnode.c index 1c51bfd4b..166ca30a3 100644 --- a/girnode.c +++ b/girnode.c @@ -328,6 +328,7 @@ _g_ir_node_free (GIrNode *node) g_free (node->name); g_free (enum_->gtype_name); g_free (enum_->gtype_init); + g_free (enum_->error_domain); for (l = enum_->values; l; l = l->next) _g_ir_node_free ((GIrNode *)l->data); @@ -712,6 +713,8 @@ _g_ir_node_get_full_size_internal (GIrNode *parent, size += ALIGN_VALUE (strlen (enum_->gtype_name) + 1, 4); size += ALIGN_VALUE (strlen (enum_->gtype_init) + 1, 4); } + if (enum_->error_domain) + size += ALIGN_VALUE (strlen (enum_->error_domain) + 1, 4); for (l = enum_->values; l; l = l->next) size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); @@ -2021,6 +2024,10 @@ _g_ir_node_build_typelib (GIrNode *node, blob->gtype_name = 0; blob->gtype_init = 0; } + if (enum_->error_domain) + blob->error_domain = _g_ir_write_string (enum_->error_domain, strings, data, offset2); + else + blob->error_domain = 0; blob->n_values = 0; blob->reserved2 = 0; diff --git a/girnode.h b/girnode.h index fb2616b1e..6e03821ba 100644 --- a/girnode.h +++ b/girnode.h @@ -285,6 +285,7 @@ struct _GIrNodeEnum gchar *gtype_name; gchar *gtype_init; + gchar *error_domain; GList *values; }; diff --git a/girparser.c b/girparser.c index 4e5527259..c9b7d6292 100644 --- a/girparser.c +++ b/girparser.c @@ -1332,6 +1332,7 @@ start_enum (GMarkupParseContext *context, const gchar *typename; const gchar *typeinit; const gchar *deprecated; + const gchar *error_domain; GIrNodeEnum *enum_; if (!((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) || @@ -1344,6 +1345,7 @@ start_enum (GMarkupParseContext *context, name = find_attribute ("name", attribute_names, attribute_values); typename = find_attribute ("glib:type-name", attribute_names, attribute_values); typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + error_domain = find_attribute ("glib:error-domain", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); if (name == NULL) @@ -1361,6 +1363,8 @@ start_enum (GMarkupParseContext *context, ((GIrNode *)enum_)->name = g_strdup (name); enum_->gtype_name = g_strdup (typename); enum_->gtype_init = g_strdup (typeinit); + enum_->error_domain = g_strdup (error_domain); + if (deprecated) enum_->deprecated = TRUE; else diff --git a/girwriter.c b/girwriter.c index 2cdc9a11f..d9f916c55 100644 --- a/girwriter.c +++ b/girwriter.c @@ -805,6 +805,7 @@ write_enum_info (const gchar *namespace, const gchar *name; const gchar *type_name; const gchar *type_init; + const gchar *error_domain; gboolean deprecated; gint i; @@ -813,6 +814,7 @@ write_enum_info (const gchar *namespace, type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); + error_domain = g_enum_info_get_error_domain (info); if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_ENUM) xml_start_element (file, "enumeration"); @@ -822,6 +824,8 @@ write_enum_info (const gchar *namespace, if (type_init) xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init); + if (error_domain) + xml_printf (file, " glib:error-domain=\"%s\"", error_domain); if (deprecated) xml_printf (file, " deprecated=\"1\""); diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 2bda8d9d0..49fbe4e3e 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -798,6 +798,8 @@ typedef struct { * (will be a signed or unsigned integral type) * @gtype_name: String name of the associated #GType * @gtype_init: String naming the symbol which gets the runtime #GType + * @error_domain: String naming the #GError domain this enum is + * associated with * @n_values: The lengths of the values arrays. * @values: Describes the enum values. */ @@ -817,7 +819,7 @@ typedef struct { guint16 n_values; guint16 reserved2; - guint32 reserved3; + guint32 error_domain; ValueBlob values[]; } EnumBlob; From ff6cada5528275d906763bf2133e937ebeea304b Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 19 May 2011 17:46:36 -0400 Subject: [PATCH 449/692] Add g_irepository_find_by_error_domain() Add a method to look up a GIEnumInfo given its associated error quark. Based on a patch from Colin Walters. https://bugzilla.gnome.org/show_bug.cgi?id=602516 --- girepository.c | 83 ++++++++++++++++++++++++++++++++++++++++++++ girepository.h | 2 ++ gitypelib-internal.h | 3 ++ gitypelib.c | 30 ++++++++++++++++ 4 files changed, 118 insertions(+) diff --git a/girepository.c b/girepository.c index 1afba0c80..a2a778d91 100644 --- a/girepository.c +++ b/girepository.c @@ -45,6 +45,7 @@ struct _GIRepositoryPrivate GHashTable *typelibs; /* (string) namespace -> GITypelib */ GHashTable *lazy_typelibs; /* (string) namespace-version -> GITypelib */ GHashTable *info_by_gtype; /* GType -> GIBaseInfo */ + GHashTable *info_by_error_domain; /* GQuark -> GIBaseInfo */ }; G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT); @@ -64,6 +65,10 @@ g_irepository_init (GIRepository *repository) = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) NULL, (GDestroyNotify) g_base_info_unref); + repository->priv->info_by_error_domain + = g_hash_table_new_full (g_direct_hash, g_direct_equal, + (GDestroyNotify) NULL, + (GDestroyNotify) g_base_info_unref); } static void @@ -74,6 +79,7 @@ g_irepository_finalize (GObject *object) g_hash_table_destroy (repository->priv->typelibs); g_hash_table_destroy (repository->priv->lazy_typelibs); g_hash_table_destroy (repository->priv->info_by_gtype); + g_hash_table_destroy (repository->priv->info_by_error_domain); (* G_OBJECT_CLASS (g_irepository_parent_class)->finalize) (G_OBJECT (repository)); } @@ -675,6 +681,83 @@ g_irepository_find_by_name (GIRepository *repository, NULL, typelib, entry->offset); } +typedef struct { + GIRepository *repository; + GQuark domain; + + GITypelib *result_typelib; + DirEntry *result; +} FindByErrorDomainData; + +static void +find_by_error_domain_foreach (gpointer key, + gpointer value, + gpointer datap) +{ + GITypelib *typelib = (GITypelib*)value; + FindByErrorDomainData *data = datap; + + if (data->result != NULL) + return; + + data->result = g_typelib_get_dir_entry_by_error_domain (typelib, data->domain); + if (data->result) + data->result_typelib = typelib; +} + +/** + * g_irepository_find_by_error_domain: + * @repository: (allow-none): A #GIRepository, may be %NULL for the default + * @domain: a #GError domain + * + * Searches for the enum type corresponding to the given #GError + * domain. Before calling this function for a particular namespace, + * you must call g_irepository_require() once to load the namespace, or + * otherwise ensure the namespace has already been loaded. + * + * Returns: (transfer full): #GIEnumInfo representing metadata about @domain's + * enum type, or %NULL + * + * Since: 1.29.17 + */ +GIEnumInfo * +g_irepository_find_by_error_domain (GIRepository *repository, + GQuark domain) +{ + FindByErrorDomainData data; + GIEnumInfo *cached; + + repository = get_repository (repository); + + cached = g_hash_table_lookup (repository->priv->info_by_error_domain, + GUINT_TO_POINTER (domain)); + + if (cached != NULL) + return g_base_info_ref ((GIBaseInfo *)cached); + + data.repository = repository; + data.domain = domain; + data.result_typelib = NULL; + data.result = NULL; + + g_hash_table_foreach (repository->priv->typelibs, find_by_error_domain_foreach, &data); + if (data.result == NULL) + g_hash_table_foreach (repository->priv->lazy_typelibs, find_by_error_domain_foreach, &data); + + if (data.result != NULL) + { + cached = _g_info_new_full (data.result->blob_type, + repository, + NULL, data.result_typelib, data.result->offset); + + g_hash_table_insert (repository->priv->info_by_error_domain, + GUINT_TO_POINTER (domain), + g_base_info_ref (cached)); + return cached; + } + return NULL; +} + static void collect_namespaces (gpointer key, gpointer value, diff --git a/girepository.h b/girepository.h index fddcf8c16..9e99f6e31 100644 --- a/girepository.h +++ b/girepository.h @@ -123,6 +123,8 @@ gint g_irepository_get_n_infos (GIRepository *repository, GIBaseInfo * g_irepository_get_info (GIRepository *repository, const gchar *namespace_, gint index); +GIEnumInfo * g_irepository_find_by_error_domain (GIRepository *repository, + GQuark domain); const gchar * g_irepository_get_typelib_path (GIRepository *repository, const gchar *namespace_); const gchar * g_irepository_get_shared_library (GIRepository *repository, diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 49fbe4e3e..1dde5163b 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -1117,6 +1117,9 @@ DirEntry *g_typelib_get_dir_entry_by_gtype (GITypelib *typelib, gboolean fastpass, GType gtype); +DirEntry *g_typelib_get_dir_entry_by_error_domain (GITypelib *typelib, + GQuark error_domain); + void g_typelib_check_sanity (void); #define g_typelib_get_string(typelib,offset) ((const gchar*)&(typelib->data)[(offset)]) diff --git a/gitypelib.c b/gitypelib.c index 3869a6d25..f610d4586 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -249,6 +249,36 @@ g_typelib_get_dir_entry_by_gtype (GITypelib *typelib, return NULL; } +DirEntry * +g_typelib_get_dir_entry_by_error_domain (GITypelib *typelib, + GQuark error_domain) +{ + Header *header = (Header *)typelib->data; + guint n_entries = header->n_local_entries; + const char *domain_string = g_quark_to_string (error_domain); + DirEntry *entry; + guint i; + + for (i = 1; i <= n_entries; i++) + { + EnumBlob *blob; + const char *enum_domain_string; + + entry = g_typelib_get_dir_entry (typelib, i); + if (entry->blob_type != BLOB_TYPE_ENUM) + continue; + + blob = (EnumBlob *)(&typelib->data[entry->offset]); + if (!blob->error_domain) + continue; + + enum_domain_string = g_typelib_get_string (typelib, blob->error_domain); + if (strcmp (domain_string, enum_domain_string) == 0) + return entry; + } + return NULL; +} + void g_typelib_check_sanity (void) { From 1dcf01a490bf274edcf19eda2386a6f17dd405d2 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 13 Aug 2011 10:35:13 -0300 Subject: [PATCH 450/692] Add signal flags This adds all GSignalFlags into the gir. https://bugzilla.gnome.org/show_bug.cgi?id=656457 --- gdump.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/gdump.c b/gdump.c index e607f3237..aab067b6f 100644 --- a/gdump.c +++ b/gdump.c @@ -166,9 +166,33 @@ dump_signals (GType type, GOutputStream *out) sigid = sig_ids[i]; g_signal_query (sigid, &query); - escaped_printf (out, " \n", + escaped_printf (out, " \n"); + for (j = 0; j < query.n_params; j++) { escaped_printf (out, " \n", From 4ce922a903118342bac73045c435b4449c04b766 Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Sat, 13 Aug 2011 11:21:05 -0300 Subject: [PATCH 451/692] Add signal flags This adds all GSignalFlags into the gir. https://bugzilla.gnome.org/show_bug.cgi?id=656457 --- gdump.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/gdump.c b/gdump.c index e607f3237..aab067b6f 100644 --- a/gdump.c +++ b/gdump.c @@ -166,9 +166,33 @@ dump_signals (GType type, GOutputStream *out) sigid = sig_ids[i]; g_signal_query (sigid, &query); - escaped_printf (out, " \n", + escaped_printf (out, " \n"); + for (j = 0; j < query.n_params; j++) { escaped_printf (out, " \n", From 322ac4f0a31e4c0d230d2e2a961d87ea45573805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20Sch=C3=B6nfeld?= Date: Sat, 13 Aug 2011 17:28:30 +0200 Subject: [PATCH 452/692] Allow enums and bitfields to have static methods This uses the same backcompat machinery that was introduced for static methods for non-class types, so this change does not break users of the existing presentations. New libgirepository API: g_enum_info_get_n_methods g_enum_info_get_method https://bugzilla.gnome.org/show_bug.cgi?id=656499 --- gienuminfo.c | 55 ++++++++++++++++++++++++++++++++++++++++++++ gienuminfo.h | 3 +++ girnode.c | 18 ++++++++++++++- girnode.h | 1 + girparser.c | 17 ++++++++++++++ gitypelib-internal.h | 9 ++++++-- gitypelib.c | 22 ++++++++++++------ 7 files changed, 115 insertions(+), 10 deletions(-) diff --git a/gienuminfo.c b/gienuminfo.c index 338a46ee0..90b19a96f 100644 --- a/gienuminfo.c +++ b/gienuminfo.c @@ -111,6 +111,61 @@ g_enum_info_get_value (GIEnumInfo *info, return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, (GIBaseInfo*)info, rinfo->typelib, offset); } +/** + * g_enum_info_get_n_methods: + * @info: a #GIEnumInfo + * + * Obtain the number of methods that this enum type has. + * + * Returns: number of methods + */ +gint +g_enum_info_get_n_methods (GIEnumInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + EnumBlob *blob; + + g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (GI_IS_ENUM_INFO (info), 0); + + blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset]; + + return blob->n_methods; +} + +/** + * g_enum_info_get_method: + * @info: a #GIEnumInfo + * @n: index of method to get + * + * Obtain an enum type method at index @n. + * + * Returns: (transfer full): the #GIFunctionInfo. Free the struct by calling + * g_base_info_unref() when done. + */ +GIFunctionInfo * +g_enum_info_get_method (GIEnumInfo *info, + gint n) +{ + gint offset; + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header; + EnumBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_ENUM_INFO (info), NULL); + + header = (Header *)rinfo->typelib->data; + blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset]; + + offset = rinfo->offset + header->enum_blob_size + + blob->n_values * header->value_blob_size + + n * header->function_blob_size; + + return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, + rinfo->typelib, offset); +} + /** * g_enum_info_get_storage_type: * @info: a #GIEnumInfo diff --git a/gienuminfo.h b/gienuminfo.h index fc0f3c842..def97f952 100644 --- a/gienuminfo.h +++ b/gienuminfo.h @@ -40,6 +40,9 @@ G_BEGIN_DECLS gint g_enum_info_get_n_values (GIEnumInfo *info); GIValueInfo * g_enum_info_get_value (GIEnumInfo *info, gint n); +gint g_enum_info_get_n_methods (GIEnumInfo *info); +GIFunctionInfo * g_enum_info_get_method (GIEnumInfo *info, + gint n); GITypeTag g_enum_info_get_storage_type (GIEnumInfo *info); const gchar * g_enum_info_get_error_domain (GIEnumInfo *info); diff --git a/girnode.c b/girnode.c index 166ca30a3..fcc8ce5e3 100644 --- a/girnode.c +++ b/girnode.c @@ -333,6 +333,10 @@ _g_ir_node_free (GIrNode *node) for (l = enum_->values; l; l = l->next) _g_ir_node_free ((GIrNode *)l->data); g_list_free (enum_->values); + + for (l = enum_->methods; l; l = l->next) + _g_ir_node_free ((GIrNode *)l->data); + g_list_free (enum_->methods); } break; @@ -467,6 +471,8 @@ _g_ir_node_get_size (GIrNode *node) size = sizeof (EnumBlob); for (l = enum_->values; l; l = l->next) size += _g_ir_node_get_size ((GIrNode *)l->data); + for (l = enum_->methods; l; l = l->next) + size += _g_ir_node_get_size ((GIrNode *)l->data); } break; @@ -718,6 +724,8 @@ _g_ir_node_get_full_size_internal (GIrNode *parent, for (l = enum_->values; l; l = l->next) size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); + for (l = enum_->methods; l; l = l->next) + size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); } break; @@ -2030,7 +2038,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob->error_domain = 0; blob->n_values = 0; - blob->reserved2 = 0; + blob->n_methods = 0; for (l = enum_->values; l; l = l->next) { @@ -2039,6 +2047,14 @@ _g_ir_node_build_typelib (GIrNode *node, blob->n_values++; _g_ir_node_build_typelib (value, node, build, offset, offset2); } + + for (l = enum_->methods; l; l = l->next) + { + GIrNode *method = (GIrNode *)l->data; + + blob->n_methods++; + _g_ir_node_build_typelib (method, node, build, offset, offset2); + } } break; diff --git a/girnode.h b/girnode.h index 6e03821ba..328634556 100644 --- a/girnode.h +++ b/girnode.h @@ -288,6 +288,7 @@ struct _GIrNodeEnum gchar *error_domain; GList *values; + GList *methods; }; struct _GIrNodeBoxed diff --git a/girparser.c b/girparser.c index c9b7d6292..6984e8266 100644 --- a/girparser.c +++ b/girparser.c @@ -805,6 +805,9 @@ start_function (GMarkupParseContext *context, strcmp (element_name, "method") == 0 || strcmp (element_name, "callback") == 0); break; + case STATE_ENUM: + found = strcmp (element_name, "function") == 0; + break; case STATE_STRUCT_FIELD: found = (found || strcmp (element_name, "callback") == 0); break; @@ -925,6 +928,15 @@ start_function (GMarkupParseContext *context, union_->members = g_list_append (union_->members, function); } break; + case G_IR_NODE_ENUM: + case G_IR_NODE_FLAGS: + { + GIrNodeEnum *enum_; + + enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx); + enum_->methods = g_list_append (enum_->methods, function); + } + break; default: g_assert_not_reached (); } @@ -3186,6 +3198,9 @@ end_element_handler (GMarkupParseContext *context, state_switch (ctx, STATE_STRUCT); else if (CURRENT_NODE (ctx)->type == G_IR_NODE_UNION) state_switch (ctx, STATE_UNION); + else if (CURRENT_NODE (ctx)->type == G_IR_NODE_ENUM || + CURRENT_NODE (ctx)->type == G_IR_NODE_FLAGS) + state_switch (ctx, STATE_ENUM); else { int line_number, char_number; @@ -3256,6 +3271,8 @@ end_element_handler (GMarkupParseContext *context, case STATE_ENUM: if (strcmp ("member", element_name) == 0) break; + else if (strcmp ("function", element_name) == 0) + break; else if (require_one_of_end_elements (context, ctx, element_name, error, "enumeration", "bitfield", NULL)) diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 1dde5163b..f450a2fb7 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -800,8 +800,10 @@ typedef struct { * @gtype_init: String naming the symbol which gets the runtime #GType * @error_domain: String naming the #GError domain this enum is * associated with - * @n_values: The lengths of the values arrays. + * @n_values: The length of the values array. + * @n_methods: The length of the methods array. * @values: Describes the enum values. + * @methods: Describes the enum methods. */ typedef struct { guint16 blob_type; @@ -817,11 +819,14 @@ typedef struct { guint32 gtype_init; guint16 n_values; - guint16 reserved2; + guint16 n_methods; guint32 error_domain; ValueBlob values[]; +#if 0 + FunctionBlob methods[]; +#endif } EnumBlob; /** diff --git a/gitypelib.c b/gitypelib.c index f610d4586..2e5b0e1b2 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -1428,6 +1428,7 @@ validate_enum_blob (ValidateContext *ctx, GITypelib *typelib = ctx->typelib; EnumBlob *blob; gint i; + guint32 offset2; if (typelib->len < offset + sizeof (EnumBlob)) { @@ -1473,7 +1474,8 @@ validate_enum_blob (ValidateContext *ctx, return FALSE; if (typelib->len < offset + sizeof (EnumBlob) + - blob->n_values * sizeof (ValueBlob)) + blob->n_values * sizeof (ValueBlob) + + blob->n_methods * sizeof (FunctionBlob)) { g_set_error (error, G_TYPELIB_ERROR, @@ -1482,22 +1484,22 @@ validate_enum_blob (ValidateContext *ctx, return FALSE; } + offset2 = offset + sizeof (EnumBlob); + push_context (ctx, get_string_nofail (typelib, blob->name)); - for (i = 0; i < blob->n_values; i++) + for (i = 0; i < blob->n_values; i++, offset2 += sizeof (ValueBlob)) { if (!validate_value_blob (typelib, - offset + sizeof (EnumBlob) + - i * sizeof (ValueBlob), + offset2, error)) return FALSE; #if 0 - v1 = (ValueBlob *)&typelib->data[offset + sizeof (EnumBlob) + - i * sizeof (ValueBlob)]; + v1 = (ValueBlob *)&typelib->data[offset2]; for (j = 0; j < i; j++) { - v2 = (ValueBlob *)&typelib->data[offset + sizeof (EnumBlob) + + v2 = (ValueBlob *)&typelib->data[offset2 + j * sizeof (ValueBlob)]; if (v1->value == v2->value) @@ -1514,6 +1516,12 @@ validate_enum_blob (ValidateContext *ctx, #endif } + for (i = 0; i < blob->n_methods; i++, offset2 += sizeof (FunctionBlob)) + { + if (!validate_function_blob (ctx, offset2, BLOB_TYPE_ENUM, error)) + return FALSE; + } + pop_context (ctx); return TRUE; From 13069a377f7c48f86ce95f9fa5f5b6030cd6c727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20Sch=C3=B6nfeld?= Date: Thu, 18 Aug 2011 22:51:57 +0200 Subject: [PATCH 453/692] Add 'Since:' tags to the newly added GIEnumInfo methods --- gienuminfo.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gienuminfo.c b/gienuminfo.c index 90b19a96f..eeade7561 100644 --- a/gienuminfo.c +++ b/gienuminfo.c @@ -118,6 +118,8 @@ g_enum_info_get_value (GIEnumInfo *info, * Obtain the number of methods that this enum type has. * * Returns: number of methods + * + * Since: 1.29.17 */ gint g_enum_info_get_n_methods (GIEnumInfo *info) @@ -142,6 +144,8 @@ g_enum_info_get_n_methods (GIEnumInfo *info) * * Returns: (transfer full): the #GIFunctionInfo. Free the struct by calling * g_base_info_unref() when done. + * + * Since: 1.29.17 */ GIFunctionInfo * g_enum_info_get_method (GIEnumInfo *info, From b8010062b5eeac19b1cbfa9977532d039ca985a8 Mon Sep 17 00:00:00 2001 From: Pavel Holejsovsky Date: Fri, 19 Aug 2011 21:20:10 +0200 Subject: [PATCH 454/692] Fix g_irepository_find_by_gtype() for GDK_TYPE_RECTANGLE Complement fix for g-ir-scanner which converts every GdkRectangle gtype to CairoRectangleInt. Make sure that C-side API is also aware of this workaround. Use case requiring this patch: When binding implementation wants to get/set property, it can use either GI-based approach (g_property_info_xxx() funcs), or just GLib facilities. Although former is probably preferred, there are cases when latter is still needed (e.g. gstreamer uses dynamic properties, which are not present in the gir). In this case, binding implementation queries the type of the propertyb (using g_object_class_find_property()), it gets GDK_TYPE_RECTANGLE, and without the patch it cannot map it to any known type. https://bugzilla.gnome.org/show_bug.cgi?id=655423 --- gitypelib.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/gitypelib.c b/gitypelib.c index 2e5b0e1b2..dcc265119 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -208,6 +208,17 @@ g_typelib_get_dir_entry_by_gtype (GITypelib *typelib, guint i; const char *c_prefix; + /* There is a corner case regarding GdkRectangle. GdkRectangle is a + boxed type, but it is just an alias to boxed struct + CairoRectangleInt. Scanner automatically converts all references + to GdkRectangle to CairoRectangleInt, so GdkRectangle does not + appear in the typelibs at all, although user code might query it. + So if we get such query, we also change it to lookup of + CairoRectangleInt. + https://bugzilla.gnome.org/show_bug.cgi?id=655423 */ + if (!fastpass && !strcmp (gtype_name, "GdkRectangle")) + gtype_name = "CairoRectangleInt"; + /* Inside each typelib, we include the "C prefix" which acts as * a namespace mechanism. For GtkTreeView, the C prefix is Gtk. * Given the assumption that GTypes for a library also use the From 6f0cf9a0aa618613c37a4a1bd642fde5aa299af9 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 3 Sep 2011 12:02:54 -0400 Subject: [PATCH 455/692] girffi: Remove unnecessary sys/mman.h include While we're here move config.h to the top for consistency. --- girffi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/girffi.c b/girffi.c index b5d359732..aae1dcc38 100644 --- a/girffi.c +++ b/girffi.c @@ -19,10 +19,10 @@ * Boston, MA 02111-1307, USA. */ -#include -#include +#include "config.h" + +#include -#include #include #include #include From 61c8a0dda20c7318ea990513992a4efaf4394a7d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 3 Sep 2011 12:34:29 -0400 Subject: [PATCH 456/692] gi-dump-types: New uninstalled debugging program Usage: ./_build/gi-dump-types g_object_get_type --- gdump.c | 2 ++ gi-dump-types.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 gi-dump-types.c diff --git a/gdump.c b/gdump.c index aab067b6f..c237a81ef 100644 --- a/gdump.c +++ b/gdump.c @@ -431,6 +431,8 @@ dump_error_quark (GQuark quark, const char *symbol, GOutputStream *out) */ #ifndef G_IREPOSITORY_COMPILATION static gboolean +dump_irepository (const char *arg, GError **error) G_GNUC_UNUSED; +static gboolean dump_irepository (const char *arg, GError **error) #else gboolean diff --git a/gi-dump-types.c b/gi-dump-types.c new file mode 100644 index 000000000..eacf8a01d --- /dev/null +++ b/gi-dump-types.c @@ -0,0 +1,34 @@ +#include "gdump.c" +#include + +int +main (int argc, + char **argv) +{ + int i; + GOutputStream *stdout; + GModule *self; + + g_type_init (); + + stdout = g_unix_output_stream_new (1, FALSE); + + self = g_module_open (NULL, 0); + + for (i = 1; i < argc; i++) + { + GError *error = NULL; + GType type; + + type = invoke_get_type (self, argv[i], &error); + if (!type) + { + g_printerr ("%s\n", error->message); + g_clear_error (&error); + } + else + dump_type (type, argv[i], stdout); + } + + return 0; +} From 522ebcd2d6d164eedbf1851ce4b241dc70e74520 Mon Sep 17 00:00:00 2001 From: Dieter Verfaillie Date: Mon, 5 Sep 2011 17:00:37 +0200 Subject: [PATCH 457/692] Windows port: cmph_time.h includes sys/resource.h which is not available on Windows. So only include it when WIN32 is not defined. https://bugzilla.gnome.org/show_bug.cgi?id=620566 --- cmph/cmph_time.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/cmph/cmph_time.h b/cmph/cmph_time.h index d8018090c..c03558fb6 100644 --- a/cmph/cmph_time.h +++ b/cmph/cmph_time.h @@ -6,12 +6,10 @@ #undef ELAPSED_TIME_IN_uSECONDS #endif -#ifdef WIN32 -// include headers to use gettimeofday -#else - #ifdef __GNUC__ +#ifdef __GNUC__ #include - #include + #ifndef WIN32 + #include #endif #endif From 846196233701649d4b7641a201b18ef963b41a5f Mon Sep 17 00:00:00 2001 From: Dieter Verfaillie Date: Mon, 5 Sep 2011 17:19:39 +0200 Subject: [PATCH 458/692] Windows port: compute GOBJECT_INTROSPECTION_LIBDIR at runtime. Otherwise, we fail to properly locate the typelibs, because on Windows the value of GOBJECT_INTROSPECTION_LIBDIR depends on where Glib has been installed. Due to the nature of how we handle software that depends on Glib on Windows (it is recommended that each program bundles it's private copy), we're working in a "multi-prefixed" environment. Hence the value computed at build time will most likely not even exist at runtime. https://bugzilla.gnome.org/show_bug.cgi?id=620566 --- girepository.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/girepository.c b/girepository.c index a2a778d91..cc81107fa 100644 --- a/girepository.c +++ b/girepository.c @@ -50,6 +50,39 @@ struct _GIRepositoryPrivate G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT); +#ifdef G_PLATFORM_WIN32 + +#include + +static HMODULE girepository_dll = NULL; + +#ifdef DLL_EXPORT + +BOOL WINAPI +DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved) +{ + if (fdwReason == DLL_PROCESS_ATTACH) + girepository_dll = hinstDLL; + + return TRUE; +} + +#endif + +#undef GOBJECT_INTROSPECTION_LIBDIR + +/* GOBJECT_INTROSPECTION_LIBDIR is used only in code called just once, + * so no problem leaking this + */ +#define GOBJECT_INTROSPECTION_LIBDIR \ + g_build_filename (g_win32_get_package_installation_directory_of_module (girepository_dll), \ + "lib", \ + NULL) + +#endif + static void g_irepository_init (GIRepository *repository) { From 87fd1d5dadf17efdb408faf27573fee4c48b5f03 Mon Sep 17 00:00:00 2001 From: Pavel Holejsovsky Date: Mon, 12 Sep 2011 19:54:39 +0200 Subject: [PATCH 459/692] Fix g_type_info_is_pointer() for overriden types of arguments. Algorithm which detects whether argument type is pointer checks for trailing '*' characters in c:type .gir elements. This failed if ctype is either 'gpointer' or 'gconstpointer'. Add specific check for gpointer/gconstpointer types when deducing pointerness of the type. https://bugzilla.gnome.org/show_bug.cgi?id=658848 --- girparser.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/girparser.c b/girparser.c index 6984e8266..0a4a65d88 100644 --- a/girparser.c +++ b/girparser.c @@ -1947,6 +1947,10 @@ start_type (GMarkupParseContext *context, const char *cp = ctype + strlen(ctype) - 1; while (cp > ctype && *cp-- == '*') pointer_depth++; + + if (g_str_has_prefix (ctype, "gpointer") + || g_str_has_prefix (ctype, "gconstpointer")) + pointer_depth++; } if (ctx->current_typed->type == G_IR_NODE_PARAM && From 11cf4c56f3e8d218fe0c27f90331cab50cd60d66 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 21 Sep 2011 13:13:45 -0400 Subject: [PATCH 460/692] repository: Fix g_irepository_get_c_prefix() It was returning the wrong data. https://bugzilla.gnome.org/show_bug.cgi?id=659749 --- girepository.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girepository.c b/girepository.c index cc81107fa..b5cd4c7c3 100644 --- a/girepository.c +++ b/girepository.c @@ -929,7 +929,7 @@ g_irepository_get_c_prefix (GIRepository *repository, g_return_val_if_fail (typelib != NULL, NULL); header = (Header *) typelib->data; - if (header->shared_library) + if (header->c_prefix) return g_typelib_get_string (typelib, header->c_prefix); else return NULL; From b75e788785c8cebe53fa4d86405a1a09be3a9c64 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 5 Oct 2011 16:31:43 -0400 Subject: [PATCH 461/692] giconstantinfo: Add API to fix memory leak https://bugzilla.gnome.org/show_bug.cgi?id=654069 --- giconstantinfo.c | 30 ++++++++++++++++++++++++++++++ giconstantinfo.h | 2 ++ 2 files changed, 32 insertions(+) diff --git a/giconstantinfo.c b/giconstantinfo.c index c0823030d..2c3cc2922 100644 --- a/giconstantinfo.c +++ b/giconstantinfo.c @@ -68,6 +68,35 @@ g_constant_info_get_type (GIConstantInfo *info) #define DO_ALIGNED_COPY(dest_addr, src_addr, type) \ memcpy((dest_addr), (src_addr), sizeof(type)) +/** + * g_constant_info_free_value: (skip) + * @info: a #GIConstantInfo + * @value: the argument + * + * Free the value returned from g_constant_info_get_value(). + * + * Since: 1.30.1 + */ +void +g_constant_info_free_value (GIConstantInfo *info, + GIArgument *value) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + ConstantBlob *blob; + + g_return_if_fail (info != NULL); + g_return_if_fail (GI_IS_CONSTANT_INFO (info)); + + blob = (ConstantBlob *)&rinfo->typelib->data[rinfo->offset]; + + /* FIXME non-basic types ? */ + if (blob->type.flags.reserved == 0 && blob->type.flags.reserved2 == 0) + { + if (blob->type.flags.pointer) + g_free (value->v_pointer); + } +} + /** * g_constant_info_get_value: (skip) * @info: a #GIConstantInfo @@ -76,6 +105,7 @@ g_constant_info_get_type (GIConstantInfo *info) * Obtain the value associated with the #GIConstantInfo and store it in the * @value parameter. @argument needs to be allocated before passing it in. * The size of the constant value stored in @argument will be returned. + * Free the value with g_constant_info_free_value(). * * Returns: size of the constant */ diff --git a/giconstantinfo.h b/giconstantinfo.h index a2679bd24..2e7d697fa 100644 --- a/giconstantinfo.h +++ b/giconstantinfo.h @@ -34,6 +34,8 @@ G_BEGIN_DECLS (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_CONSTANT) GITypeInfo * g_constant_info_get_type (GIConstantInfo *info); +void g_constant_info_free_value(GIConstantInfo *info, + GIArgument *value); gint g_constant_info_get_value(GIConstantInfo *info, GIArgument *value); G_END_DECLS From c87a386cd178f86f2c49e48b2085c0e27a513bbd Mon Sep 17 00:00:00 2001 From: Alberto Ruiz Date: Tue, 18 Oct 2011 16:45:38 +0100 Subject: [PATCH 462/692] parser: prevents a segfault when _g_ir_parser_parse_string returns NULL error was not set. Noticed the segmentation fault while using Vala to generate a .gir, a bug has been filed tomake sure Vala doesn't export gir symbols outside of a namespace (see https://bugzilla.gnome.org/show_bug.cgi?id=661952) https://bugzilla.gnome.org/show_bug.cgi?id=661951 --- girparser.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/girparser.c b/girparser.c index 0a4a65d88..fd742f948 100644 --- a/girparser.c +++ b/girparser.c @@ -3502,6 +3502,11 @@ _g_ir_parser_parse_string (GIrParser *parser, if (ctx.modules) return ctx.modules->data; + + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Expected namespace element in the gir file"); return NULL; } From acd55584c2ca703a885f5c3908ef08ea2900f450 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Wed, 19 Oct 2011 23:26:35 +0100 Subject: [PATCH 463/692] Use the correct size when freeing unused info A GIBaseInfo struct can underneath either be GIRealInfo *or* GIUnresolvedInfo if the type is GI_INFO_TYPE_UNRESOLVED. So when we eventually free the structures slice use the correct struct type otherwise things get unhappy. --- gibaseinfo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gibaseinfo.c b/gibaseinfo.c index bfb774360..48af5c217 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -253,7 +253,10 @@ g_base_info_unref (GIBaseInfo *info) if (rinfo->repository) g_object_unref (rinfo->repository); - g_slice_free (GIRealInfo, rinfo); + if (rinfo->type == GI_INFO_TYPE_UNRESOLVED) + g_slice_free (GIUnresolvedInfo, rinfo); + else + g_slice_free (GIRealInfo, rinfo); } } From fd0625aa6ed9b071cf3c0abd650bb6fcd34b1bbd Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 28 Nov 2011 04:56:58 -0500 Subject: [PATCH 464/692] gibaseinfo: Fix compiler warnings g_slice_free complains when you pass it a pointer of a different type than it was expecting, like it should. https://bugzilla.gnome.org/show_bug.cgi?id=665249 --- gibaseinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gibaseinfo.c b/gibaseinfo.c index 48af5c217..ab4ce3cfc 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -254,7 +254,7 @@ g_base_info_unref (GIBaseInfo *info) g_object_unref (rinfo->repository); if (rinfo->type == GI_INFO_TYPE_UNRESOLVED) - g_slice_free (GIUnresolvedInfo, rinfo); + g_slice_free (GIUnresolvedInfo, (GIUnresolvedInfo *) rinfo); else g_slice_free (GIRealInfo, rinfo); } From cfcbd719ea2384bd8858959cd9155e5a5d8ac23f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 28 Nov 2011 04:59:47 -0500 Subject: [PATCH 465/692] gitypelib: Fix compiler warnings These variables are unused. https://bugzilla.gnome.org/show_bug.cgi?id=665249 --- gitypelib.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/gitypelib.c b/gitypelib.c index dcc265119..53a4bea8b 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -645,12 +645,9 @@ validate_error_type_blob (GITypelib *typelib, GError **error) { ErrorTypeBlob *blob; - Header *header; blob = (ErrorTypeBlob*)&typelib->data[offset]; - header = (Header *)typelib->data; - if (!blob->pointer) { g_set_error (error, @@ -850,8 +847,6 @@ validate_function_blob (ValidateContext *ctx, { GITypelib *typelib = ctx->typelib; FunctionBlob *blob; - SignatureBlob *sigblob; - gboolean is_method; if (typelib->len < offset + sizeof (FunctionBlob)) { @@ -881,19 +876,6 @@ validate_function_blob (ValidateContext *ctx, if (!validate_name (typelib, "function symbol", typelib->data, blob->symbol, error)) return FALSE; - switch (container_type) - { - case BLOB_TYPE_BOXED: - case BLOB_TYPE_STRUCT: - case BLOB_TYPE_UNION: - case BLOB_TYPE_OBJECT: - case BLOB_TYPE_INTERFACE: - is_method = !(blob->constructor || blob->setter || blob->getter || blob->wraps_vfunc); - break; - default: - is_method = FALSE; - } - if (blob->constructor) { switch (container_type) @@ -946,8 +928,6 @@ validate_function_blob (ValidateContext *ctx, if (!validate_signature_blob (typelib, blob->signature, error)) return FALSE; - sigblob = (SignatureBlob*) &typelib->data[blob->signature]; - if (blob->constructor) { SimpleTypeBlob *simple = return_type_from_signature (typelib, From c99df8f34ca63f4192241b0d8f09003d3d065aa5 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 21 Dec 2011 15:55:18 -0500 Subject: [PATCH 466/692] ffi: Treat enums as 32 bit signed values to fix PPC64 To call a function dynamically using ffi, the caller first has to tell ffi the size of all the input arguments of the function. On little endian architectures (like x86_64) specifying a size that's too large will happen to work because of how the bits are laid out in memory. On big endian architectures, however, specifying the wrong size can lead to reading the wrong bits. The function g_type_info_get_ffi_type maps input giargument types to specific sizes. It was assuming enums were word (pointer) sized; in fact they can be in theory any size (1,2,4,8 bytes), but in practice in introspection (via GIArgument) as well as GValue we're limited to 4 byte enums. This commit fixes PPC64 (big endian, 64 bit). Signed-off-by: Colin Walters https://bugzilla.gnome.org/show_bug.cgi?id=665150 --- girffi.c | 60 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/girffi.c b/girffi.c index aae1dcc38..1fa483964 100644 --- a/girffi.c +++ b/girffi.c @@ -30,16 +30,10 @@ #include "girepository.h" #include "girepository-private.h" -/** - * gi_type_tag_get_ffi_type: - * @tag: A #GITypeTag - * @is_pointer: Whether or not this is a pointer type - * - * Returns: A #ffi_type corresponding to the platform default C ABI for @tag and @is_pointer. - */ -ffi_type * -gi_type_tag_get_ffi_type (GITypeTag tag, - gboolean is_pointer) +static ffi_type * +gi_type_tag_get_ffi_type_internal (GITypeTag tag, + gboolean is_pointer, + gboolean is_enum) { switch (tag) { @@ -77,12 +71,21 @@ gi_type_tag_get_ffi_type (GITypeTag tag, case GI_TYPE_TAG_UTF8: case GI_TYPE_TAG_FILENAME: 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: case GI_TYPE_TAG_ERROR: return &ffi_type_pointer; + case GI_TYPE_TAG_INTERFACE: + { + /* We need to handle enums specially: + * https://bugzilla.gnome.org/show_bug.cgi?id=665150 + */ + if (!is_enum) + return &ffi_type_pointer; + else + return &ffi_type_sint32; + } case GI_TYPE_TAG_VOID: if (is_pointer) return &ffi_type_pointer; @@ -95,6 +98,20 @@ gi_type_tag_get_ffi_type (GITypeTag tag, return NULL; } +/** + * gi_type_tag_get_ffi_type: + * @tag: A #GITypeTag + * @is_pointer: Whether or not this is a pointer type + * + * Returns: A #ffi_type corresponding to the platform default C ABI for @tag and @is_pointer. + */ +ffi_type * +gi_type_tag_get_ffi_type (GITypeTag tag, + gboolean is_pointer) +{ + return gi_type_tag_get_ffi_type_internal (tag, is_pointer, FALSE); +} + /** * g_type_info_get_ffi_type: * @info: A #GITypeInfo @@ -104,7 +121,26 @@ gi_type_tag_get_ffi_type (GITypeTag tag, ffi_type * g_type_info_get_ffi_type (GITypeInfo *info) { - return gi_type_tag_get_ffi_type (g_type_info_get_tag (info), g_type_info_is_pointer (info)); + gboolean is_enum; + GIBaseInfo *iinfo; + + if (g_type_info_get_tag (info) == GI_TYPE_TAG_INTERFACE) + { + iinfo = g_type_info_get_interface (info); + switch (g_base_info_get_type (iinfo)) + { + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + is_enum = TRUE; + break; + default: + is_enum = FALSE; + break; + } + g_base_info_unref (iinfo); + } + + return gi_type_tag_get_ffi_type_internal (g_type_info_get_tag (info), g_type_info_is_pointer (info), is_enum); } /** From c18e0be5494b4884041c03cb8e4fc1c831bdbb7a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 12 Dec 2011 16:14:57 -0500 Subject: [PATCH 467/692] repository: Squash memory leak in _get_func and fix up style --- giobjectinfo.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/giobjectinfo.c b/giobjectinfo.c index fbf5d8ab2..4aca8bd45 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -756,28 +756,30 @@ _get_func(GIObjectInfo *info, const char* symbol; GSList *parents = NULL, *l; GIObjectInfo *parent_info; + gpointer func = NULL; parent_info = info; - while (parent_info != NULL) { - parents = g_slist_prepend(parents, parent_info); - parent_info = g_object_info_get_parent(parent_info); - } - - for (l = parents; l; l = l->next) { - GIObjectInfoRefFunction func; - parent_info = l->data; - symbol = getter(parent_info); - if (symbol == NULL) - continue; - if (g_typelib_symbol (((GIRealInfo *)parent_info)->typelib, symbol, (void**) &func)) { - g_slist_free(parents); - return func; + while (parent_info != NULL) + { + parents = g_slist_prepend (parents, parent_info); + parent_info = g_object_info_get_parent (parent_info); } - } - g_slist_free(parents); - return NULL; + for (l = parents; l; l = l->next) + { + GIObjectInfoRefFunction func; + parent_info = l->data; + symbol = getter (parent_info); + if (symbol == NULL) + continue; + g_typelib_symbol (((GIRealInfo *)parent_info)->typelib, symbol, (gpointer*) &func); + if (func) + break; + } + + g_slist_free_full (parents, (GDestroyNotify) g_base_info_unref); + return func; } /** From 3e1486f9244785afbef655ac5656dcc68e90602e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 6 Jan 2012 14:55:45 -0500 Subject: [PATCH 468/692] girffi: Fix compiler warnings --- girffi.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/girffi.c b/girffi.c index 1fa483964..3bddb7240 100644 --- a/girffi.c +++ b/girffi.c @@ -121,22 +121,21 @@ gi_type_tag_get_ffi_type (GITypeTag tag, ffi_type * g_type_info_get_ffi_type (GITypeInfo *info) { - gboolean is_enum; + gboolean is_enum = FALSE; GIBaseInfo *iinfo; if (g_type_info_get_tag (info) == GI_TYPE_TAG_INTERFACE) { iinfo = g_type_info_get_interface (info); switch (g_base_info_get_type (iinfo)) - { - case GI_INFO_TYPE_ENUM: - case GI_INFO_TYPE_FLAGS: - is_enum = TRUE; - break; - default: - is_enum = FALSE; - break; - } + { + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + is_enum = TRUE; + break; + default: + break; + } g_base_info_unref (iinfo); } @@ -198,13 +197,11 @@ static ffi_type * g_callable_info_get_ffi_return_type (GICallableInfo *callable_info) { GITypeInfo *return_type; - GITypeTag type_tag; ffi_type *return_ffi_type; g_return_val_if_fail (callable_info != NULL, NULL); return_type = g_callable_info_get_return_type (callable_info); - type_tag = g_type_info_get_tag (return_type); return_ffi_type = g_type_info_get_ffi_type (return_type); g_base_info_unref((GIBaseInfo*)return_type); From a0d19ca066398a3ebfcbc7e2cee9ed634216946f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 28 Nov 2011 14:51:04 -0500 Subject: [PATCH 469/692] girffi: Add new g_function_invoker_new_for_address This is a new method designed to make a GIFunctionInvoker for any GICallableInfo*, for bindings to use. --- girffi.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++---------- girffi.h | 5 ++++ 2 files changed, 70 insertions(+), 14 deletions(-) diff --git a/girffi.c b/girffi.c index 3bddb7240..2e8fe3377 100644 --- a/girffi.c +++ b/girffi.c @@ -230,13 +230,7 @@ g_function_info_prep_invoker (GIFunctionInfo *info, GError **error) { const char *symbol; - ffi_type *rtype; - ffi_type **atypes; - GITypeInfo *tinfo; - GIArgInfo *ainfo; - gboolean is_method; - gboolean throws; - gint n_args, n_invoke_args, i; + gpointer addr; g_return_val_if_fail (info != NULL, FALSE); g_return_val_if_fail (invoker != NULL, FALSE); @@ -244,7 +238,7 @@ g_function_info_prep_invoker (GIFunctionInfo *info, symbol = g_function_info_get_symbol ((GIFunctionInfo*) info); if (!g_typelib_symbol (g_base_info_get_typelib((GIBaseInfo *) info), - symbol, &(invoker->native_address))) + symbol, &addr)) { g_set_error (error, G_INVOKE_ERROR, @@ -254,15 +248,72 @@ g_function_info_prep_invoker (GIFunctionInfo *info, return FALSE; } - is_method = (g_function_info_get_flags (info) & GI_FUNCTION_IS_METHOD) != 0 - && (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR) == 0; - throws = g_function_info_get_flags (info) & GI_FUNCTION_THROWS; + return g_function_invoker_new_for_address (addr, info, invoker, error); +} - tinfo = g_callable_info_get_return_type ((GICallableInfo *)info); +/** + * g_function_invoker_new_for_address: + * @addr: The address + * @info: A #GICallableInfo + * @invoker: Output invoker structure + * @error: A #GError + * + * Initialize the caller-allocated @invoker structure with a cache + * of information needed to invoke the C function corresponding to + * @info with the platform's default ABI. + * + * A primary intent of this function is that a dynamic structure allocated + * by a language binding could contain a #GIFunctionInvoker structure + * inside the binding's function mapping. + * + * Returns: %TRUE on success, %FALSE otherwise with @error set. + */ +gboolean +g_function_invoker_new_for_address (gpointer addr, + GICallableInfo *info, + GIFunctionInvoker *invoker, + GError **error) +{ + ffi_type *rtype; + ffi_type **atypes; + GITypeInfo *tinfo; + GIArgInfo *ainfo; + GIInfoType info_type; + gboolean is_method; + gboolean throws; + gint n_args, n_invoke_args, i; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (invoker != NULL, FALSE); + + invoker->native_address = addr; + + info_type = g_base_info_get_type ((GIBaseInfo *) info); + + switch (info_type) + { + case GI_INFO_TYPE_FUNCTION: + { + GIFunctionInfoFlags flags; + flags = g_function_info_get_flags ((GIFunctionInfo *)info); + is_method = (flags & GI_FUNCTION_IS_METHOD) != 0; + throws = (flags & GI_FUNCTION_THROWS) != 0; + } + break; + case GI_INFO_TYPE_CALLBACK: + case GI_INFO_TYPE_VFUNC: + is_method = TRUE; + throws = FALSE; + break; + default: + g_assert_not_reached (); + } + + tinfo = g_callable_info_get_return_type (info); rtype = g_type_info_get_ffi_type (tinfo); g_base_info_unref ((GIBaseInfo *)tinfo); - n_args = g_callable_info_get_n_args ((GICallableInfo *)info); + n_args = g_callable_info_get_n_args (info); if (is_method) n_invoke_args = n_args+1; else @@ -282,7 +333,7 @@ g_function_info_prep_invoker (GIFunctionInfo *info, for (i = 0; i < n_args; i++) { int offset = (is_method ? 1 : 0); - ainfo = g_callable_info_get_arg ((GICallableInfo *)info, i); + ainfo = g_callable_info_get_arg (info, i); switch (g_arg_info_get_direction (ainfo)) { case GI_DIRECTION_IN: diff --git a/girffi.h b/girffi.h index a5cc9e460..3b3e9c74b 100644 --- a/girffi.h +++ b/girffi.h @@ -53,6 +53,11 @@ gboolean g_function_info_prep_invoker (GIFunctionInfo *info, GIFunctionInvoker *invoker, GError **error); +gboolean g_function_invoker_new_for_address (gpointer addr, + GICallableInfo *info, + GIFunctionInvoker *invoker, + GError **error); + void g_function_invoker_destroy (GIFunctionInvoker *invoker); From 3aaf08b49d8d38bfa580987a5219796629c815f3 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 4 Jan 2012 14:46:51 -0500 Subject: [PATCH 470/692] giobjectinfo: Add g_object_info_find_vfunc_using_interfaces As an analogue to g_object_info_find_method_using_interfaces, add a new API so that we can find a vfunc using the same strategy. --- giobjectinfo.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ giobjectinfo.h | 3 +++ 2 files changed, 63 insertions(+) diff --git a/giobjectinfo.c b/giobjectinfo.c index 4aca8bd45..32a5b0c51 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -659,6 +659,66 @@ g_object_info_find_vfunc (GIObjectInfo *info, return _g_base_info_find_vfunc (rinfo, offset, blob->n_vfuncs, name); } +/** + * g_object_info_find_vfunc_using_interfaces: + * @info: a #GIObjectInfo + * @name: name of method to obtain + * @implementor: (out) (transfer full): The implementor of the interface + * + * Locate a virtual function slot with name @name, searching both the object + * @info and any interfaces it implements. Note that the namespace for + * virtuals is distinct from that of methods; there may or may not be a + * concrete method associated for a virtual. If there is one, it may be + * retrieved using g_vfunc_info_get_invoker(), otherwise %NULL will be + * returned. + * + * Note that this function does *not* search parent classes; you will have + * to chain up if that's desired. + * + * Returns: (transfer full): the #GIFunctionInfo. Free the struct by calling + * g_base_info_unref() when done. + */ +GIVFuncInfo * +g_object_info_find_vfunc_using_interfaces (GIObjectInfo *info, + const gchar *name, + GIObjectInfo **implementor) +{ + GIVFuncInfo *result = NULL; + GIObjectInfo *implementor_result = NULL; + + result = g_object_info_find_vfunc (info, name); + if (result) + implementor_result = g_base_info_ref ((GIBaseInfo*) info); + + if (result == NULL) + { + int n_interfaces; + int i; + + n_interfaces = g_object_info_get_n_interfaces (info); + for (i = 0; i < n_interfaces; ++i) + { + GIInterfaceInfo *iface_info; + + iface_info = g_object_info_get_interface (info, i); + + result = g_interface_info_find_vfunc (iface_info, name); + + if (result != NULL) + { + implementor_result = iface_info; + break; + } + g_base_info_unref ((GIBaseInfo*) iface_info); + } + } + if (implementor) + *implementor = implementor_result; + else if (implementor_result != NULL) + g_base_info_unref ((GIBaseInfo*) implementor_result); + return result; +} + /** * g_object_info_get_n_constants: * @info: a #GIObjectInfo diff --git a/giobjectinfo.h b/giobjectinfo.h index fd35ef8f0..569c08390 100644 --- a/giobjectinfo.h +++ b/giobjectinfo.h @@ -108,6 +108,9 @@ GIVFuncInfo * g_object_info_get_vfunc (GIObjectInfo *info, gint n); GIVFuncInfo * g_object_info_find_vfunc (GIObjectInfo *info, const gchar *name); +GIVFuncInfo * g_object_info_find_vfunc_using_interfaces (GIObjectInfo *info, + const gchar *name, + GIObjectInfo **implementor); gint g_object_info_get_n_constants (GIObjectInfo *info); GIConstantInfo * g_object_info_get_constant (GIObjectInfo *info, gint n); From b9d098146094d58e89cb6bcbbf4039264251f299 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 3 Feb 2012 13:20:00 -0500 Subject: [PATCH 471/692] girepository: Add GI_VFUNC_THROWS Virtual functions can definitely throw an error. Right now the scanner omits the GError parameter for them and adds throws="1", but g-ir-compiler ignores this. https://bugzilla.gnome.org/show_bug.cgi?id=669332 --- girnode.c | 1 + girnode.h | 1 + girparser.c | 7 +++++++ girwriter.c | 3 +++ gitypelib-internal.h | 3 ++- gitypes.h | 4 +++- givfuncinfo.c | 3 +++ 7 files changed, 20 insertions(+), 2 deletions(-) diff --git a/girnode.c b/girnode.c index fcc8ce5e3..c5a70486f 100644 --- a/girnode.c +++ b/girnode.c @@ -1784,6 +1784,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob->must_be_implemented = 0; /* FIXME */ blob->must_not_be_implemented = 0; /* FIXME */ blob->class_closure = 0; /* FIXME */ + blob->throws = vfunc->throws; blob->reserved = 0; if (vfunc->invoker) diff --git a/girnode.h b/girnode.h index 328634556..018261ae1 100644 --- a/girnode.h +++ b/girnode.h @@ -206,6 +206,7 @@ struct _GIrNodeVFunc gboolean must_be_implemented; gboolean must_not_be_implemented; gboolean is_class_closure; + gboolean throws; char *invoker; diff --git a/girparser.c b/girparser.c index fd742f948..b5c4ee323 100644 --- a/girparser.c +++ b/girparser.c @@ -2345,6 +2345,7 @@ start_vfunc (GMarkupParseContext *context, const gchar *is_class_closure; const gchar *offset; const gchar *invoker; + const gchar *throws; GIrNodeInterface *iface; GIrNodeVFunc *vfunc; @@ -2362,6 +2363,7 @@ start_vfunc (GMarkupParseContext *context, is_class_closure = find_attribute ("is-class-closure", attribute_names, attribute_values); offset = find_attribute ("offset", attribute_names, attribute_values); invoker = find_attribute ("invoker", attribute_names, attribute_values); + throws = find_attribute ("throws", attribute_names, attribute_values); if (name == NULL) { @@ -2400,6 +2402,11 @@ start_vfunc (GMarkupParseContext *context, else vfunc->is_class_closure = FALSE; + if (throws && strcmp (throws, "1") == 0) + vfunc->throws = TRUE; + else + vfunc->throws = FALSE; + if (offset) vfunc->offset = atoi (offset); else diff --git a/girwriter.c b/girwriter.c index d9f916c55..7f5f7e872 100644 --- a/girwriter.c +++ b/girwriter.c @@ -916,6 +916,9 @@ write_vfunc_info (const gchar *namespace, else if (flags & GI_VFUNC_MUST_NOT_OVERRIDE) xml_printf (file, " override=\"never\""); + if (flags & GI_VFUNC_THROWS) + xml_printf (file, " throws=\"1\""); + xml_printf (file, " offset=\"%d\"", offset); if (invoker) diff --git a/gitypelib-internal.h b/gitypelib-internal.h index f450a2fb7..c6575d676 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -925,7 +925,8 @@ typedef struct { guint16 must_be_implemented : 1; guint16 must_not_be_implemented : 1; guint16 class_closure : 1; - guint16 reserved :12; + guint16 throws : 1; + guint16 reserved :11; guint16 signal; guint16 struct_offset; diff --git a/gitypes.h b/gitypes.h index cbe43168b..f83ea8bc7 100644 --- a/gitypes.h +++ b/gitypes.h @@ -403,6 +403,7 @@ typedef enum * @GI_VFUNC_MUST_CHAIN_UP: chains up to the parent type * @GI_VFUNC_MUST_OVERRIDE: overrides * @GI_VFUNC_MUST_NOT_OVERRIDE: does not override + * @GI_VFUNC_THROWS: Includes a #GError * * Flags of a #GIVFuncInfo struct. */ @@ -410,7 +411,8 @@ typedef enum { GI_VFUNC_MUST_CHAIN_UP = 1 << 0, GI_VFUNC_MUST_OVERRIDE = 1 << 1, - GI_VFUNC_MUST_NOT_OVERRIDE = 1 << 2 + GI_VFUNC_MUST_NOT_OVERRIDE = 1 << 2, + GI_VFUNC_THROWS = 1 << 3 } GIVFuncInfoFlags; /** diff --git a/givfuncinfo.c b/givfuncinfo.c index 332655a05..c55c28d75 100644 --- a/givfuncinfo.c +++ b/givfuncinfo.c @@ -104,6 +104,9 @@ g_vfunc_info_get_flags (GIVFuncInfo *info) if (blob->must_not_be_implemented) flags = flags | GI_VFUNC_MUST_NOT_OVERRIDE; + if (blob->throws) + flags = flags | GI_VFUNC_THROWS; + return flags; } From e865dcb7b4b0d5c847954bb33ba7262e0aa75524 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 3 Feb 2012 13:42:56 -0500 Subject: [PATCH 472/692] Add Emacs mode lines to C sources --- gdump.c | 3 ++- gi-dump-types.c | 1 + giarginfo.c | 3 ++- giarginfo.h | 3 ++- gibaseinfo.c | 3 ++- gibaseinfo.h | 3 ++- gicallableinfo.c | 3 ++- gicallableinfo.h | 3 ++- giconstantinfo.c | 3 ++- giconstantinfo.h | 3 ++- gienuminfo.c | 3 ++- gienuminfo.h | 3 ++- gifieldinfo.c | 3 ++- gifieldinfo.h | 3 ++- gifunctioninfo.c | 3 ++- gifunctioninfo.h | 3 ++- giinterfaceinfo.c | 3 ++- giinterfaceinfo.h | 3 ++- ginvoke.c | 3 ++- giobjectinfo.c | 3 ++- giobjectinfo.h | 3 ++- gipropertyinfo.c | 3 ++- gipropertyinfo.h | 3 ++- giregisteredtypeinfo.c | 3 ++- giregisteredtypeinfo.h | 3 ++- girepository-private.h | 4 ++-- girepository.c | 4 ++-- girepository.h | 3 ++- girffi.c | 3 ++- girffi.h | 3 ++- girmodule.c | 3 ++- girmodule.h | 3 ++- girnode.c | 3 ++- girnode.h | 3 ++- giroffsets.c | 3 ++- girparser.c | 3 ++- girparser.h | 3 ++- girwriter.c | 4 ++-- girwriter.h | 3 ++- gisignalinfo.c | 3 ++- gisignalinfo.h | 3 ++- gistructinfo.c | 3 ++- gistructinfo.h | 3 ++- gitypeinfo.c | 3 ++- gitypeinfo.h | 3 ++- gitypelib-internal.h | 3 ++- gitypelib.c | 3 ++- gitypelib.h | 3 ++- gitypes.h | 3 ++- giunioninfo.c | 3 ++- giunioninfo.h | 3 ++- givfuncinfo.c | 3 ++- givfuncinfo.h | 3 ++- glib-compat.h | 3 ++- gthash-test.c | 3 ++- gthash.c | 3 ++- 56 files changed, 111 insertions(+), 58 deletions(-) diff --git a/gdump.c b/gdump.c index c237a81ef..7e02d391f 100644 --- a/gdump.c +++ b/gdump.c @@ -1,4 +1,5 @@ -/* GObject introspection: Dump introspection data +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Dump introspection data * * Copyright (C) 2008 Colin Walters * diff --git a/gi-dump-types.c b/gi-dump-types.c index eacf8a01d..13e7ae68a 100644 --- a/gi-dump-types.c +++ b/gi-dump-types.c @@ -1,3 +1,4 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ #include "gdump.c" #include diff --git a/giarginfo.c b/giarginfo.c index 0d1f0bbf6..d61f4be24 100644 --- a/giarginfo.c +++ b/giarginfo.c @@ -1,4 +1,5 @@ -/* GObject introspection: Argument implementation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Argument implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/giarginfo.h b/giarginfo.h index 9daafa270..3f4163e30 100644 --- a/giarginfo.h +++ b/giarginfo.h @@ -1,4 +1,5 @@ -/* GObject introspection: Argument +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Argument * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gibaseinfo.c b/gibaseinfo.c index ab4ce3cfc..ff9c9395a 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -1,4 +1,5 @@ -/* GObject introspection: Base struct implementation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Base struct implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gibaseinfo.h b/gibaseinfo.h index 7bb1cab09..54c8ee4f3 100644 --- a/gibaseinfo.h +++ b/gibaseinfo.h @@ -1,4 +1,5 @@ -/* GObject introspection: GIBaseInfo +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: GIBaseInfo * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gicallableinfo.c b/gicallableinfo.c index 475346e22..28043fa52 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -1,4 +1,5 @@ -/* GObject introspection: Callable implementation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Callable implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gicallableinfo.h b/gicallableinfo.h index a1d22c749..0c5fac794 100644 --- a/gicallableinfo.h +++ b/gicallableinfo.h @@ -1,4 +1,5 @@ -/* GObject introspection: Callable +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Callable * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/giconstantinfo.c b/giconstantinfo.c index 2c3cc2922..88220b4e8 100644 --- a/giconstantinfo.c +++ b/giconstantinfo.c @@ -1,4 +1,5 @@ -/* GObject introspection: Constant implementation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Constant implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/giconstantinfo.h b/giconstantinfo.h index 2e7d697fa..2bbf95699 100644 --- a/giconstantinfo.h +++ b/giconstantinfo.h @@ -1,4 +1,5 @@ -/* GObject introspection: Constant +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Constant * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gienuminfo.c b/gienuminfo.c index eeade7561..a9b7c1df6 100644 --- a/gienuminfo.c +++ b/gienuminfo.c @@ -1,4 +1,5 @@ -/* GObject introspection: Enum implementation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Enum implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gienuminfo.h b/gienuminfo.h index def97f952..0b9a9e1be 100644 --- a/gienuminfo.h +++ b/gienuminfo.h @@ -1,4 +1,5 @@ -/* GObject introspection: Enum and Enum values +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Enum and Enum values * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gifieldinfo.c b/gifieldinfo.c index 41976855d..1d9a20ddc 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -1,4 +1,5 @@ -/* GObject introspection: Field implementation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Field implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gifieldinfo.h b/gifieldinfo.h index 589221b73..4ca540932 100644 --- a/gifieldinfo.h +++ b/gifieldinfo.h @@ -1,4 +1,5 @@ -/* GObject introspection: Field and Field values +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Field and Field values * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gifunctioninfo.c b/gifunctioninfo.c index 2544cc3f1..92f4ccd2d 100644 --- a/gifunctioninfo.c +++ b/gifunctioninfo.c @@ -1,4 +1,5 @@ -/* GObject introspection: Function implementation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Function implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gifunctioninfo.h b/gifunctioninfo.h index b2fa1f762..7a9ecae01 100644 --- a/gifunctioninfo.h +++ b/gifunctioninfo.h @@ -1,4 +1,5 @@ -/* GObject introspection: Function +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Function * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/giinterfaceinfo.c b/giinterfaceinfo.c index e3e721d8b..69cd63d90 100644 --- a/giinterfaceinfo.c +++ b/giinterfaceinfo.c @@ -1,4 +1,5 @@ -/* GObject introspection: Interface implementation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Interface implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/giinterfaceinfo.h b/giinterfaceinfo.h index 4f4c05c9f..8cab9961a 100644 --- a/giinterfaceinfo.h +++ b/giinterfaceinfo.h @@ -1,4 +1,5 @@ -/* GObject introspection: Interface +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Interface * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/ginvoke.c b/ginvoke.c index 0f9d22c94..84e1e748f 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -1,4 +1,5 @@ -/* GObject introspection: Invoke functionality +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Invoke functionality * * Copyright (C) 2005 Matthias Clasen * diff --git a/giobjectinfo.c b/giobjectinfo.c index 32a5b0c51..3b8f64bb8 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -1,4 +1,5 @@ -/* GObject introspection: Object implementation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Object implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/giobjectinfo.h b/giobjectinfo.h index 569c08390..ee4b8a823 100644 --- a/giobjectinfo.h +++ b/giobjectinfo.h @@ -1,4 +1,5 @@ -/* GObject introspection: Object +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Object * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gipropertyinfo.c b/gipropertyinfo.c index 552c0c3e2..61316cb9c 100644 --- a/gipropertyinfo.c +++ b/gipropertyinfo.c @@ -1,4 +1,5 @@ -/* GObject introspection: Property implementation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Property implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gipropertyinfo.h b/gipropertyinfo.h index 487389cba..14b18b417 100644 --- a/gipropertyinfo.h +++ b/gipropertyinfo.h @@ -1,4 +1,5 @@ -/* GObject introspection: Property +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Property * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/giregisteredtypeinfo.c b/giregisteredtypeinfo.c index 6c1b93217..6e3d31e2a 100644 --- a/giregisteredtypeinfo.c +++ b/giregisteredtypeinfo.c @@ -1,4 +1,5 @@ -/* GObject introspection: Registered Type implementation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Registered Type implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/giregisteredtypeinfo.h b/giregisteredtypeinfo.h index 76a1ee22d..d46d738bd 100644 --- a/giregisteredtypeinfo.h +++ b/giregisteredtypeinfo.h @@ -1,4 +1,5 @@ -/* GObject introspection: Registered Type +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Registered Type * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/girepository-private.h b/girepository-private.h index 52d65b2bd..05b13626b 100644 --- a/girepository-private.h +++ b/girepository-private.h @@ -1,5 +1,5 @@ -/* -*- Mode: C; c-file-style: "gnu"; -*- */ -/* GObject introspection: Private headers +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Private headers * * Copyright (C) 2010 Johan Dahlin * diff --git a/girepository.c b/girepository.c index b5cd4c7c3..5d561c288 100644 --- a/girepository.c +++ b/girepository.c @@ -1,5 +1,5 @@ -/* -*- Mode: C; c-file-style: "gnu"; -*- */ -/* GObject introspection: Repository implementation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Repository implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008 Colin Walters diff --git a/girepository.h b/girepository.h index 9e99f6e31..02bd4a109 100644 --- a/girepository.h +++ b/girepository.h @@ -1,4 +1,5 @@ -/* GObject introspection: Repository +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Repository * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/girffi.c b/girffi.c index 2e8fe3377..e727beabd 100644 --- a/girffi.c +++ b/girffi.c @@ -1,4 +1,5 @@ -/* GObject introspection: Helper functions for ffi integration +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Helper functions for ffi integration * * Copyright (C) 2008 Red Hat, Inc * Copyright (C) 2005 Matthias Clasen diff --git a/girffi.h b/girffi.h index 3b3e9c74b..e976f9241 100644 --- a/girffi.h +++ b/girffi.h @@ -1,4 +1,5 @@ -/* GObject introspection: Helper functions for ffi integration +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Helper functions for ffi integration * * Copyright (C) 2008 Red Hat, Inc * diff --git a/girmodule.c b/girmodule.c index f438a193b..af71f369b 100644 --- a/girmodule.c +++ b/girmodule.c @@ -1,4 +1,5 @@ -/* GObject introspection: Typelib creation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Typelib creation * * Copyright (C) 2005 Matthias Clasen * diff --git a/girmodule.h b/girmodule.h index c81dec322..7837f2cf2 100644 --- a/girmodule.h +++ b/girmodule.h @@ -1,4 +1,5 @@ -/* GObject introspection: Parsed IDL +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Parsed IDL * * Copyright (C) 2005 Matthias Clasen * diff --git a/girnode.c b/girnode.c index c5a70486f..881aa9be1 100644 --- a/girnode.c +++ b/girnode.c @@ -1,4 +1,5 @@ -/* GObject introspection: Typelib creation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Typelib creation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/girnode.h b/girnode.h index 018261ae1..d89847ac6 100644 --- a/girnode.h +++ b/girnode.h @@ -1,4 +1,5 @@ -/* GObject introspection: Parsed GIR +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Parsed GIR * * Copyright (C) 2005 Matthias Clasen * diff --git a/giroffsets.c b/giroffsets.c index 2c84b7071..e3c9d7f51 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -1,4 +1,5 @@ -/* GObject introspection: Compute structure offsets +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Compute structure offsets * * Copyright (C) 2008 Red Hat, Inc. * diff --git a/girparser.c b/girparser.c index b5c4ee323..041c65d70 100644 --- a/girparser.c +++ b/girparser.c @@ -1,4 +1,5 @@ -/* GObject introspection: A parser for the XML GIR format +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: A parser for the XML GIR format * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008 Philip Van Hoof diff --git a/girparser.h b/girparser.h index e56c63b51..4f79c7776 100644 --- a/girparser.h +++ b/girparser.h @@ -1,4 +1,5 @@ -/* GObject introspection: A parser for the XML GIR format +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: A parser for the XML GIR format * * Copyright (C) 2005 Matthias Clasen * diff --git a/girwriter.c b/girwriter.c index 7f5f7e872..73088a12f 100644 --- a/girwriter.c +++ b/girwriter.c @@ -1,5 +1,5 @@ -/* -*- Mode: C; c-file-style: "gnu"; -*- */ -/* GObject introspection: IDL generator +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: IDL generator * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/girwriter.h b/girwriter.h index 3ca7418b4..85f74a79e 100644 --- a/girwriter.h +++ b/girwriter.h @@ -1,4 +1,5 @@ -/* GObject introspection: IDL writer +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: IDL writer * * Copyright (C) 2007 Johan Dahlin * diff --git a/gisignalinfo.c b/gisignalinfo.c index ddc891a41..f4110c382 100644 --- a/gisignalinfo.c +++ b/gisignalinfo.c @@ -1,4 +1,5 @@ -/* GObject introspection: Signal implementation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Signal implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gisignalinfo.h b/gisignalinfo.h index 12054b003..e3a1e4a49 100644 --- a/gisignalinfo.h +++ b/gisignalinfo.h @@ -1,4 +1,5 @@ -/* GObject introspection: Signal +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Signal * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gistructinfo.c b/gistructinfo.c index ad1916830..dc17e3223 100644 --- a/gistructinfo.c +++ b/gistructinfo.c @@ -1,4 +1,5 @@ -/* GObject introspection: Struct implementation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Struct implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gistructinfo.h b/gistructinfo.h index 91296c1c7..1d10708eb 100644 --- a/gistructinfo.h +++ b/gistructinfo.h @@ -1,4 +1,5 @@ -/* GObject introspection: Struct +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Struct * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gitypeinfo.c b/gitypeinfo.c index 5864f82fe..a43fbc1bb 100644 --- a/gitypeinfo.c +++ b/gitypeinfo.c @@ -1,4 +1,5 @@ -/* GObject introspection: Type implementation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Type implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gitypeinfo.h b/gitypeinfo.h index 56e7309aa..ef834b12b 100644 --- a/gitypeinfo.h +++ b/gitypeinfo.h @@ -1,4 +1,5 @@ -/* GObject introspection: Type +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Type * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gitypelib-internal.h b/gitypelib-internal.h index c6575d676..08fb8500f 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -1,4 +1,5 @@ -/* GObject introspection: struct definitions for the binary +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: struct definitions for the binary * typelib format, validation * * Copyright (C) 2005 Matthias Clasen diff --git a/gitypelib.c b/gitypelib.c index 53a4bea8b..ae6b84587 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -1,4 +1,5 @@ -/* GObject introspection: typelib validation, auxiliary functions +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: typelib validation, auxiliary functions * related to the binary typelib format * * Copyright (C) 2005 Matthias Clasen diff --git a/gitypelib.h b/gitypelib.h index 2906a8f2c..52c5c4006 100644 --- a/gitypelib.h +++ b/gitypelib.h @@ -1,4 +1,5 @@ -/* GObject introspection: Public typelib API +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Public typelib API * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/gitypes.h b/gitypes.h index f83ea8bc7..486f20aa7 100644 --- a/gitypes.h +++ b/gitypes.h @@ -1,4 +1,5 @@ -/* GObject introspection: types +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: types * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/giunioninfo.c b/giunioninfo.c index 15a4c7d14..95b71123f 100644 --- a/giunioninfo.c +++ b/giunioninfo.c @@ -1,4 +1,5 @@ -/* GObject introspection: Union implementation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Union implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/giunioninfo.h b/giunioninfo.h index e42fe6f87..83696f765 100644 --- a/giunioninfo.h +++ b/giunioninfo.h @@ -1,4 +1,5 @@ -/* GObject introspection: Union +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Union * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/givfuncinfo.c b/givfuncinfo.c index c55c28d75..f80396c0c 100644 --- a/givfuncinfo.c +++ b/givfuncinfo.c @@ -1,4 +1,5 @@ -/* GObject introspection: Virtual Function implementation +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Virtual Function implementation * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/givfuncinfo.h b/givfuncinfo.h index 3c556cbe3..d8a8533b8 100644 --- a/givfuncinfo.h +++ b/givfuncinfo.h @@ -1,4 +1,5 @@ -/* GObject introspection: Virtual Functions +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Virtual Functions * * Copyright (C) 2005 Matthias Clasen * Copyright (C) 2008,2009 Red Hat, Inc. diff --git a/glib-compat.h b/glib-compat.h index a4d3e4994..2518092ca 100644 --- a/glib-compat.h +++ b/glib-compat.h @@ -1,4 +1,5 @@ -/* GObject introspection: Compatibility definitions +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Compatibility definitions * * Copyright (C) 2009 Javier Jardón * diff --git a/gthash-test.c b/gthash-test.c index a2e3cf82b..7909a0c85 100644 --- a/gthash-test.c +++ b/gthash-test.c @@ -1,4 +1,5 @@ -/* GObject introspection: Test typelib hashing +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Test typelib hashing * * Copyright (C) 2010 Red Hat, Inc. * diff --git a/gthash.c b/gthash.c index 5042ebe3e..8a3529592 100644 --- a/gthash.c +++ b/gthash.c @@ -1,4 +1,5 @@ -/* GObject introspection: Typelib hashing +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Typelib hashing * * Copyright (C) 2010 Red Hat, Inc. * From 04cf2f480d1fce9cd0bf12de103ca917e1412e6f Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 3 Feb 2012 13:47:17 -0500 Subject: [PATCH 473/692] girffi: Fix g_function_info_new_for_address to respect G_VFUNC_THROWS --- girffi.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/girffi.c b/girffi.c index e727beabd..d4c728a5c 100644 --- a/girffi.c +++ b/girffi.c @@ -301,8 +301,15 @@ g_function_invoker_new_for_address (gpointer addr, throws = (flags & GI_FUNCTION_THROWS) != 0; } break; - case GI_INFO_TYPE_CALLBACK: case GI_INFO_TYPE_VFUNC: + { + GIVFuncInfoFlags flags; + flags = g_vfunc_info_get_flags ((GIVFuncInfo *)info); + throws = (flags & GI_VFUNC_THROWS) != 0; + } + is_method = FALSE; + break; + case GI_INFO_TYPE_CALLBACK: is_method = TRUE; throws = FALSE; break; From c2d79efd539d44fcc9751ace9669185b50c9aaac Mon Sep 17 00:00:00 2001 From: Jesse van den Kieboom Date: Fri, 3 Feb 2012 17:11:59 +0100 Subject: [PATCH 474/692] Plug memory leak in lazy typelibs hash table https://bugzilla.gnome.org/show_bug.cgi?id=669317 --- girepository.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/girepository.c b/girepository.c index 5d561c288..1384c0e94 100644 --- a/girepository.c +++ b/girepository.c @@ -93,7 +93,9 @@ g_irepository_init (GIRepository *repository) (GDestroyNotify) NULL, (GDestroyNotify) g_typelib_free); repository->priv->lazy_typelibs - = g_hash_table_new (g_str_hash, g_str_equal); + = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) NULL); repository->priv->info_by_gtype = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) NULL, From 87857869e980643d17805773a337215ae430877e Mon Sep 17 00:00:00 2001 From: Thorsten Glaser Date: Wed, 8 Feb 2012 09:02:37 -0500 Subject: [PATCH 475/692] typelib: Fix invalid alignment assumptions The current source has invalid assumptions about structure alignment that break on platforms like m68k where 32-bit integers are aligned to 16-bit only. Fix this by introducing explicit structure padding for 32-bit quantities following odd numbers of 16-bit quantities and structure trail padding, to make the binary representation generated by the compiler match the text of the specification exactly. https://bugzilla.gnome.org/show_bug.cgi?id=661839 --- gitypelib-internal.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 08fb8500f..ed8e6792d 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -282,7 +282,7 @@ typedef struct { guint32 sections; /* */ - guint16 padding[5]; + guint16 padding[6]; } Header; typedef enum { @@ -434,6 +434,10 @@ typedef struct { gint8 closure; gint8 destroy; + /* */ + guint16 padding; + /* */ + SimpleTypeBlob arg_type; } ArgBlob; @@ -1051,6 +1055,8 @@ typedef struct { guint16 n_vfuncs; guint16 n_constants; + guint16 padding; + guint32 reserved2; guint32 reserved3; From a714bef96560307ca069fabf0d6ee32fa6d828c6 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 10 Feb 2012 10:19:17 -0500 Subject: [PATCH 476/692] girffi: Virtual functions are methods --- girffi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girffi.c b/girffi.c index d4c728a5c..114006139 100644 --- a/girffi.c +++ b/girffi.c @@ -307,7 +307,7 @@ g_function_invoker_new_for_address (gpointer addr, flags = g_vfunc_info_get_flags ((GIVFuncInfo *)info); throws = (flags & GI_VFUNC_THROWS) != 0; } - is_method = FALSE; + is_method = TRUE; break; case GI_INFO_TYPE_CALLBACK: is_method = TRUE; From 4359a037dbbbce54755d78823d92565e64c84061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean=20Br=C3=A9fort?= Date: Fri, 17 Feb 2012 11:48:35 -0500 Subject: [PATCH 477/692] repository: Ensure error is set if we're parsing a malformed file https://bugzilla.gnome.org/show_bug.cgi?id=661951 --- girparser.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/girparser.c b/girparser.c index 041c65d70..fa0de1f88 100644 --- a/girparser.c +++ b/girparser.c @@ -3511,10 +3511,11 @@ _g_ir_parser_parse_string (GIrParser *parser, if (ctx.modules) return ctx.modules->data; - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_INVALID_CONTENT, - "Expected namespace element in the gir file"); + if (error && *error == NULL) + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "Expected namespace element in the gir file"); return NULL; } From 0d58e2e9243a31ba8a75e20377a86f6bda9b3e0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 16 Feb 2012 11:25:55 -0500 Subject: [PATCH 478/692] repository: Fix conversion of FFI values on big-endian architectures Adapted from the fixes for (see bug 665152). It makes sure values are properly converted between glib and FFI, which is critical for big endian architectures. Patch adjusted to use GIArgument instead of custom union types by Colin Walters https://bugzilla.gnome.org/show_bug.cgi?id=668902 --- gicallableinfo.c | 103 +++++++++++++++++++++++++++++++-- ginvoke.c | 144 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 204 insertions(+), 43 deletions(-) diff --git a/gicallableinfo.c b/gicallableinfo.c index 28043fa52..fec77b820 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -360,6 +360,79 @@ g_callable_info_iterate_return_attributes (GICallableInfo *info, return TRUE; } +/* Extract the correct bits from an ffi_arg return value into + * GIArgument: https://bugzilla.gnome.org/show_bug.cgi?id=665152 + * + * Also see the ffi_call man page - the storage requirements for return + * values are "special". + */ +typedef GIArgument GIFFIReturnValue; + +static void +set_gargument_from_ffi_return_value (GITypeInfo *return_info, + GIArgument *arg, + GIFFIReturnValue *ffi_value) +{ + switch (g_type_info_get_tag (return_info)) { + case GI_TYPE_TAG_INT8: + arg->v_int8 = (gint8) ffi_value->v_long; + break; + case GI_TYPE_TAG_UINT8: + arg->v_uint8 = (guint8) ffi_value->v_ulong; + break; + case GI_TYPE_TAG_INT16: + arg->v_int16 = (gint16) ffi_value->v_long; + break; + case GI_TYPE_TAG_UINT16: + arg->v_uint16 = (guint16) ffi_value->v_ulong; + break; + case GI_TYPE_TAG_INT32: + arg->v_int32 = (gint32) ffi_value->v_long; + break; + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_BOOLEAN: + case GI_TYPE_TAG_UNICHAR: + arg->v_uint32 = (guint32) ffi_value->v_ulong; + break; + case GI_TYPE_TAG_INT64: + arg->v_int64 = (gint64) ffi_value->v_int64; + break; + case GI_TYPE_TAG_UINT64: + arg->v_uint64 = (guint64) ffi_value->v_uint64; + break; + case GI_TYPE_TAG_FLOAT: + arg->v_float = ffi_value->v_float; + break; + case GI_TYPE_TAG_DOUBLE: + arg->v_double = ffi_value->v_double; + break; + case GI_TYPE_TAG_INTERFACE: + { + GIBaseInfo* interface_info; + GIInfoType interface_type; + + interface_info = g_type_info_get_interface(return_info); + interface_type = g_base_info_get_type(interface_info); + + switch(interface_type) { + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + arg->v_int32 = (gint32) ffi_value->v_long; + break; + default: + arg->v_pointer = (gpointer) ffi_value->v_ulong; + break; + } + + g_base_info_unref(interface_info); + } + break; + default: + arg->v_pointer = (gpointer) ffi_value->v_ulong; + break; + } +} + gboolean _g_callable_info_invoke (GIFunctionInfo *info, gpointer function, @@ -376,16 +449,20 @@ _g_callable_info_invoke (GIFunctionInfo *info, ffi_type *rtype; ffi_type **atypes; GITypeInfo *tinfo; + GITypeInfo *rinfo; + GITypeTag rtag; GIArgInfo *ainfo; gint n_args, n_invoke_args, in_pos, out_pos, i; gpointer *args; gboolean success = FALSE; GError *local_error = NULL; gpointer error_address = &local_error; + GIFFIReturnValue ffi_return_value; + gpointer return_value_p; /* Will point inside the union return_value */ - tinfo = g_callable_info_get_return_type ((GICallableInfo *)info); - rtype = g_type_info_get_ffi_type (tinfo); - g_base_info_unref ((GIBaseInfo *)tinfo); + rinfo = g_callable_info_get_return_type ((GICallableInfo *)info); + rtype = g_type_info_get_ffi_type (rinfo); + rtag = g_type_info_get_tag(rinfo); in_pos = 0; out_pos = 0; @@ -516,7 +593,23 @@ _g_callable_info_invoke (GIFunctionInfo *info, goto out; g_return_val_if_fail (return_value, FALSE); - ffi_call (&cif, function, return_value, args); + /* See comment for GIFFIReturnValue above */ + switch (rtag) + { + case GI_TYPE_TAG_FLOAT: + return_value_p = &ffi_return_value.v_float; + break; + case GI_TYPE_TAG_DOUBLE: + return_value_p = &ffi_return_value.v_double; + break; + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + return_value_p = &ffi_return_value.v_uint64; + break; + default: + return_value_p = &ffi_return_value.v_long; + } + ffi_call (&cif, function, return_value_p, args); if (local_error) { @@ -525,8 +618,10 @@ _g_callable_info_invoke (GIFunctionInfo *info, } else { + set_gargument_from_ffi_return_value(rinfo, return_value, &ffi_return_value); success = TRUE; } out: + g_base_info_unref ((GIBaseInfo *)rinfo); return success; } diff --git a/ginvoke.c b/ginvoke.c index 84e1e748f..581956a36 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -88,57 +88,121 @@ value_to_ffi_type (const GValue *gvalue, gpointer *value) return rettype; } -static void -value_from_ffi_type (GValue *gvalue, gpointer *value) +/* See comment aboe set_gargument_from_ffi_return_value() */ +static ffi_type * +g_value_to_ffi_return_type (const GValue *gvalue, + const GIArgument *ffi_value, + gpointer *value) { - switch (g_type_fundamental (G_VALUE_TYPE (gvalue))) - { - case G_TYPE_INT: - g_value_set_int (gvalue, *(gint*)value); + ffi_type *rettype = NULL; + GType type = g_type_fundamental (G_VALUE_TYPE (gvalue)); + g_assert (type != G_TYPE_INVALID); + + *value = (gpointer)&(ffi_value->v_long); + + switch (type) { + case G_TYPE_CHAR: + rettype = &ffi_type_sint8; + break; + case G_TYPE_UCHAR: + rettype = &ffi_type_uint8; + break; + case G_TYPE_BOOLEAN: + case G_TYPE_INT: + rettype = &ffi_type_sint; + break; + case G_TYPE_UINT: + rettype = &ffi_type_uint; + break; + case G_TYPE_STRING: + case G_TYPE_OBJECT: + case G_TYPE_BOXED: + case G_TYPE_POINTER: + rettype = &ffi_type_pointer; + break; + case G_TYPE_FLOAT: + rettype = &ffi_type_float; + *value = (gpointer)&(ffi_value->v_float); + break; + case G_TYPE_DOUBLE: + rettype = &ffi_type_double; + *value = (gpointer)&(ffi_value->v_double); + break; + case G_TYPE_LONG: + rettype = &ffi_type_slong; + break; + case G_TYPE_ULONG: + rettype = &ffi_type_ulong; + break; + case G_TYPE_INT64: + rettype = &ffi_type_sint64; + *value = (gpointer)&(ffi_value->v_int64); + break; + case G_TYPE_UINT64: + rettype = &ffi_type_uint64; + *value = (gpointer)&(ffi_value->v_uint64); + break; + default: + rettype = &ffi_type_pointer; + *value = NULL; + g_warning ("Unsupported fundamental type: %s", g_type_name (type)); + break; + } + return rettype; +} + +static void +g_value_from_ffi_value (GValue *gvalue, + const GIArgument *value) +{ + switch (g_type_fundamental (G_VALUE_TYPE (gvalue))) { + case G_TYPE_INT: + g_value_set_int (gvalue, (gint)value->v_long); break; - case G_TYPE_FLOAT: - g_value_set_float (gvalue, *(gfloat*)value); + case G_TYPE_FLOAT: + g_value_set_float (gvalue, (gfloat)value->v_float); break; - case G_TYPE_DOUBLE: - g_value_set_double (gvalue, *(gdouble*)value); + case G_TYPE_DOUBLE: + g_value_set_double (gvalue, (gdouble)value->v_double); break; - case G_TYPE_BOOLEAN: - g_value_set_boolean (gvalue, *(gboolean*)value); + case G_TYPE_BOOLEAN: + g_value_set_boolean (gvalue, (gboolean)value->v_long); break; - case G_TYPE_STRING: - g_value_set_string (gvalue, *(gchar**)value); + case G_TYPE_STRING: + g_value_set_string (gvalue, (gchar*)value->v_pointer); break; - case G_TYPE_CHAR: - g_value_set_char (gvalue, *(gchar*)value); + case G_TYPE_CHAR: + g_value_set_char (gvalue, (gchar)value->v_long); break; - case G_TYPE_UCHAR: - g_value_set_uchar (gvalue, *(guchar*)value); + case G_TYPE_UCHAR: + g_value_set_uchar (gvalue, (guchar)value->v_ulong); break; - case G_TYPE_UINT: - g_value_set_uint (gvalue, *(guint*)value); + case G_TYPE_UINT: + g_value_set_uint (gvalue, (guint)value->v_ulong); break; - case G_TYPE_POINTER: - g_value_set_pointer (gvalue, *(gpointer*)value); + case G_TYPE_POINTER: + g_value_set_pointer (gvalue, (gpointer)value->v_pointer); break; - case G_TYPE_LONG: - g_value_set_long (gvalue, *(glong*)value); + case G_TYPE_LONG: + g_value_set_long (gvalue, (glong)value->v_long); break; - case G_TYPE_ULONG: - g_value_set_ulong (gvalue, *(gulong*)value); + case G_TYPE_ULONG: + g_value_set_ulong (gvalue, (gulong)value->v_ulong); break; - case G_TYPE_INT64: - g_value_set_int64 (gvalue, *(gint64*)value); + case G_TYPE_INT64: + g_value_set_int64 (gvalue, (gint64)value->v_int64); break; - case G_TYPE_UINT64: - g_value_set_uint64 (gvalue, *(guint64*)value); + case G_TYPE_UINT64: + g_value_set_uint64 (gvalue, (guint64)value->v_uint64); break; - case G_TYPE_BOXED: - g_value_set_boxed (gvalue, *(gpointer*)value); + case G_TYPE_BOXED: + g_value_set_boxed (gvalue, (gpointer)value->v_pointer); break; - default: - g_warning ("Unsupported fundamental type: %s", - g_type_name (g_type_fundamental (G_VALUE_TYPE (gvalue)))); - } + default: + g_warning ("Unsupported fundamental type: %s", + g_type_name (g_type_fundamental (G_VALUE_TYPE (gvalue)))); + } + } void @@ -149,6 +213,7 @@ gi_cclosure_marshal_generic (GClosure *closure, gpointer invocation_hint, gpointer marshal_data) { + GIArgument return_ffi_value; ffi_type *rtype; void *rvalue; int n_args; @@ -160,15 +225,16 @@ gi_cclosure_marshal_generic (GClosure *closure, if (return_gvalue && G_VALUE_TYPE (return_gvalue)) { + rtype = g_value_to_ffi_return_type (return_gvalue, &return_ffi_value, + &rvalue); rtype = value_to_ffi_type (return_gvalue, &rvalue); } else { rtype = &ffi_type_void; + rvalue = &return_ffi_value.v_long; } - rvalue = g_alloca (MAX (rtype->size, sizeof (ffi_arg))); - n_args = n_param_values + 1; atypes = g_alloca (sizeof (ffi_type *) * n_args); args = g_alloca (sizeof (gpointer) * n_args); @@ -204,5 +270,5 @@ gi_cclosure_marshal_generic (GClosure *closure, ffi_call (&cif, marshal_data ? marshal_data : cc->callback, rvalue, args); if (return_gvalue && G_VALUE_TYPE (return_gvalue)) - value_from_ffi_type (return_gvalue, rvalue); + g_value_from_ffi_value (return_gvalue, &return_ffi_value); } From 4b71be0ef06da02f9db1a9a1eaffb36003f29d96 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 16 Feb 2012 16:58:59 -0500 Subject: [PATCH 479/692] repository: Add new public gi_type_info_extract_ffi_return_value() API Dealing with FFI and return values is very tricky; this API allows sharing the bits to do it between gobject-introspection and gjs (and potentially other FFI binding consumers). **NOTE** I swapped the order of the arguments, under the premise that out arguments should generally be last. https://bugzilla.gnome.org/show_bug.cgi?id=668902 --- gicallableinfo.c | 12 +++++------- girffi.h | 6 ++++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/gicallableinfo.c b/gicallableinfo.c index fec77b820..25372ffa0 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -366,12 +366,10 @@ g_callable_info_iterate_return_attributes (GICallableInfo *info, * Also see the ffi_call man page - the storage requirements for return * values are "special". */ -typedef GIArgument GIFFIReturnValue; - -static void -set_gargument_from_ffi_return_value (GITypeInfo *return_info, - GIArgument *arg, - GIFFIReturnValue *ffi_value) +void +gi_type_info_extract_ffi_return_value (GITypeInfo *return_info, + GIFFIReturnValue *ffi_value, + GIArgument *arg) { switch (g_type_info_get_tag (return_info)) { case GI_TYPE_TAG_INT8: @@ -618,7 +616,7 @@ _g_callable_info_invoke (GIFunctionInfo *info, } else { - set_gargument_from_ffi_return_value(rinfo, return_value, &ffi_return_value); + gi_type_info_extract_ffi_return_value (rinfo, &ffi_return_value, return_value); success = TRUE; } out: diff --git a/girffi.h b/girffi.h index e976f9241..56caff732 100644 --- a/girffi.h +++ b/girffi.h @@ -46,10 +46,16 @@ struct _GIFunctionInvoker { gpointer padding[3]; }; +typedef GIArgument GIFFIReturnValue; + ffi_type * gi_type_tag_get_ffi_type (GITypeTag type_tag, gboolean is_pointer); ffi_type * g_type_info_get_ffi_type (GITypeInfo *info); +void gi_type_info_extract_ffi_return_value (GITypeInfo *return_info, + GIFFIReturnValue *ffi_value, + GIArgument *arg); + gboolean g_function_info_prep_invoker (GIFunctionInfo *info, GIFunctionInvoker *invoker, GError **error); From b2eef541e9bd38ced9d314398a13cd90024235ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 8 Mar 2012 13:25:57 +0100 Subject: [PATCH 480/692] repository: Remove extraneous leftover assignment to rvalue. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michel Dänzer https://bugzilla.gnome.org/show_bug.cgi?id=668902 --- ginvoke.c | 1 - 1 file changed, 1 deletion(-) diff --git a/ginvoke.c b/ginvoke.c index 581956a36..6c39c48ec 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -227,7 +227,6 @@ gi_cclosure_marshal_generic (GClosure *closure, { rtype = g_value_to_ffi_return_type (return_gvalue, &return_ffi_value, &rvalue); - rtype = value_to_ffi_type (return_gvalue, &rvalue); } else { From 320fd24734fd8e4b2f887cfc77ca8fca670f29a4 Mon Sep 17 00:00:00 2001 From: Tomeu Vizoso Date: Sun, 30 Oct 2011 16:31:23 +0100 Subject: [PATCH 481/692] Make g_callable_info_invoke public So it can be used for invoking callbacks https://bugzilla.gnome.org/show_bug.cgi?id=663052 Signed-off-by: Martin Pitt --- gicallableinfo.c | 20 ++++++++++---------- gicallableinfo.h | 10 ++++++++++ gifunctioninfo.c | 20 ++++++++++---------- girepository-private.h | 11 ----------- givfuncinfo.c | 20 ++++++++++---------- 5 files changed, 40 insertions(+), 41 deletions(-) diff --git a/gicallableinfo.c b/gicallableinfo.c index 25372ffa0..95fa2fc2d 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -432,16 +432,16 @@ gi_type_info_extract_ffi_return_value (GITypeInfo *return_info, } gboolean -_g_callable_info_invoke (GIFunctionInfo *info, - gpointer function, - const GIArgument *in_args, - int n_in_args, - const GIArgument *out_args, - int n_out_args, - GIArgument *return_value, - gboolean is_method, - gboolean throws, - GError **error) +g_callable_info_invoke (GIFunctionInfo *info, + gpointer function, + const GIArgument *in_args, + int n_in_args, + const GIArgument *out_args, + int n_out_args, + GIArgument *return_value, + gboolean is_method, + gboolean throws, + GError **error) { ffi_cif cif; ffi_type *rtype; diff --git a/gicallableinfo.h b/gicallableinfo.h index 0c5fac794..48c08c413 100644 --- a/gicallableinfo.h +++ b/gicallableinfo.h @@ -55,6 +55,16 @@ GIArgInfo * g_callable_info_get_arg (GICallableInfo *info, void g_callable_info_load_arg (GICallableInfo *info, gint n, GIArgInfo *arg); +gboolean g_callable_info_invoke (GICallableInfo *info, + gpointer function, + const GIArgument *in_args, + int n_in_args, + const GIArgument *out_args, + int n_out_args, + GIArgument *return_value, + gboolean is_method, + gboolean throws, + GError **error); G_END_DECLS diff --git a/gifunctioninfo.c b/gifunctioninfo.c index 92f4ccd2d..a5858c76b 100644 --- a/gifunctioninfo.c +++ b/gifunctioninfo.c @@ -271,14 +271,14 @@ g_function_info_invoke (GIFunctionInfo *info, && (g_function_info_get_flags (info) & GI_FUNCTION_IS_CONSTRUCTOR) == 0; throws = g_function_info_get_flags (info) & GI_FUNCTION_THROWS; - return _g_callable_info_invoke ((GICallableInfo*) info, - func, - in_args, - n_in_args, - out_args, - n_out_args, - return_value, - is_method, - throws, - error); + return g_callable_info_invoke ((GICallableInfo*) info, + func, + in_args, + n_in_args, + out_args, + n_out_args, + return_value, + is_method, + throws, + error); } diff --git a/girepository-private.h b/girepository-private.h index 05b13626b..275776d8a 100644 --- a/girepository-private.h +++ b/girepository-private.h @@ -108,17 +108,6 @@ GIVFuncInfo * _g_base_info_find_vfunc (GIRealInfo *rinfo, gint n_vfuncs, const gchar *name); -gboolean _g_callable_info_invoke (GICallableInfo *info, - gpointer function, - const GIArgument *in_args, - int n_in_args, - const GIArgument *out_args, - int n_out_args, - GIArgument *return_value, - gboolean is_method, - gboolean throws, - GError **error); - extern ffi_status ffi_prep_closure_loc (ffi_closure *, ffi_cif *, void (*fun)(ffi_cif *, void *, void **, void *), diff --git a/givfuncinfo.c b/givfuncinfo.c index f80396c0c..462521b62 100644 --- a/givfuncinfo.c +++ b/givfuncinfo.c @@ -308,14 +308,14 @@ g_vfunc_info_invoke (GIVFuncInfo *info, if (*error != NULL) return FALSE; - return _g_callable_info_invoke ((GICallableInfo*) info, - func, - in_args, - n_in_args, - out_args, - n_out_args, - return_value, - TRUE, - FALSE, - error); + return g_callable_info_invoke ((GICallableInfo*) info, + func, + in_args, + n_in_args, + out_args, + n_out_args, + return_value, + TRUE, + FALSE, + error); } From 5374f24d38f67bd6380182c14f23089e24331a13 Mon Sep 17 00:00:00 2001 From: Dieter Verfaillie Date: Tue, 3 Apr 2012 07:47:48 +0200 Subject: [PATCH 482/692] Fix malformed GTK-Doc comment blocks: - add missing colons - invalid annotations - invalid parameters and tags - correct parameter name - preserve description indentation - no description parts - comment end marker - invalid empty lines - line numbers AnnotationParser now emits warnings which are considered as errors by "make check" so fix those warnings... https://bugzilla.gnome.org/show_bug.cgi?id=672254 --- girepository.c | 6 +++--- girepository.h | 2 +- gitypes.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/girepository.c b/girepository.c index 1384c0e94..bcc4a1b42 100644 --- a/girepository.c +++ b/girepository.c @@ -809,7 +809,7 @@ collect_namespaces (gpointer key, * * Return the list of currently loaded namespaces. * - * Returns: (utf8) (transfer full): List of namespaces + * Returns: (element-type utf8) (transfer full): List of namespaces */ gchar ** g_irepository_get_loaded_namespaces (GIRepository *repository) @@ -902,7 +902,7 @@ g_irepository_get_shared_library (GIRepository *repository, } /** - * g_irepository_get_c_prefix + * g_irepository_get_c_prefix: * @repository: (allow-none): A #GIRepository, may be %NULL for the default * @namespace_: Namespace to inspect * @@ -938,7 +938,7 @@ g_irepository_get_c_prefix (GIRepository *repository, } /** - * g_irepository_get_typelib_path + * g_irepository_get_typelib_path: * @repository: (allow-none): Repository, may be %NULL for the default * @namespace_: GI namespace to use, e.g. "Gtk" * diff --git a/girepository.h b/girepository.h index 02bd4a109..eb990a278 100644 --- a/girepository.h +++ b/girepository.h @@ -74,7 +74,7 @@ struct _GIRepositoryClass }; /** - * GIRepositoryLoadFlags + * GIRepositoryLoadFlags: * @G_IREPOSITORY_LOAD_FLAG_LAZY: Load the types lazily. * * Flags that controlls how a typelib is loaded by diff --git a/gitypes.h b/gitypes.h index 486f20aa7..88181b28f 100644 --- a/gitypes.h +++ b/gitypes.h @@ -117,7 +117,7 @@ typedef GIBaseInfo GIValueInfo; typedef GIBaseInfo GISignalInfo; /** - * GIVFuncInfo + * GIVFuncInfo: * * Represents a virtual function. */ From d0b8813d1480d2c99aa1d242edb545d747966688 Mon Sep 17 00:00:00 2001 From: Pavel Holejsovsky Date: Sat, 31 Mar 2012 19:12:48 +0200 Subject: [PATCH 483/692] Avoid _get_func() consuming reference from input info Fix of leak in 4c9424e18d71237f438a99bc5f2d45ae7de60b78 was a bit overaggressive, stealing also one reference from input 'info' argument. Also fixes another bug in that commit - local 'func' shadowing the return value, causing that function always returned NULL even when some result was actually found. https://bugzilla.gnome.org/show_bug.cgi?id=673282 --- giobjectinfo.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/giobjectinfo.c b/giobjectinfo.c index 3b8f64bb8..7ba2a93b8 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -819,7 +819,7 @@ _get_func(GIObjectInfo *info, GIObjectInfo *parent_info; gpointer func = NULL; - parent_info = info; + parent_info = g_base_info_ref (info); while (parent_info != NULL) { parents = g_slist_prepend (parents, parent_info); @@ -828,7 +828,6 @@ _get_func(GIObjectInfo *info, for (l = parents; l; l = l->next) { - GIObjectInfoRefFunction func; parent_info = l->data; symbol = getter (parent_info); if (symbol == NULL) From 0a96da92840cf0eb043b6ddb8c2618a23f8cbabe Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Mon, 9 Apr 2012 14:19:23 -0300 Subject: [PATCH 484/692] Make introspection compile with -Wall -Werror Address all gcc warnings, -Werror is not enabled yet but at least -Wall -Werror passes on my machine. --- cmph/bdz.c | 9 +++++++++ cmph/bdz_ph.c | 8 ++++++++ cmph/bmz.c | 9 +++++++++ cmph/bmz8.c | 9 +++++++++ cmph/brz.c | 14 +++++++++++++- cmph/chd.c | 9 ++++++++- cmph/chd_ph.c | 8 ++++++++ cmph/chm.c | 9 +++++++++ cmph/cmph.c | 3 +-- cmph/cmph_structs.c | 7 +++++++ cmph/fch.c | 9 +++++++++ ginvoke.c | 2 +- girepository.c | 2 -- girwriter.c | 2 -- 14 files changed, 91 insertions(+), 9 deletions(-) diff --git a/cmph/bdz.c b/cmph/bdz.c index a57f70f84..a385b152a 100755 --- a/cmph/bdz.c +++ b/cmph/bdz.c @@ -9,6 +9,7 @@ #include #include #include +#include //#define DEBUG #include "debug.h" #define UNASSIGNED 3U @@ -508,6 +509,10 @@ int bdz_dump(cmph_t *mphf, FILE *fd) nbytes = fwrite(&(data->ranktablesize), sizeof(cmph_uint32), (size_t)1, fd); nbytes = fwrite(data->ranktable, sizeof(cmph_uint32)*(data->ranktablesize), (size_t)1, fd); + if (nbytes == 0 && ferror(fd)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + return 0; + } #ifdef DEBUG cmph_uint32 i; fprintf(stderr, "G: "); @@ -549,6 +554,10 @@ void bdz_load(FILE *f, cmph_t *mphf) bdz->ranktable = (cmph_uint32 *)calloc((size_t)bdz->ranktablesize, sizeof(cmph_uint32)); nbytes = fread(bdz->ranktable, sizeof(cmph_uint32)*(bdz->ranktablesize), (size_t)1, f); + if (nbytes == 0 && ferror(f)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + return; + } #ifdef DEBUG cmph_uint32 i = 0; diff --git a/cmph/bdz_ph.c b/cmph/bdz_ph.c index 16257c0f4..2e9860712 100755 --- a/cmph/bdz_ph.c +++ b/cmph/bdz_ph.c @@ -9,6 +9,7 @@ #include #include #include +#include //#define DEBUG #include "debug.h" #define UNASSIGNED 3 @@ -465,6 +466,10 @@ int bdz_ph_dump(cmph_t *mphf, FILE *fd) sizeg = (cmph_uint32)ceil(data->n/5.0); nbytes = fwrite(data->g, sizeof(cmph_uint8)*sizeg, (size_t)1, fd); + if (nbytes == 0 && ferror(fd)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + return 0; + } #ifdef DEBUG cmph_uint32 i; fprintf(stderr, "G: "); @@ -501,6 +506,9 @@ void bdz_ph_load(FILE *f, cmph_t *mphf) bdz_ph->g = (cmph_uint8 *)calloc((size_t)sizeg, sizeof(cmph_uint8)); nbytes = fread(bdz_ph->g, sizeg*sizeof(cmph_uint8), (size_t)1, f); + if (nbytes == 0 && ferror(f)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + } return; } diff --git a/cmph/bmz.c b/cmph/bmz.c index 3eabfb7f2..9c6cea004 100644 --- a/cmph/bmz.c +++ b/cmph/bmz.c @@ -11,6 +11,7 @@ #include #include #include +#include //#define DEBUG #include "debug.h" @@ -469,6 +470,10 @@ int bmz_dump(cmph_t *mphf, FILE *fd) nbytes = fwrite(&(data->m), sizeof(cmph_uint32), (size_t)1, fd); nbytes = fwrite(data->g, sizeof(cmph_uint32)*(data->n), (size_t)1, fd); + if (nbytes == 0 && ferror(fd)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + return 0; + } #ifdef DEBUG cmph_uint32 i; fprintf(stderr, "G: "); @@ -510,6 +515,10 @@ void bmz_load(FILE *f, cmph_t *mphf) bmz->g = (cmph_uint32 *)malloc(sizeof(cmph_uint32)*bmz->n); nbytes = fread(bmz->g, bmz->n*sizeof(cmph_uint32), (size_t)1, f); + if (nbytes == 0 && ferror(f)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + return; + } #ifdef DEBUG fprintf(stderr, "G: "); for (i = 0; i < bmz->n; ++i) fprintf(stderr, "%u ", bmz->g[i]); diff --git a/cmph/bmz8.c b/cmph/bmz8.c index 4db4dfce8..206c48c4d 100644 --- a/cmph/bmz8.c +++ b/cmph/bmz8.c @@ -10,6 +10,7 @@ #include #include #include +#include //#define DEBUG #include "debug.h" @@ -482,6 +483,10 @@ int bmz8_dump(cmph_t *mphf, FILE *fd) nbytes = fwrite(&(data->m), sizeof(cmph_uint8), (size_t)1, fd); nbytes = fwrite(data->g, sizeof(cmph_uint8)*(data->n), (size_t)1, fd); + if (nbytes == 0 && ferror(fd)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + return 0; + } /* #ifdef DEBUG fprintf(stderr, "G: "); for (i = 0; i < data->n; ++i) fprintf(stderr, "%u ", data->g[i]); @@ -523,6 +528,10 @@ void bmz8_load(FILE *f, cmph_t *mphf) bmz8->g = (cmph_uint8 *)malloc(sizeof(cmph_uint8)*bmz8->n); nbytes = fread(bmz8->g, bmz8->n*sizeof(cmph_uint8), (size_t)1, f); + if (nbytes == 0 && ferror(f)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + return; + } #ifdef DEBUG fprintf(stderr, "G: "); for (i = 0; i < bmz8->n; ++i) fprintf(stderr, "%u ", bmz8->g[i]); diff --git a/cmph/brz.c b/cmph/brz.c index f9c48ef7c..f0c91c4bd 100755 --- a/cmph/brz.c +++ b/cmph/brz.c @@ -15,6 +15,7 @@ #include #include #include +#include #define MAX_BUCKET_SIZE 255 //#define DEBUG #include "debug.h" @@ -370,7 +371,11 @@ static int brz_gen_mphf(cmph_config_t *mph) nbytes = fwrite(&(brz->algo), sizeof(brz->algo), (size_t)1, brz->mphf_fd); nbytes = fwrite(&(brz->k), sizeof(cmph_uint32), (size_t)1, brz->mphf_fd); // number of MPHFs nbytes = fwrite(brz->size, sizeof(cmph_uint8)*(brz->k), (size_t)1, brz->mphf_fd); - + if (nbytes == 0 && ferror(brz->mphf_fd)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + return 0; + } + //tmp_fds = (FILE **)calloc(nflushes, sizeof(FILE *)); buff_manager = buffer_manager_new(brz->memory_availability, nflushes); buffer_merge = (cmph_uint8 **)calloc((size_t)nflushes, sizeof(cmph_uint8 *)); @@ -574,6 +579,10 @@ int brz_dump(cmph_t *mphf, FILE *fd) // Dumping m and the vector offset. nbytes = fwrite(&(data->m), sizeof(cmph_uint32), (size_t)1, fd); nbytes = fwrite(data->offset, sizeof(cmph_uint32)*(data->k), (size_t)1, fd); + if (nbytes == 0 && ferror(fd)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + return 0; + } return 1; } @@ -639,6 +648,9 @@ void brz_load(FILE *f, cmph_t *mphf) nbytes = fread(&(brz->m), sizeof(cmph_uint32), (size_t)1, f); brz->offset = (cmph_uint32 *)malloc(sizeof(cmph_uint32)*brz->k); nbytes = fread(brz->offset, sizeof(cmph_uint32)*(brz->k), (size_t)1, f); + if (nbytes == 0 && ferror(f)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + } return; } diff --git a/cmph/chd.c b/cmph/chd.c index 7fb3b8bb8..71579ee34 100644 --- a/cmph/chd.c +++ b/cmph/chd.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "cmph_structs.h" #include "chd_structs.h" @@ -189,6 +190,9 @@ void chd_load(FILE *fd, cmph_t *mphf) DEBUGP("Loading Compressed rank structure, which has %u bytes\n", chd->packed_cr_size); chd->packed_cr = (cmph_uint8 *) calloc((size_t)chd->packed_cr_size, (size_t)1); nbytes = fread(chd->packed_cr, chd->packed_cr_size, (size_t)1, fd); + if (nbytes == 0 && ferror(fd)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + } } int chd_dump(cmph_t *mphf, FILE *fd) @@ -206,7 +210,10 @@ int chd_dump(cmph_t *mphf, FILE *fd) DEBUGP("Dumping compressed rank structure with %u bytes to disk\n", buflen); nbytes = fwrite(&data->packed_cr_size, sizeof(cmph_uint32), (size_t)1, fd); nbytes = fwrite(data->packed_cr, data->packed_cr_size, (size_t)1, fd); - + if (nbytes == 0 && ferror(fd)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + return 0; + } return 1; } diff --git a/cmph/chd_ph.c b/cmph/chd_ph.c index 71f83fbd3..6cd9437a9 100644 --- a/cmph/chd_ph.c +++ b/cmph/chd_ph.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "cmph_structs.h" #include "chd_structs_ph.h" @@ -859,6 +860,9 @@ void chd_ph_load(FILE *fd, cmph_t *mphf) DEBUGP("Reading n and nbuckets\n"); nbytes = fread(&(chd_ph->n), sizeof(cmph_uint32), (size_t)1, fd); nbytes = fread(&(chd_ph->nbuckets), sizeof(cmph_uint32), (size_t)1, fd); + if (nbytes == 0 && ferror(fd)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + } } int chd_ph_dump(cmph_t *mphf, FILE *fd) @@ -885,6 +889,10 @@ int chd_ph_dump(cmph_t *mphf, FILE *fd) // dumping n and nbuckets nbytes = fwrite(&(data->n), sizeof(cmph_uint32), (size_t)1, fd); nbytes = fwrite(&(data->nbuckets), sizeof(cmph_uint32), (size_t)1, fd); + if (nbytes == 0 && ferror(fd)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + return 0; + } return 1; } diff --git a/cmph/chm.c b/cmph/chm.c index 9cdbf41bc..3af8c8069 100644 --- a/cmph/chm.c +++ b/cmph/chm.c @@ -10,6 +10,7 @@ #include #include #include +#include //#define DEBUG #include "debug.h" @@ -225,6 +226,10 @@ int chm_dump(cmph_t *mphf, FILE *fd) nbytes = fwrite(&(data->m), sizeof(cmph_uint32), (size_t)1, fd); nbytes = fwrite(data->g, sizeof(cmph_uint32)*data->n, (size_t)1, fd); + if (nbytes == 0 && ferror(fd)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + return 0; + } /* #ifdef DEBUG fprintf(stderr, "G: "); for (i = 0; i < data->n; ++i) fprintf(stderr, "%u ", data->g[i]); @@ -265,6 +270,10 @@ void chm_load(FILE *f, cmph_t *mphf) chm->g = (cmph_uint32 *)malloc(sizeof(cmph_uint32)*chm->n); nbytes = fread(chm->g, chm->n*sizeof(cmph_uint32), (size_t)1, f); + if (nbytes == 0 && ferror(f)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + return; + } #ifdef DEBUG fprintf(stderr, "G: "); for (i = 0; i < chm->n; ++i) fprintf(stderr, "%u ", chm->g[i]); diff --git a/cmph/cmph.c b/cmph/cmph.c index cba735f4f..0c4b67d12 100644 --- a/cmph/cmph.c +++ b/cmph/cmph.c @@ -151,12 +151,11 @@ static void key_vector_rewind(void *data) static cmph_uint32 count_nlfile_keys(FILE *fd) { cmph_uint32 count = 0; - register char * ptr; rewind(fd); while(1) { char buf[BUFSIZ]; - ptr = fgets(buf, BUFSIZ, fd); + fgets(buf, BUFSIZ, fd); if (feof(fd)) break; if (buf[strlen(buf) - 1] != '\n') continue; ++count; diff --git a/cmph/cmph_structs.c b/cmph/cmph_structs.c index b5634248f..9ecf5fc0e 100644 --- a/cmph/cmph_structs.c +++ b/cmph/cmph_structs.c @@ -1,6 +1,7 @@ #include "cmph_structs.h" #include +#include //#define DEBUG #include "debug.h" @@ -27,6 +28,9 @@ void __cmph_dump(cmph_t *mphf, FILE *fd) register size_t nbytes; nbytes = fwrite(cmph_names[mphf->algo], (size_t)(strlen(cmph_names[mphf->algo]) + 1), (size_t)1, fd); nbytes = fwrite(&(mphf->size), sizeof(mphf->size), (size_t)1, fd); + if (nbytes == 0 && ferror(fd)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + } } cmph_t *__cmph_load(FILE *f) { @@ -62,6 +66,9 @@ cmph_t *__cmph_load(FILE *f) nbytes = fread(&(mphf->size), sizeof(mphf->size), (size_t)1, f); mphf->data = NULL; DEBUGP("Algorithm is %s and mphf is sized %u\n", cmph_names[algo], mphf->size); + if (nbytes == 0 && ferror(f)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + } return mphf; } diff --git a/cmph/fch.c b/cmph/fch.c index 67b68fbbe..f6e16e346 100644 --- a/cmph/fch.c +++ b/cmph/fch.c @@ -9,6 +9,7 @@ #include #include #include +#include #define INDEX 0 /* alignment index within a bucket */ //#define DEBUG #include "debug.h" @@ -339,6 +340,10 @@ int fch_dump(cmph_t *mphf, FILE *fd) nbytes = fwrite(&(data->p1), sizeof(double), (size_t)1, fd); nbytes = fwrite(&(data->p2), sizeof(double), (size_t)1, fd); nbytes = fwrite(data->g, sizeof(cmph_uint32)*(data->b), (size_t)1, fd); + if (nbytes == 0 && ferror(fd)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + return 0; + } #ifdef DEBUG cmph_uint32 i; fprintf(stderr, "G: "); @@ -387,6 +392,10 @@ void fch_load(FILE *f, cmph_t *mphf) fch->g = (cmph_uint32 *)malloc(sizeof(cmph_uint32)*fch->b); nbytes = fread(fch->g, fch->b*sizeof(cmph_uint32), (size_t)1, f); + if (nbytes == 0 && ferror(f)) { + fprintf(stderr, "ERROR: %s\n", strerror(errno)); + return; + } #ifdef DEBUG cmph_uint32 i; fprintf(stderr, "G: "); diff --git a/ginvoke.c b/ginvoke.c index 6c39c48ec..ed4996d9f 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -172,7 +172,7 @@ g_value_from_ffi_value (GValue *gvalue, g_value_set_string (gvalue, (gchar*)value->v_pointer); break; case G_TYPE_CHAR: - g_value_set_char (gvalue, (gchar)value->v_long); + g_value_set_schar (gvalue, (gchar)value->v_long); break; case G_TYPE_UCHAR: g_value_set_uchar (gvalue, (guchar)value->v_ulong); diff --git a/girepository.c b/girepository.c index bcc4a1b42..b5c30297a 100644 --- a/girepository.c +++ b/girepository.c @@ -372,7 +372,6 @@ register_internal (GIRepository *repository, { Header *header; const gchar *namespace; - const gchar *version; g_return_val_if_fail (typelib != NULL, FALSE); @@ -381,7 +380,6 @@ register_internal (GIRepository *repository, g_return_val_if_fail (header != NULL, FALSE); namespace = g_typelib_get_string (typelib, header->namespace); - version = g_typelib_get_string (typelib, header->nsversion); if (lazy) { diff --git a/girwriter.c b/girwriter.c index 73088a12f..5b39e2def 100644 --- a/girwriter.c +++ b/girwriter.c @@ -771,11 +771,9 @@ write_constant_info (const gchar *namespace, { GITypeInfo *type; const gchar *name; - gboolean deprecated; GIArgument value; name = g_base_info_get_name ((GIBaseInfo *)info); - deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); xml_start_element (file, "constant"); xml_printf (file, " name=\"%s\"", name); From 8af8aaa4a8b5a096a8cf6e946c7675fca2f1f233 Mon Sep 17 00:00:00 2001 From: Pavel Holejsovsky Date: Sat, 12 May 2012 07:44:57 +0200 Subject: [PATCH 485/692] girepository: avoid crash when querying nonexistent info It appears that cmph library can return (n+1) when querying item not present in its original n-item-sized set. Adjust code so that it detects this condition and do not chase stray pointers resulting from this bogus(?) hash result. https://bugzilla.gnome.org/show_bug.cgi?id=675939 --- gitypelib-internal.h | 2 +- gitypelib.c | 6 +++--- gthash-test.c | 8 ++++---- gthash.c | 10 +++++++++- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/gitypelib-internal.h b/gitypelib-internal.h index ed8e6792d..04662b4a0 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -1183,7 +1183,7 @@ void _gi_typelib_hash_builder_pack (GITypelibHashBuilder *builder, guint8* mem, void _gi_typelib_hash_builder_destroy (GITypelibHashBuilder *builder); -guint16 _gi_typelib_hash_search (guint8* memory, const char *str); +guint16 _gi_typelib_hash_search (guint8* memory, const char *str, guint n_entries); G_END_DECLS diff --git a/gitypelib.c b/gitypelib.c index ae6b84587..2af17e969 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -165,15 +165,15 @@ g_typelib_get_dir_entry_by_name (GITypelib *typelib, const char *name) { Section *dirindex; - gint i; + gint i, n_entries; const char *entry_name; DirEntry *entry; dirindex = get_section_by_id (typelib, GI_SECTION_DIRECTORY_INDEX); + n_entries = ((Header *)typelib->data)->n_local_entries; if (dirindex == NULL) { - gint n_entries = ((Header *)typelib->data)->n_local_entries; for (i = 1; i <= n_entries; i++) { entry = g_typelib_get_dir_entry (typelib, i); @@ -188,7 +188,7 @@ g_typelib_get_dir_entry_by_name (GITypelib *typelib, guint8 *hash = (guint8*) &typelib->data[dirindex->offset]; guint16 index; - index = _gi_typelib_hash_search (hash, name); + index = _gi_typelib_hash_search (hash, name, n_entries); entry = g_typelib_get_dir_entry (typelib, index + 1); entry_name = g_typelib_get_string (typelib, entry->name); if (strcmp (name, entry_name) == 0) diff --git a/gthash-test.c b/gthash-test.c index 7909a0c85..ea811e35a 100644 --- a/gthash-test.c +++ b/gthash-test.c @@ -47,10 +47,10 @@ test_build_retrieve (void) _gi_typelib_hash_builder_destroy (builder); - g_assert (_gi_typelib_hash_search (buf, "Action") == 0); - g_assert (_gi_typelib_hash_search (buf, "ZLibDecompressor") == 42); - g_assert (_gi_typelib_hash_search (buf, "VolumeMonitor") == 9); - g_assert (_gi_typelib_hash_search (buf, "FileMonitorFlags") == 31); + g_assert (_gi_typelib_hash_search (buf, "Action", 4) == 0); + g_assert (_gi_typelib_hash_search (buf, "ZLibDecompressor", 4) == 42); + g_assert (_gi_typelib_hash_search (buf, "VolumeMonitor", 4) == 9); + g_assert (_gi_typelib_hash_search (buf, "FileMonitorFlags", 4) == 31); } int diff --git a/gthash.c b/gthash.c index 8a3529592..b50ea6f0e 100644 --- a/gthash.c +++ b/gthash.c @@ -191,7 +191,7 @@ _gi_typelib_hash_builder_destroy (GITypelibHashBuilder *builder) } guint16 -_gi_typelib_hash_search (guint8* memory, const char *str) +_gi_typelib_hash_search (guint8* memory, const char *str, guint n_entries) { guint32 *mph; guint16 *table; @@ -203,6 +203,14 @@ _gi_typelib_hash_search (guint8* memory, const char *str) offset = cmph_search_packed (mph, str, strlen (str)); + /* Make sure that offset always lies in the entries array. cmph + cometimes generates offset larger than number of entries (for + 'str' argument which is not in the hashed list). In this case, + fake the correct result and depend on caller's final check that + the entry is really the one that the caller wanted. */ + if (offset >= n_entries) + offset = 0; + dirmap_offset = *((guint32*)memory); table = (guint16*) (memory + dirmap_offset); From df10915ba5172ec1fb802182369e43142c1e049e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 25 May 2012 16:32:44 -0400 Subject: [PATCH 486/692] givfuncinfo: Fix memory leak The field info wasn't being freed after it was used --- givfuncinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/givfuncinfo.c b/givfuncinfo.c index 462521b62..f9ba64a7f 100644 --- a/givfuncinfo.c +++ b/givfuncinfo.c @@ -253,6 +253,7 @@ g_vfunc_info_get_address (GIVFuncInfo *vfunc_info, offset = g_field_info_get_offset (field_info); func = *(gpointer*) G_STRUCT_MEMBER_P (implementor_vtable, offset); g_type_class_unref (implementor_vtable); + g_base_info_unref (field_info); if (func == NULL) { From 849c7c2f664fdccb28d78c9dc08c52d73a6299a9 Mon Sep 17 00:00:00 2001 From: Alan Knowles Date: Thu, 28 Jun 2012 12:07:35 -0400 Subject: [PATCH 487/692] fix GIArgument being exported as _Argument in .gir https://bugzilla.gnome.org/show_bug.cgi?id=635128 --- gitypes.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gitypes.h b/gitypes.h index 88181b28f..a0f3b3757 100644 --- a/gitypes.h +++ b/gitypes.h @@ -158,7 +158,12 @@ typedef GIBaseInfo GITypeInfo; */ typedef struct _GIUnresolvedInfo GIUnresolvedInfo; -union _GIArgument +/** + * GIArgument: + * + * Stores an argument of varying type + */ +typedef union { gboolean v_boolean; gint8 v_int8; @@ -181,8 +186,7 @@ union _GIArgument gsize v_size; gchar * v_string; gpointer v_pointer; -}; -typedef union _GIArgument GIArgument; +} GIArgument; /** * GIInfoType: From d936489647d5ade8fa4267850416a4eecf986b99 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 29 Jun 2012 10:05:09 -0400 Subject: [PATCH 488/692] Fix build --- gitypes.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gitypes.h b/gitypes.h index a0f3b3757..a90ed4c85 100644 --- a/gitypes.h +++ b/gitypes.h @@ -186,7 +186,7 @@ typedef union gsize v_size; gchar * v_string; gpointer v_pointer; -} GIArgument; +} GIArgument; /** * GIInfoType: @@ -443,7 +443,7 @@ typedef enum #ifndef __GI_SCANNER__ /* backwards compatibility */ -typedef union _GIArgument GArgument; +typedef GIArgument GArgument; typedef struct _GITypelib GTypelib; #endif From d65cec7f15163370fee39a75e445c2c7f48c91dc Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 9 Apr 2012 15:41:39 -0300 Subject: [PATCH 489/692] gicallableinfo: Add two new convenience methods: is_method and can_throw_gerror https://bugzilla.gnome.org/show_bug.cgi?id=673805 --- gicallableinfo.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ gicallableinfo.h | 2 ++ girffi.c | 29 ++------------------ 3 files changed, 74 insertions(+), 27 deletions(-) diff --git a/gicallableinfo.c b/gicallableinfo.c index 95fa2fc2d..28c5950ed 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -81,6 +81,76 @@ signature_offset (GICallableInfo *info) return 0; } +/** + * g_callable_info_can_throw_gerror: + * @info: a #GICallableInfo + * + * Returns: %TRUE if this #GICallableInfo can throw a #GError + * + * Since: 1.34 + */ +gboolean +g_callable_info_can_throw_gerror (GICallableInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo*)info; + switch (rinfo->type) { + case GI_INFO_TYPE_FUNCTION: + { + FunctionBlob *blob; + blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; + return blob->throws; + } + case GI_INFO_TYPE_VFUNC: + { + VFuncBlob *blob; + blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; + return blob->throws; + } + case GI_INFO_TYPE_CALLBACK: + case GI_INFO_TYPE_SIGNAL: + return FALSE; + default: + g_assert_not_reached (); + } +} + +/** + * g_callable_info_is_method: + * @info: a #GICallableInfo + * + * Determines if the callable info is a method. For #GIVFuncInfos, + * #GICallbackInfos, and #GISignalInfos, + * this is always true. Otherwise, this looks at the %GI_FUNCTION_IS_METHOD + * flag on the #GIFunctionInfo. + * + * Concretely, this function returns whether g_callable_info_get_n_args() + * matches the number of arguments in the raw C method. For methods, there + * is one more C argument than is exposed by introspection: the "self" + * or "this" object. + * + * Since: 1.34 + */ +gboolean +g_callable_info_is_method (GICallableInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo*)info; + switch (rinfo->type) { + case GI_INFO_TYPE_FUNCTION: + { + FunctionBlob *blob; + blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; + return (!blob->constructor && !blob->is_static); + } + case GI_INFO_TYPE_VFUNC: + case GI_INFO_TYPE_SIGNAL: + return TRUE; + case GI_INFO_TYPE_CALLBACK: + return FALSE; + default: + g_assert_not_reached (); + } +} + /** * g_callable_info_get_return_type: * @info: a #GICallableInfo diff --git a/gicallableinfo.h b/gicallableinfo.h index 48c08c413..a7d7079a7 100644 --- a/gicallableinfo.h +++ b/gicallableinfo.h @@ -37,6 +37,8 @@ G_BEGIN_DECLS (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_SIGNAL) || \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_VFUNC)) +gboolean g_callable_info_is_method (GICallableInfo *info); +gboolean g_callable_info_can_throw_gerror (GICallableInfo *info); GITypeInfo * g_callable_info_get_return_type (GICallableInfo *info); void g_callable_info_load_return_type (GICallableInfo *info, GITypeInfo *type); diff --git a/girffi.c b/girffi.c index 114006139..f6e47fb07 100644 --- a/girffi.c +++ b/girffi.c @@ -289,33 +289,8 @@ g_function_invoker_new_for_address (gpointer addr, invoker->native_address = addr; - info_type = g_base_info_get_type ((GIBaseInfo *) info); - - switch (info_type) - { - case GI_INFO_TYPE_FUNCTION: - { - GIFunctionInfoFlags flags; - flags = g_function_info_get_flags ((GIFunctionInfo *)info); - is_method = (flags & GI_FUNCTION_IS_METHOD) != 0; - throws = (flags & GI_FUNCTION_THROWS) != 0; - } - break; - case GI_INFO_TYPE_VFUNC: - { - GIVFuncInfoFlags flags; - flags = g_vfunc_info_get_flags ((GIVFuncInfo *)info); - throws = (flags & GI_VFUNC_THROWS) != 0; - } - is_method = TRUE; - break; - case GI_INFO_TYPE_CALLBACK: - is_method = TRUE; - throws = FALSE; - break; - default: - g_assert_not_reached (); - } + is_method = g_callable_info_is_method (info); + throws = g_callable_info_can_throw_gerror (info); tinfo = g_callable_info_get_return_type (info); rtype = g_type_info_get_ffi_type (tinfo); From 3bcc0e43c6ecf68e41642f83a6c3343e6bb2856e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 9 Apr 2012 17:51:08 -0300 Subject: [PATCH 490/692] girffi: Fix g_callable_info_prepare_closure for certain callables Namely, those that are methods and those that throw GErrors. We have very similar code in two places that calculate arg lengths and argument types to stick into libffi. Merge, clean up, and correct both. https://bugzilla.gnome.org/show_bug.cgi?id=673805 --- girffi.c | 115 +++++++++++++++++++++---------------------------------- 1 file changed, 44 insertions(+), 71 deletions(-) diff --git a/girffi.c b/girffi.c index f6e47fb07..ec710c377 100644 --- a/girffi.c +++ b/girffi.c @@ -146,42 +146,65 @@ g_type_info_get_ffi_type (GITypeInfo *info) /** * g_callable_info_get_ffi_arg_types: * @callable_info: a callable info from a typelib + * @n_args_p: (out): The number of arguments * * Return value: an array of ffi_type*. The array itself * should be freed using g_free() after use. */ static ffi_type ** -g_callable_info_get_ffi_arg_types (GICallableInfo *callable_info) +g_callable_info_get_ffi_arg_types (GICallableInfo *callable_info, + int *n_args_p) { ffi_type **arg_types; - gint n_args, i; + gboolean is_method, throws; + gint n_args, n_invoke_args, i, offset; g_return_val_if_fail (callable_info != NULL, NULL); n_args = g_callable_info_get_n_args (callable_info); + is_method = g_callable_info_is_method (callable_info); + throws = g_callable_info_can_throw_gerror (callable_info); + offset = is_method ? 1 : 0; - arg_types = (ffi_type **) g_new0 (ffi_type *, n_args + 1); + n_invoke_args = n_args; + + if (is_method) + n_invoke_args++; + if (throws) + n_invoke_args++; + + if (n_args_p) + *n_args_p = n_invoke_args; + + arg_types = (ffi_type **) g_new0 (ffi_type *, n_invoke_args + 1); + + if (is_method) + arg_types[0] = &ffi_type_pointer; + if (throws) + arg_types[n_invoke_args - 1] = &ffi_type_pointer; for (i = 0; i < n_args; ++i) { - GIArgInfo *arg_info = g_callable_info_get_arg (callable_info, i); - GITypeInfo *arg_type = g_arg_info_get_type (arg_info); - switch (g_arg_info_get_direction (arg_info)) + GIArgInfo arg_info; + GITypeInfo arg_type; + + g_callable_info_load_arg (callable_info, i, &arg_info); + g_arg_info_load_type (&arg_info, &arg_type); + switch (g_arg_info_get_direction (&arg_info)) { case GI_DIRECTION_IN: - arg_types[i] = g_type_info_get_ffi_type (arg_type); + arg_types[i + offset] = g_type_info_get_ffi_type (&arg_type); break; case GI_DIRECTION_OUT: case GI_DIRECTION_INOUT: - arg_types[i] = &ffi_type_pointer; + arg_types[i + offset] = &ffi_type_pointer; break; default: g_assert_not_reached (); } - g_base_info_unref ((GIBaseInfo *)arg_info); - g_base_info_unref ((GIBaseInfo *)arg_type); } - arg_types[n_args] = NULL; + + arg_types[n_invoke_args] = NULL; return arg_types; } @@ -275,71 +298,19 @@ g_function_invoker_new_for_address (gpointer addr, GIFunctionInvoker *invoker, GError **error) { - ffi_type *rtype; ffi_type **atypes; - GITypeInfo *tinfo; - GIArgInfo *ainfo; - GIInfoType info_type; - gboolean is_method; - gboolean throws; - gint n_args, n_invoke_args, i; + gint n_args; g_return_val_if_fail (info != NULL, FALSE); g_return_val_if_fail (invoker != NULL, FALSE); invoker->native_address = addr; - is_method = g_callable_info_is_method (info); - throws = g_callable_info_can_throw_gerror (info); + atypes = g_callable_info_get_ffi_arg_types (info, &n_args); - tinfo = g_callable_info_get_return_type (info); - rtype = g_type_info_get_ffi_type (tinfo); - g_base_info_unref ((GIBaseInfo *)tinfo); - - n_args = g_callable_info_get_n_args (info); - if (is_method) - n_invoke_args = n_args+1; - else - n_invoke_args = n_args; - - if (throws) - /* Add an argument for the GError */ - n_invoke_args ++; - - /* TODO: avoid malloc here? */ - atypes = g_malloc0 (sizeof (ffi_type*) * n_invoke_args); - - if (is_method) - { - atypes[0] = &ffi_type_pointer; - } - for (i = 0; i < n_args; i++) - { - int offset = (is_method ? 1 : 0); - ainfo = g_callable_info_get_arg (info, i); - switch (g_arg_info_get_direction (ainfo)) - { - case GI_DIRECTION_IN: - tinfo = g_arg_info_get_type (ainfo); - atypes[i+offset] = g_type_info_get_ffi_type (tinfo); - g_base_info_unref ((GIBaseInfo *)tinfo); - break; - case GI_DIRECTION_OUT: - case GI_DIRECTION_INOUT: - atypes[i+offset] = &ffi_type_pointer; - break; - default: - g_assert_not_reached (); - } - g_base_info_unref ((GIBaseInfo *)ainfo); - } - - if (throws) - { - atypes[n_invoke_args - 1] = &ffi_type_pointer; - } - - return ffi_prep_cif (&(invoker->cif), FFI_DEFAULT_ABI, n_invoke_args, rtype, atypes) == FFI_OK; + return ffi_prep_cif (&(invoker->cif), FFI_DEFAULT_ABI, n_args, + g_callable_info_get_ffi_return_type (info), + atypes) == FFI_OK; } /** @@ -380,6 +351,8 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, gpointer user_data) { gpointer exec_ptr; + int n_args; + ffi_type **atypes; GIClosureWrapper *closure; ffi_status status; @@ -395,10 +368,10 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, } closure->writable_self = closure; - status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, - g_callable_info_get_n_args (callable_info), + atypes = g_callable_info_get_ffi_arg_types (callable_info, &n_args); + status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, n_args, g_callable_info_get_ffi_return_type (callable_info), - g_callable_info_get_ffi_arg_types (callable_info)); + atypes); if (status != FFI_OK) { g_warning ("ffi_prep_cif failed: %d\n", status); From 27f11b2e51f2448221bcfc2ff18e36f82b050b98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20Sch=C3=B6nfeld?= Date: Sat, 25 Aug 2012 15:51:15 +0200 Subject: [PATCH 491/692] girepository: Add g_interface_info_find_signal Add the convenience method g_interface_info_find_signal, mirroring g_object_info_find_signal. https://bugzilla.gnome.org/show_bug.cgi?id=682672 --- giinterfaceinfo.c | 33 +++++++++++++++++++++++++++++++++ giinterfaceinfo.h | 2 ++ 2 files changed, 35 insertions(+) diff --git a/giinterfaceinfo.c b/giinterfaceinfo.c index 69cd63d90..f998da446 100644 --- a/giinterfaceinfo.c +++ b/giinterfaceinfo.c @@ -292,6 +292,39 @@ g_interface_info_get_signal (GIInterfaceInfo *info, rinfo->typelib, offset); } +/** + * g_interface_info_find_signal: + * @info: a #GIInterfaceInfo + * @name: Name of signal + * + * Returns: (transfer full): Info for the signal with name @name in @info, or + * %NULL on failure. + * + * Since: 1.34 + */ +GISignalInfo * +g_interface_info_find_signal (GIInterfaceInfo *info, + const gchar *name) +{ + gint n_signals; + gint i; + + n_signals = g_interface_info_get_n_signals (info); + for (i = 0; i < n_signals; i++) + { + GISignalInfo *siginfo = g_interface_info_get_signal (info, i); + + if (g_strcmp0 (g_base_info_get_name (siginfo), name) != 0) + { + g_base_info_unref ((GIBaseInfo*)siginfo); + continue; + } + + return siginfo; + } + return NULL; +} + /** * g_interface_info_get_n_vfuncs: * @info: a #GIInterfaceInfo diff --git a/giinterfaceinfo.h b/giinterfaceinfo.h index 8cab9961a..ce40cda7e 100644 --- a/giinterfaceinfo.h +++ b/giinterfaceinfo.h @@ -48,6 +48,8 @@ GIFunctionInfo * g_interface_info_find_method (GIInterfaceInfo *info, gint g_interface_info_get_n_signals (GIInterfaceInfo *info); GISignalInfo * g_interface_info_get_signal (GIInterfaceInfo *info, gint n); +GISignalInfo * g_interface_info_find_signal (GIInterfaceInfo *info, + const gchar *name); gint g_interface_info_get_n_vfuncs (GIInterfaceInfo *info); GIVFuncInfo * g_interface_info_get_vfunc (GIInterfaceInfo *info, gint n); From 56048fc81c985b20e9b9af78573b49e7e4e8cf27 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 25 Aug 2012 04:05:17 -0300 Subject: [PATCH 492/692] girepository: Fix leak in g_vfunc_info_get_address We need to fix the struct info here. https://bugzilla.gnome.org/show_bug.cgi?id=682647 --- givfuncinfo.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/givfuncinfo.c b/givfuncinfo.c index f9ba64a7f..9d6ea39db 100644 --- a/givfuncinfo.c +++ b/givfuncinfo.c @@ -220,7 +220,8 @@ g_vfunc_info_get_address (GIVFuncInfo *vfunc_info, GIStructInfo *struct_info; GIFieldInfo *field_info = NULL; int length, i, offset; - gpointer implementor_vtable, func; + gpointer implementor_vtable; + gpointer func = NULL; object_info = (GIObjectInfo *) g_base_info_get_container (vfunc_info); struct_info = g_object_info_get_class_struct (object_info); @@ -246,7 +247,7 @@ g_vfunc_info_get_address (GIVFuncInfo *vfunc_info, G_INVOKE_ERROR, G_INVOKE_ERROR_SYMBOL_NOT_FOUND, "Couldn't find struct field for this vfunc"); - return NULL; + goto out; } implementor_vtable = g_type_class_ref (implementor_gtype); @@ -263,9 +264,12 @@ g_vfunc_info_get_address (GIVFuncInfo *vfunc_info, "Class %s doesn't implement %s", g_type_name (implementor_gtype), g_base_info_get_name ( (GIBaseInfo*) vfunc_info)); - return NULL; + goto out; } + out: + g_base_info_unref ((GIBaseInfo*) struct_info); + return func; } From 1eb27e4bf8561055f46bc5e7fc1b729451633497 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Mon, 3 Sep 2012 14:39:31 +0200 Subject: [PATCH 493/692] ginvoke: support conversion of fundamental type GParamSpec values https://bugzilla.gnome.org/show_bug.cgi?id=683265 --- ginvoke.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ginvoke.c b/ginvoke.c index ed4996d9f..5c0ace4c8 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -52,6 +52,7 @@ value_to_ffi_type (const GValue *gvalue, gpointer *value) case G_TYPE_OBJECT: case G_TYPE_BOXED: case G_TYPE_POINTER: + case G_TYPE_PARAM: rettype = &ffi_type_pointer; *value = (gpointer)&(gvalue->data[0].v_pointer); break; @@ -118,6 +119,7 @@ g_value_to_ffi_return_type (const GValue *gvalue, case G_TYPE_OBJECT: case G_TYPE_BOXED: case G_TYPE_POINTER: + case G_TYPE_PARAM: rettype = &ffi_type_pointer; break; case G_TYPE_FLOAT: @@ -198,6 +200,9 @@ g_value_from_ffi_value (GValue *gvalue, case G_TYPE_BOXED: g_value_set_boxed (gvalue, (gpointer)value->v_pointer); break; + case G_TYPE_PARAM: + g_value_set_param (gvalue, (gpointer)value->v_pointer); + break; default: g_warning ("Unsupported fundamental type: %s", g_type_name (g_type_fundamental (G_VALUE_TYPE (gvalue)))); From 5428e934b289db65b7dabd7cd637d6b377aac5ed Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 16 Oct 2012 10:58:08 -0400 Subject: [PATCH 494/692] Drop calls to g_type_init() And bump our GLib requirement. --- cmph-bdz-test.c | 1 - gi-dump-types.c | 2 -- gthash-test.c | 1 - 3 files changed, 4 deletions(-) diff --git a/cmph-bdz-test.c b/cmph-bdz-test.c index fdff9d179..92c445f8f 100644 --- a/cmph-bdz-test.c +++ b/cmph-bdz-test.c @@ -128,7 +128,6 @@ main(int argc, char **argv) { gint ret; - g_type_init (); g_test_init (&argc, &argv, NULL); g_test_add_func ("/cmph-bdz/search", test_search); diff --git a/gi-dump-types.c b/gi-dump-types.c index 13e7ae68a..69d8b12d4 100644 --- a/gi-dump-types.c +++ b/gi-dump-types.c @@ -10,8 +10,6 @@ main (int argc, GOutputStream *stdout; GModule *self; - g_type_init (); - stdout = g_unix_output_stream_new (1, FALSE); self = g_module_open (NULL, 0); diff --git a/gthash-test.c b/gthash-test.c index ea811e35a..faeb2dc5b 100644 --- a/gthash-test.c +++ b/gthash-test.c @@ -56,7 +56,6 @@ test_build_retrieve (void) int main(int argc, char **argv) { - g_type_init (); g_test_init (&argc, &argv, NULL); g_test_add_func ("/gthash/build-retrieve", test_build_retrieve); From 86b7d7cc99004242f9162d9608520fdc832c7098 Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Fri, 10 Aug 2012 11:43:02 +0800 Subject: [PATCH 495/692] cmph: Remove C99ism and other fixes ...So that it will compile on non-C99 compilers. The changes are mainly moving the variable declarations to the start of the resecptive blocks. Also, replace the use of buflen in chd.c as it might not be defined for all platforms, instead using packed_cr_size as it seems to represent the value that is to be printed/displayed by the debugging output. https://bugzilla.gnome.org/show_bug.cgi?id=681820 --- cmph/bdz.c | 19 +++-- cmph/bdz_ph.c | 12 ++- cmph/bmz.c | 29 ++++--- cmph/bmz8.c | 24 +++--- cmph/brz.c | 174 +++++++++++++++++++++++++---------------- cmph/chd.c | 8 +- cmph/chd_ph.c | 11 ++- cmph/chm.c | 26 +++--- cmph/compressed_rank.c | 16 ++-- cmph/compressed_seq.c | 42 +++++----- cmph/fch.c | 43 ++++++---- 11 files changed, 252 insertions(+), 152 deletions(-) diff --git a/cmph/bdz.c b/cmph/bdz.c index a385b152a..81cd7151c 100755 --- a/cmph/bdz.c +++ b/cmph/bdz.c @@ -489,6 +489,10 @@ int bdz_dump(cmph_t *mphf, FILE *fd) cmph_uint32 buflen; register size_t nbytes; bdz_data_t *data = (bdz_data_t *)mphf->data; + cmph_uint32 sizeg; +#ifdef DEBUG + cmph_uint32 i; +#endif __cmph_dump(mphf, fd); hash_state_dump(data->hl, &buf, &buflen); @@ -501,7 +505,7 @@ int bdz_dump(cmph_t *mphf, FILE *fd) nbytes = fwrite(&(data->m), sizeof(cmph_uint32), (size_t)1, fd); nbytes = fwrite(&(data->r), sizeof(cmph_uint32), (size_t)1, fd); - cmph_uint32 sizeg = (cmph_uint32)ceil(data->n/4.0); + sizeg = (cmph_uint32)ceil(data->n/4.0); nbytes = fwrite(data->g, sizeof(cmph_uint8)*sizeg, (size_t)1, fd); nbytes = fwrite(&(data->k), sizeof(cmph_uint32), (size_t)1, fd); @@ -509,12 +513,11 @@ int bdz_dump(cmph_t *mphf, FILE *fd) nbytes = fwrite(&(data->ranktablesize), sizeof(cmph_uint32), (size_t)1, fd); nbytes = fwrite(data->ranktable, sizeof(cmph_uint32)*(data->ranktablesize), (size_t)1, fd); - if (nbytes == 0 && ferror(fd)) { + if (nbytes == 0 && ferror(fd)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); return 0; } #ifdef DEBUG - cmph_uint32 i; fprintf(stderr, "G: "); for (i = 0; i < data->n; ++i) fprintf(stderr, "%u ", GETVALUE(data->g, i)); fprintf(stderr, "\n"); @@ -528,6 +531,9 @@ void bdz_load(FILE *f, cmph_t *mphf) cmph_uint32 buflen, sizeg; register size_t nbytes; bdz_data_t *bdz = (bdz_data_t *)malloc(sizeof(bdz_data_t)); +#ifdef DEBUG + cmph_uint32 i = 0; +#endif DEBUGP("Loading bdz mphf\n"); mphf->data = bdz; @@ -554,13 +560,13 @@ void bdz_load(FILE *f, cmph_t *mphf) bdz->ranktable = (cmph_uint32 *)calloc((size_t)bdz->ranktablesize, sizeof(cmph_uint32)); nbytes = fread(bdz->ranktable, sizeof(cmph_uint32)*(bdz->ranktablesize), (size_t)1, f); - if (nbytes == 0 && ferror(f)) { + if (nbytes == 0 && ferror(f)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); return; } #ifdef DEBUG - cmph_uint32 i = 0; + i = 0; fprintf(stderr, "G: "); for (i = 0; i < bdz->n; ++i) fprintf(stderr, "%u ", GETVALUE(bdz->g,i)); fprintf(stderr, "\n"); @@ -639,6 +645,7 @@ void bdz_pack(cmph_t *mphf, void *packed_mphf) { bdz_data_t *data = (bdz_data_t *)mphf->data; cmph_uint8 * ptr = packed_mphf; + cmph_uint32 sizeg; // packing hl type CMPH_HASH hl_type = hash_get_type(data->hl); @@ -665,7 +672,7 @@ void bdz_pack(cmph_t *mphf, void *packed_mphf) *ptr++ = data->b; // packing g - cmph_uint32 sizeg = (cmph_uint32)ceil(data->n/4.0); + sizeg = (cmph_uint32)ceil(data->n/4.0); memcpy(ptr, data->g, sizeof(cmph_uint8)*sizeg); } diff --git a/cmph/bdz_ph.c b/cmph/bdz_ph.c index 2e9860712..2095f1161 100755 --- a/cmph/bdz_ph.c +++ b/cmph/bdz_ph.c @@ -452,6 +452,10 @@ int bdz_ph_dump(cmph_t *mphf, FILE *fd) cmph_uint32 sizeg = 0; register size_t nbytes; bdz_ph_data_t *data = (bdz_ph_data_t *)mphf->data; +#ifdef DEBUG + cmph_uint32 i; +#endif + __cmph_dump(mphf, fd); hash_state_dump(data->hl, &buf, &buflen); @@ -466,12 +470,11 @@ int bdz_ph_dump(cmph_t *mphf, FILE *fd) sizeg = (cmph_uint32)ceil(data->n/5.0); nbytes = fwrite(data->g, sizeof(cmph_uint8)*sizeg, (size_t)1, fd); - if (nbytes == 0 && ferror(fd)) { + if (nbytes == 0 && ferror(fd)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); return 0; } #ifdef DEBUG - cmph_uint32 i; fprintf(stderr, "G: "); for (i = 0; i < data->n; ++i) fprintf(stderr, "%u ", GETVALUE(data->g, i)); fprintf(stderr, "\n"); @@ -506,7 +509,7 @@ void bdz_ph_load(FILE *f, cmph_t *mphf) bdz_ph->g = (cmph_uint8 *)calloc((size_t)sizeg, sizeof(cmph_uint8)); nbytes = fread(bdz_ph->g, sizeg*sizeof(cmph_uint8), (size_t)1, f); - if (nbytes == 0 && ferror(f)) { + if (nbytes == 0 && ferror(f)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); } return; @@ -556,6 +559,7 @@ void bdz_ph_pack(cmph_t *mphf, void *packed_mphf) { bdz_ph_data_t *data = (bdz_ph_data_t *)mphf->data; cmph_uint8 * ptr = packed_mphf; + cmph_uint32 sizeg; // packing hl type CMPH_HASH hl_type = hash_get_type(data->hl); @@ -571,7 +575,7 @@ void bdz_ph_pack(cmph_t *mphf, void *packed_mphf) ptr += sizeof(data->r); // packing g - cmph_uint32 sizeg = (cmph_uint32)ceil(data->n/5.0); + sizeg = (cmph_uint32)ceil(data->n/5.0); memcpy(ptr, data->g, sizeof(cmph_uint8)*sizeg); } diff --git a/cmph/bmz.c b/cmph/bmz.c index 9c6cea004..9573825af 100644 --- a/cmph/bmz.c +++ b/cmph/bmz.c @@ -450,6 +450,10 @@ int bmz_dump(cmph_t *mphf, FILE *fd) cmph_uint32 two = 2; //number of hash functions bmz_data_t *data = (bmz_data_t *)mphf->data; register size_t nbytes; +#ifdef DEBUG + cmph_uint32 i; +#endif + __cmph_dump(mphf, fd); nbytes = fwrite(&two, sizeof(cmph_uint32), (size_t)1, fd); @@ -470,12 +474,11 @@ int bmz_dump(cmph_t *mphf, FILE *fd) nbytes = fwrite(&(data->m), sizeof(cmph_uint32), (size_t)1, fd); nbytes = fwrite(data->g, sizeof(cmph_uint32)*(data->n), (size_t)1, fd); - if (nbytes == 0 && ferror(fd)) { + if (nbytes == 0 && ferror(fd)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); return 0; } #ifdef DEBUG - cmph_uint32 i; fprintf(stderr, "G: "); for (i = 0; i < data->n; ++i) fprintf(stderr, "%u ", data->g[i]); fprintf(stderr, "\n"); @@ -515,10 +518,11 @@ void bmz_load(FILE *f, cmph_t *mphf) bmz->g = (cmph_uint32 *)malloc(sizeof(cmph_uint32)*bmz->n); nbytes = fread(bmz->g, bmz->n*sizeof(cmph_uint32), (size_t)1, f); - if (nbytes == 0 && ferror(f)) { + if (nbytes == 0 && ferror(f)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); return; } + #ifdef DEBUG fprintf(stderr, "G: "); for (i = 0; i < bmz->n; ++i) fprintf(stderr, "%u ", bmz->g[i]); @@ -559,6 +563,7 @@ void bmz_pack(cmph_t *mphf, void *packed_mphf) bmz_data_t *data = (bmz_data_t *)mphf->data; cmph_uint8 * ptr = packed_mphf; + CMPH_HASH h2_type; // packing h1 type CMPH_HASH h1_type = hash_get_type(data->hashes[0]); @@ -570,7 +575,7 @@ void bmz_pack(cmph_t *mphf, void *packed_mphf) ptr += hash_state_packed_size(h1_type); // packing h2 type - CMPH_HASH h2_type = hash_get_type(data->hashes[1]); + h2_type = hash_get_type(data->hashes[1]); *((cmph_uint32 *) ptr) = h2_type; ptr += sizeof(cmph_uint32); @@ -612,18 +617,22 @@ cmph_uint32 bmz_search_packed(void *packed_mphf, const char *key, cmph_uint32 ke { register cmph_uint8 *h1_ptr = packed_mphf; register CMPH_HASH h1_type = *((cmph_uint32 *)h1_ptr); + register cmph_uint8 *h2_ptr; + register CMPH_HASH h2_type; + register cmph_uint32 *g_ptr, n, h1, h2; + h1_ptr += 4; - register cmph_uint8 *h2_ptr = h1_ptr + hash_state_packed_size(h1_type); - register CMPH_HASH h2_type = *((cmph_uint32 *)h2_ptr); + h2_ptr = h1_ptr + hash_state_packed_size(h1_type); + h2_type = *((cmph_uint32 *)h2_ptr); h2_ptr += 4; - register cmph_uint32 *g_ptr = (cmph_uint32 *)(h2_ptr + hash_state_packed_size(h2_type)); + g_ptr = (cmph_uint32 *)(h2_ptr + hash_state_packed_size(h2_type)); - register cmph_uint32 n = *g_ptr++; + n = *g_ptr++; - register cmph_uint32 h1 = hash_packed(h1_ptr, h1_type, key, keylen) % n; - register cmph_uint32 h2 = hash_packed(h2_ptr, h2_type, key, keylen) % n; + h1 = hash_packed(h1_ptr, h1_type, key, keylen) % n; + h2 = hash_packed(h2_ptr, h2_type, key, keylen) % n; if (h1 == h2 && ++h2 > n) h2 = 0; return (g_ptr[h1] + g_ptr[h2]); } diff --git a/cmph/bmz8.c b/cmph/bmz8.c index 206c48c4d..15853c00b 100644 --- a/cmph/bmz8.c +++ b/cmph/bmz8.c @@ -483,7 +483,7 @@ int bmz8_dump(cmph_t *mphf, FILE *fd) nbytes = fwrite(&(data->m), sizeof(cmph_uint8), (size_t)1, fd); nbytes = fwrite(data->g, sizeof(cmph_uint8)*(data->n), (size_t)1, fd); - if (nbytes == 0 && ferror(fd)) { + if (nbytes == 0 && ferror(fd)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); return 0; } @@ -528,10 +528,11 @@ void bmz8_load(FILE *f, cmph_t *mphf) bmz8->g = (cmph_uint8 *)malloc(sizeof(cmph_uint8)*bmz8->n); nbytes = fread(bmz8->g, bmz8->n*sizeof(cmph_uint8), (size_t)1, f); - if (nbytes == 0 && ferror(f)) { + if (nbytes == 0 && ferror(f)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); return; } + #ifdef DEBUG fprintf(stderr, "G: "); for (i = 0; i < bmz8->n; ++i) fprintf(stderr, "%u ", bmz8->g[i]); @@ -571,6 +572,7 @@ void bmz8_pack(cmph_t *mphf, void *packed_mphf) { bmz8_data_t *data = (bmz8_data_t *)mphf->data; cmph_uint8 * ptr = packed_mphf; + CMPH_HASH h2_type; // packing h1 type CMPH_HASH h1_type = hash_get_type(data->hashes[0]); @@ -582,7 +584,7 @@ void bmz8_pack(cmph_t *mphf, void *packed_mphf) ptr += hash_state_packed_size(h1_type); // packing h2 type - CMPH_HASH h2_type = hash_get_type(data->hashes[1]); + h2_type = hash_get_type(data->hashes[1]); *((cmph_uint32 *) ptr) = h2_type; ptr += sizeof(cmph_uint32); @@ -623,18 +625,22 @@ cmph_uint8 bmz8_search_packed(void *packed_mphf, const char *key, cmph_uint32 ke { register cmph_uint8 *h1_ptr = packed_mphf; register CMPH_HASH h1_type = *((cmph_uint32 *)h1_ptr); + register cmph_uint8 *h2_ptr; + register CMPH_HASH h2_type; + register cmph_uint8 *g_ptr, n, h1, h2; + h1_ptr += 4; - register cmph_uint8 *h2_ptr = h1_ptr + hash_state_packed_size(h1_type); - register CMPH_HASH h2_type = *((cmph_uint32 *)h2_ptr); + h2_ptr = h1_ptr + hash_state_packed_size(h1_type); + h2_type = *((cmph_uint32 *)h2_ptr); h2_ptr += 4; - register cmph_uint8 *g_ptr = h2_ptr + hash_state_packed_size(h2_type); + g_ptr = h2_ptr + hash_state_packed_size(h2_type); - register cmph_uint8 n = *g_ptr++; + n = *g_ptr++; - register cmph_uint8 h1 = (cmph_uint8)(hash_packed(h1_ptr, h1_type, key, keylen) % n); - register cmph_uint8 h2 = (cmph_uint8)(hash_packed(h2_ptr, h2_type, key, keylen) % n); + h1 = (cmph_uint8)(hash_packed(h1_ptr, h1_type, key, keylen) % n); + h2 = (cmph_uint8)(hash_packed(h2_ptr, h2_type, key, keylen) % n); DEBUGP("key: %s h1: %u h2: %u\n", key, h1, h2); if (h1 == h2 && ++h2 > n) h2 = 0; return (cmph_uint8)(g_ptr[h1] + g_ptr[h2]); diff --git a/cmph/brz.c b/cmph/brz.c index f0c91c4bd..d1079c227 100755 --- a/cmph/brz.c +++ b/cmph/brz.c @@ -128,9 +128,10 @@ cmph_t *brz_new(cmph_config_t *mph, double c) brz_data_t *brzf = NULL; cmph_uint32 i; cmph_uint32 iterations = 20; + brz_config_data_t *brz; DEBUGP("c: %f\n", c); - brz_config_data_t *brz = (brz_config_data_t *)mph->data; + brz = (brz_config_data_t *)mph->data; switch(brz->algo) // validating restrictions over parameter c. { case CMPH_BMZ8: @@ -252,13 +253,14 @@ static int brz_gen_mphf(cmph_config_t *mph) /* Buffers management */ if (memory_usage + keylen + sizeof(keylen) > brz->memory_availability) // flush buffers { + cmph_uint32 value, sum, keylen1; if(mph->verbosity) { fprintf(stderr, "Flushing %u\n", nkeys_in_buffer); } - cmph_uint32 value = buckets_size[0]; - cmph_uint32 sum = 0; - cmph_uint32 keylen1 = 0; + value = buckets_size[0]; + sum = 0; + keylen1 = 0; buckets_size[0] = 0; for(i = 1; i < brz->k; i++) { @@ -312,14 +314,16 @@ static int brz_gen_mphf(cmph_config_t *mph) mph->key_source->dispose(mph->key_source->data, key, keylen); } if (memory_usage != 0) // flush buffers - { + { + cmph_uint32 value; + cmph_uint32 sum, keylen1; if(mph->verbosity) { fprintf(stderr, "Flushing %u\n", nkeys_in_buffer); } - cmph_uint32 value = buckets_size[0]; - cmph_uint32 sum = 0; - cmph_uint32 keylen1 = 0; + value = buckets_size[0]; + sum = 0; + keylen1 = 0; buckets_size[0] = 0; for(i = 1; i < brz->k; i++) { @@ -371,7 +375,7 @@ static int brz_gen_mphf(cmph_config_t *mph) nbytes = fwrite(&(brz->algo), sizeof(brz->algo), (size_t)1, brz->mphf_fd); nbytes = fwrite(&(brz->k), sizeof(cmph_uint32), (size_t)1, brz->mphf_fd); // number of MPHFs nbytes = fwrite(brz->size, sizeof(cmph_uint8)*(brz->k), (size_t)1, brz->mphf_fd); - if (nbytes == 0 && ferror(brz->mphf_fd)) { + if (nbytes == 0 && ferror(brz->mphf_fd)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); return 0; } @@ -579,7 +583,7 @@ int brz_dump(cmph_t *mphf, FILE *fd) // Dumping m and the vector offset. nbytes = fwrite(&(data->m), sizeof(cmph_uint32), (size_t)1, fd); nbytes = fwrite(data->offset, sizeof(cmph_uint32)*(data->k), (size_t)1, fd); - if (nbytes == 0 && ferror(fd)) { + if (nbytes == 0 && ferror(fd)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); return 0; } @@ -648,24 +652,27 @@ void brz_load(FILE *f, cmph_t *mphf) nbytes = fread(&(brz->m), sizeof(cmph_uint32), (size_t)1, f); brz->offset = (cmph_uint32 *)malloc(sizeof(cmph_uint32)*brz->k); nbytes = fread(brz->offset, sizeof(cmph_uint32)*(brz->k), (size_t)1, f); - if (nbytes == 0 && ferror(f)) { + if (nbytes == 0 && ferror(f)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); } + return; } static cmph_uint32 brz_bmz8_search(brz_data_t *brz, const char *key, cmph_uint32 keylen, cmph_uint32 * fingerprint) { register cmph_uint32 h0; + register cmph_uint32 m, n, h1, h2; + register cmph_uint8 mphf_bucket; hash_vector(brz->h0, key, keylen, fingerprint); h0 = fingerprint[2] % brz->k; - register cmph_uint32 m = brz->size[h0]; - register cmph_uint32 n = (cmph_uint32)ceil(brz->c * m); - register cmph_uint32 h1 = hash(brz->h1[h0], key, keylen) % n; - register cmph_uint32 h2 = hash(brz->h2[h0], key, keylen) % n; - register cmph_uint8 mphf_bucket; + m = brz->size[h0]; + n = (cmph_uint32)ceil(brz->c * m); + h1 = hash(brz->h1[h0], key, keylen) % n; + h2 = hash(brz->h2[h0], key, keylen) % n; + mphf_bucket; if (h1 == h2 && ++h2 >= n) h2 = 0; mphf_bucket = (cmph_uint8)(brz->g[h0][h1] + brz->g[h0][h2]); @@ -678,17 +685,20 @@ static cmph_uint32 brz_bmz8_search(brz_data_t *brz, const char *key, cmph_uint32 static cmph_uint32 brz_fch_search(brz_data_t *brz, const char *key, cmph_uint32 keylen, cmph_uint32 * fingerprint) { register cmph_uint32 h0; + register cmph_uint32 m, b, h1, h2; + register double p1, p2; + register cmph_uint8 mphf_bucket; hash_vector(brz->h0, key, keylen, fingerprint); h0 = fingerprint[2] % brz->k; - register cmph_uint32 m = brz->size[h0]; - register cmph_uint32 b = fch_calc_b(brz->c, m); - register double p1 = fch_calc_p1(m); - register double p2 = fch_calc_p2(b); - register cmph_uint32 h1 = hash(brz->h1[h0], key, keylen) % m; - register cmph_uint32 h2 = hash(brz->h2[h0], key, keylen) % m; - register cmph_uint8 mphf_bucket = 0; + m = brz->size[h0]; + b = fch_calc_b(brz->c, m); + p1 = fch_calc_p1(m); + p2 = fch_calc_p2(b); + h1 = hash(brz->h1[h0], key, keylen) % m; + h2 = hash(brz->h2[h0], key, keylen) % m; + mphf_bucket = 0; h1 = mixh10h11h12(b, p1, p2, h1); mphf_bucket = (cmph_uint8)((h2 + brz->g[h0][h1]) % m); return (mphf_bucket + brz->offset[h0]); @@ -741,13 +751,20 @@ void brz_pack(cmph_t *mphf, void *packed_mphf) brz_data_t *data = (brz_data_t *)mphf->data; cmph_uint8 * ptr = packed_mphf; cmph_uint32 i,n; + CMPH_HASH h0_type, h1_type, h2_type; +#if defined (__ia64) || defined (__x86_64__) + cmph_uint64 * g_is_ptr; +#else + cmph_uint32 * g_is_ptr; +#endif + cmph_uint8 * g_i; // packing internal algo type memcpy(ptr, &(data->algo), sizeof(data->algo)); ptr += sizeof(data->algo); // packing h0 type - CMPH_HASH h0_type = hash_get_type(data->h0); + h0_type = hash_get_type(data->h0); memcpy(ptr, &h0_type, sizeof(h0_type)); ptr += sizeof(h0_type); @@ -764,12 +781,12 @@ void brz_pack(cmph_t *mphf, void *packed_mphf) ptr += sizeof(data->c); // packing h1 type - CMPH_HASH h1_type = hash_get_type(data->h1[0]); + h1_type = hash_get_type(data->h1[0]); memcpy(ptr, &h1_type, sizeof(h1_type)); ptr += sizeof(h1_type); // packing h2 type - CMPH_HASH h2_type = hash_get_type(data->h2[0]); + h2_type = hash_get_type(data->h2[0]); memcpy(ptr, &h2_type, sizeof(h2_type)); ptr += sizeof(h2_type); @@ -782,12 +799,12 @@ void brz_pack(cmph_t *mphf, void *packed_mphf) ptr += sizeof(cmph_uint32)*data->k; #if defined (__ia64) || defined (__x86_64__) - cmph_uint64 * g_is_ptr = (cmph_uint64 *)ptr; + g_is_ptr = (cmph_uint64 *)ptr; #else - cmph_uint32 * g_is_ptr = (cmph_uint32 *)ptr; + g_is_ptr = (cmph_uint32 *)ptr; #endif - cmph_uint8 * g_i = (cmph_uint8 *) (g_is_ptr + data->k); + g_i = (cmph_uint8 *) (g_is_ptr + data->k); for(i = 0; i < data->k; i++) { @@ -835,6 +852,7 @@ cmph_uint32 brz_packed_size(cmph_t *mphf) CMPH_HASH h0_type = hash_get_type(data->h0); CMPH_HASH h1_type = hash_get_type(data->h1[0]); CMPH_HASH h2_type = hash_get_type(data->h2[0]); + cmph_uint32 n; size = (cmph_uint32)(2*sizeof(CMPH_ALGO) + 3*sizeof(CMPH_HASH) + hash_state_packed_size(h0_type) + sizeof(cmph_uint32) + sizeof(double) + sizeof(cmph_uint8)*data->k + sizeof(cmph_uint32)*data->k); // pointers to g_is @@ -847,7 +865,7 @@ cmph_uint32 brz_packed_size(cmph_t *mphf) size += hash_state_packed_size(h1_type) * data->k; size += hash_state_packed_size(h2_type) * data->k; - cmph_uint32 n = 0; + n = 0; for(i = 0; i < data->k; i++) { switch(data->algo) @@ -871,47 +889,57 @@ static cmph_uint32 brz_bmz8_search_packed(cmph_uint32 *packed_mphf, const char * { register CMPH_HASH h0_type = *packed_mphf++; register cmph_uint32 *h0_ptr = packed_mphf; + register cmph_uint32 k, h0, m, n, h1, h2; + register cmph_uint32 *offset; + register double c; + register CMPH_HASH h1_type, h2_type; + register cmph_uint8 * size; +#if defined (__ia64) || defined (__x86_64__) + register cmph_uint64 * g_is_ptr; +#else + register cmph_uint32 * g_is_ptr; +#endif + register cmph_uint8 *h1_ptr, *h2_ptr, *g; + register cmph_uint8 mphf_bucket; + packed_mphf = (cmph_uint32 *)(((cmph_uint8 *)packed_mphf) + hash_state_packed_size(h0_type)); - register cmph_uint32 k = *packed_mphf++; + k = *packed_mphf++; - register double c = (double)(*((cmph_uint64*)packed_mphf)); + c = (double)(*((cmph_uint64*)packed_mphf)); packed_mphf += 2; - register CMPH_HASH h1_type = *packed_mphf++; + h1_type = *packed_mphf++; - register CMPH_HASH h2_type = *packed_mphf++; + h2_type = *packed_mphf++; - register cmph_uint8 * size = (cmph_uint8 *) packed_mphf; + size = (cmph_uint8 *) packed_mphf; packed_mphf = (cmph_uint32 *)(size + k); - register cmph_uint32 * offset = packed_mphf; + offset = packed_mphf; packed_mphf += k; - register cmph_uint32 h0; hash_vector_packed(h0_ptr, h0_type, key, keylen, fingerprint); h0 = fingerprint[2] % k; - register cmph_uint32 m = size[h0]; - register cmph_uint32 n = (cmph_uint32)ceil(c * m); + m = size[h0]; + n = (cmph_uint32)ceil(c * m); #if defined (__ia64) || defined (__x86_64__) - register cmph_uint64 * g_is_ptr = (cmph_uint64 *)packed_mphf; + g_is_ptr = (cmph_uint64 *)packed_mphf; #else - register cmph_uint32 * g_is_ptr = packed_mphf; + g_is_ptr = packed_mphf; #endif - register cmph_uint8 * h1_ptr = (cmph_uint8 *) g_is_ptr[h0]; + h1_ptr = (cmph_uint8 *) g_is_ptr[h0]; - register cmph_uint8 * h2_ptr = h1_ptr + hash_state_packed_size(h1_type); + h2_ptr = h1_ptr + hash_state_packed_size(h1_type); - register cmph_uint8 * g = h2_ptr + hash_state_packed_size(h2_type); + g = h2_ptr + hash_state_packed_size(h2_type); - register cmph_uint32 h1 = hash_packed(h1_ptr, h1_type, key, keylen) % n; - register cmph_uint32 h2 = hash_packed(h2_ptr, h2_type, key, keylen) % n; - - register cmph_uint8 mphf_bucket; + h1 = hash_packed(h1_ptr, h1_type, key, keylen) % n; + h2 = hash_packed(h2_ptr, h2_type, key, keylen) % n; if (h1 == h2 && ++h2 >= n) h2 = 0; mphf_bucket = (cmph_uint8)(g[h1] + g[h2]); @@ -925,49 +953,59 @@ static cmph_uint32 brz_fch_search_packed(cmph_uint32 *packed_mphf, const char *k register CMPH_HASH h0_type = *packed_mphf++; register cmph_uint32 *h0_ptr = packed_mphf; + register cmph_uint32 k, h0, m, b, h1, h2; + register double c, p1, p2; + register CMPH_HASH h1_type, h2_type; + register cmph_uint8 *size, *h1_ptr, *h2_ptr, *g; + register cmph_uint32 *offset; +#if defined (__ia64) || defined (__x86_64__) + register cmph_uint64 * g_is_ptr; +#else + register cmph_uint32 * g_is_ptr; +#endif + register cmph_uint8 mphf_bucket; + packed_mphf = (cmph_uint32 *)(((cmph_uint8 *)packed_mphf) + hash_state_packed_size(h0_type)); - register cmph_uint32 k = *packed_mphf++; + k = *packed_mphf++; - register double c = (double)(*((cmph_uint64*)packed_mphf)); + c = (double)(*((cmph_uint64*)packed_mphf)); packed_mphf += 2; - register CMPH_HASH h1_type = *packed_mphf++; + h1_type = *packed_mphf++; - register CMPH_HASH h2_type = *packed_mphf++; + h2_type = *packed_mphf++; - register cmph_uint8 * size = (cmph_uint8 *) packed_mphf; + size = (cmph_uint8 *) packed_mphf; packed_mphf = (cmph_uint32 *)(size + k); - register cmph_uint32 * offset = packed_mphf; + offset = packed_mphf; packed_mphf += k; - register cmph_uint32 h0; - hash_vector_packed(h0_ptr, h0_type, key, keylen, fingerprint); h0 = fingerprint[2] % k; - register cmph_uint32 m = size[h0]; - register cmph_uint32 b = fch_calc_b(c, m); - register double p1 = fch_calc_p1(m); - register double p2 = fch_calc_p2(b); + m = size[h0]; + b = fch_calc_b(c, m); + p1 = fch_calc_p1(m); + p2 = fch_calc_p2(b); #if defined (__ia64) || defined (__x86_64__) - register cmph_uint64 * g_is_ptr = (cmph_uint64 *)packed_mphf; + g_is_ptr = (cmph_uint64 *)packed_mphf; #else - register cmph_uint32 * g_is_ptr = packed_mphf; + g_is_ptr = packed_mphf; #endif - register cmph_uint8 * h1_ptr = (cmph_uint8 *) g_is_ptr[h0]; + h1_ptr = (cmph_uint8 *) g_is_ptr[h0]; - register cmph_uint8 * h2_ptr = h1_ptr + hash_state_packed_size(h1_type); + h2_ptr = h1_ptr + hash_state_packed_size(h1_type); - register cmph_uint8 * g = h2_ptr + hash_state_packed_size(h2_type); + g = h2_ptr + hash_state_packed_size(h2_type); - register cmph_uint32 h1 = hash_packed(h1_ptr, h1_type, key, keylen) % m; - register cmph_uint32 h2 = hash_packed(h2_ptr, h2_type, key, keylen) % m; + h1 = hash_packed(h1_ptr, h1_type, key, keylen) % m; + h2 = hash_packed(h2_ptr, h2_type, key, keylen) % m; - register cmph_uint8 mphf_bucket = 0; + mphf_bucket = 0; h1 = mixh10h11h12(b, p1, p2, h1); mphf_bucket = (cmph_uint8)((h2 + g[h1]) % m); return (mphf_bucket + offset[h0]); diff --git a/cmph/chd.c b/cmph/chd.c index 71579ee34..46aec52db 100644 --- a/cmph/chd.c +++ b/cmph/chd.c @@ -190,9 +190,10 @@ void chd_load(FILE *fd, cmph_t *mphf) DEBUGP("Loading Compressed rank structure, which has %u bytes\n", chd->packed_cr_size); chd->packed_cr = (cmph_uint8 *) calloc((size_t)chd->packed_cr_size, (size_t)1); nbytes = fread(chd->packed_cr, chd->packed_cr_size, (size_t)1, fd); - if (nbytes == 0 && ferror(fd)) { + if (nbytes == 0 && ferror(fd)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); } + } int chd_dump(cmph_t *mphf, FILE *fd) @@ -207,13 +208,14 @@ int chd_dump(cmph_t *mphf, FILE *fd) nbytes = fwrite(&data->packed_chd_phf_size, sizeof(cmph_uint32), (size_t)1, fd); nbytes = fwrite(data->packed_chd_phf, data->packed_chd_phf_size, (size_t)1, fd); - DEBUGP("Dumping compressed rank structure with %u bytes to disk\n", buflen); + DEBUGP("Dumping compressed rank structure with %u bytes to disk\n", data->packed_cr_size); nbytes = fwrite(&data->packed_cr_size, sizeof(cmph_uint32), (size_t)1, fd); nbytes = fwrite(data->packed_cr, data->packed_cr_size, (size_t)1, fd); - if (nbytes == 0 && ferror(fd)) { + if (nbytes == 0 && ferror(fd)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); return 0; } + return 1; } diff --git a/cmph/chd_ph.c b/cmph/chd_ph.c index 6cd9437a9..8356bded9 100644 --- a/cmph/chd_ph.c +++ b/cmph/chd_ph.c @@ -193,8 +193,9 @@ void chd_ph_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs) void chd_ph_config_set_b(cmph_config_t *mph, cmph_uint32 keys_per_bucket) { + chd_ph_config_data_t *chd_ph; assert(mph); - chd_ph_config_data_t *chd_ph = (chd_ph_config_data_t *)mph->data; + chd_ph = (chd_ph_config_data_t *)mph->data; if(keys_per_bucket < 1 || keys_per_bucket >= 15) { keys_per_bucket = 4; @@ -205,8 +206,9 @@ void chd_ph_config_set_b(cmph_config_t *mph, cmph_uint32 keys_per_bucket) void chd_ph_config_set_keys_per_bin(cmph_config_t *mph, cmph_uint32 keys_per_bin) { + chd_ph_config_data_t *chd_ph; assert(mph); - chd_ph_config_data_t *chd_ph = (chd_ph_config_data_t *)mph->data; + chd_ph = (chd_ph_config_data_t *)mph->data; if(keys_per_bin <= 1 || keys_per_bin >= 128) { keys_per_bin = 1; @@ -860,9 +862,10 @@ void chd_ph_load(FILE *fd, cmph_t *mphf) DEBUGP("Reading n and nbuckets\n"); nbytes = fread(&(chd_ph->n), sizeof(cmph_uint32), (size_t)1, fd); nbytes = fread(&(chd_ph->nbuckets), sizeof(cmph_uint32), (size_t)1, fd); - if (nbytes == 0 && ferror(fd)) { + if (nbytes == 0 && ferror(fd)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); } + } int chd_ph_dump(cmph_t *mphf, FILE *fd) @@ -889,7 +892,7 @@ int chd_ph_dump(cmph_t *mphf, FILE *fd) // dumping n and nbuckets nbytes = fwrite(&(data->n), sizeof(cmph_uint32), (size_t)1, fd); nbytes = fwrite(&(data->nbuckets), sizeof(cmph_uint32), (size_t)1, fd); - if (nbytes == 0 && ferror(fd)) { + if (nbytes == 0 && ferror(fd)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); return 0; } diff --git a/cmph/chm.c b/cmph/chm.c index 3af8c8069..36a07a0d3 100644 --- a/cmph/chm.c +++ b/cmph/chm.c @@ -226,7 +226,7 @@ int chm_dump(cmph_t *mphf, FILE *fd) nbytes = fwrite(&(data->m), sizeof(cmph_uint32), (size_t)1, fd); nbytes = fwrite(data->g, sizeof(cmph_uint32)*data->n, (size_t)1, fd); - if (nbytes == 0 && ferror(fd)) { + if (nbytes == 0 && ferror(fd)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); return 0; } @@ -270,7 +270,7 @@ void chm_load(FILE *f, cmph_t *mphf) chm->g = (cmph_uint32 *)malloc(sizeof(cmph_uint32)*chm->n); nbytes = fread(chm->g, chm->n*sizeof(cmph_uint32), (size_t)1, f); - if (nbytes == 0 && ferror(f)) { + if (nbytes == 0 && ferror(f)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); return; } @@ -313,6 +313,7 @@ void chm_pack(cmph_t *mphf, void *packed_mphf) { chm_data_t *data = (chm_data_t *)mphf->data; cmph_uint8 * ptr = packed_mphf; + CMPH_HASH h2_type; // packing h1 type CMPH_HASH h1_type = hash_get_type(data->hashes[0]); @@ -324,7 +325,7 @@ void chm_pack(cmph_t *mphf, void *packed_mphf) ptr += hash_state_packed_size(h1_type); // packing h2 type - CMPH_HASH h2_type = hash_get_type(data->hashes[1]); + h2_type = hash_get_type(data->hashes[1]); *((cmph_uint32 *) ptr) = h2_type; ptr += sizeof(cmph_uint32); @@ -370,19 +371,24 @@ cmph_uint32 chm_search_packed(void *packed_mphf, const char *key, cmph_uint32 ke { register cmph_uint8 *h1_ptr = packed_mphf; register CMPH_HASH h1_type = *((cmph_uint32 *)h1_ptr); + register cmph_uint8 *h2_ptr; + register CMPH_HASH h2_type; + register cmph_uint32 *g_ptr; + register cmph_uint32 n, m, h1, h2; + h1_ptr += 4; - register cmph_uint8 *h2_ptr = h1_ptr + hash_state_packed_size(h1_type); - register CMPH_HASH h2_type = *((cmph_uint32 *)h2_ptr); + h2_ptr = h1_ptr + hash_state_packed_size(h1_type); + h2_type = *((cmph_uint32 *)h2_ptr); h2_ptr += 4; - register cmph_uint32 *g_ptr = (cmph_uint32 *)(h2_ptr + hash_state_packed_size(h2_type)); + g_ptr = (cmph_uint32 *)(h2_ptr + hash_state_packed_size(h2_type)); - register cmph_uint32 n = *g_ptr++; - register cmph_uint32 m = *g_ptr++; + n = *g_ptr++; + m = *g_ptr++; - register cmph_uint32 h1 = hash_packed(h1_ptr, h1_type, key, keylen) % n; - register cmph_uint32 h2 = hash_packed(h2_ptr, h2_type, key, keylen) % n; + h1 = hash_packed(h1_ptr, h1_type, key, keylen) % n; + h2 = hash_packed(h2_ptr, h2_type, key, keylen) % n; DEBUGP("key: %s h1: %u h2: %u\n", key, h1, h2); if (h1 == h2 && ++h2 >= n) h2 = 0; DEBUGP("key: %s g[h1]: %u g[h2]: %u edges: %u\n", key, g_ptr[h1], g_ptr[h2], m); diff --git a/cmph/compressed_rank.c b/cmph/compressed_rank.c index 822b2e155..8019dbe5c 100644 --- a/cmph/compressed_rank.c +++ b/cmph/compressed_rank.c @@ -83,9 +83,9 @@ cmph_uint32 compressed_rank_query(compressed_rank_t * cr, cmph_uint32 idx) return cr->n; } - val_quot = idx >> cr->rem_r; - rems_mask = (1U << cr->rem_r) - 1U; - val_rem = idx & rems_mask; + val_quot = idx >> cr->rem_r; + rems_mask = (1U << cr->rem_r) - 1U; + val_rem = idx & rems_mask; if(val_quot == 0) { rank = sel_res = 0; @@ -128,6 +128,9 @@ void compressed_rank_dump(compressed_rank_t * cr, char **buf, cmph_uint32 *bufle register cmph_uint32 pos = 0; char * buf_sel = 0; cmph_uint32 buflen_sel = 0; +#ifdef DEBUG + cmph_uint32 i; +#endif *buflen = 4*(cmph_uint32)sizeof(cmph_uint32) + sel_size + vals_rems_size; @@ -164,7 +167,7 @@ void compressed_rank_dump(compressed_rank_t * cr, char **buf, cmph_uint32 *bufle memcpy(*buf + pos, buf_sel, buflen_sel); #ifdef DEBUG - cmph_uint32 i = 0; + i = 0; for(i = 0; i < buflen_sel; i++) { DEBUGP("pos = %u -- buf_sel[%u] = %u\n", pos, i, *(*buf + pos + i)); @@ -192,6 +195,9 @@ void compressed_rank_load(compressed_rank_t * cr, const char *buf, cmph_uint32 b register cmph_uint32 pos = 0; cmph_uint32 buflen_sel = 0; register cmph_uint32 vals_rems_size = 0; +#ifdef DEBUG + cmph_uint32 i; +#endif // loading max_val, n, and rem_r memcpy(&(cr->max_val), buf, sizeof(cmph_uint32)); @@ -213,7 +219,7 @@ void compressed_rank_load(compressed_rank_t * cr, const char *buf, cmph_uint32 b select_load(&cr->sel, buf + pos, buflen_sel); #ifdef DEBUG - cmph_uint32 i = 0; + i = 0; for(i = 0; i < buflen_sel; i++) { DEBUGP("pos = %u -- buf_sel[%u] = %u\n", pos, i, *(buf + pos + i)); diff --git a/cmph/compressed_seq.c b/cmph/compressed_seq.c index e558196d4..e5191fd5a 100644 --- a/cmph/compressed_seq.c +++ b/cmph/compressed_seq.c @@ -167,6 +167,9 @@ void compressed_seq_dump(compressed_seq_t * cs, char ** buf, cmph_uint32 * bufle register cmph_uint32 pos = 0; char * buf_sel = 0; cmph_uint32 buflen_sel = 0; +#ifdef DEBUG + cmph_uint32 i; +#endif *buflen = 4*(cmph_uint32)sizeof(cmph_uint32) + sel_size + length_rems_size + store_table_size; @@ -202,8 +205,8 @@ void compressed_seq_dump(compressed_seq_t * cs, char ** buf, cmph_uint32 * bufle DEBUGP("buflen_sel = %u\n", buflen_sel); memcpy(*buf + pos, buf_sel, buflen_sel); - #ifdef DEBUG - cmph_uint32 i = 0; + #ifdef DEBUG + i = 0; for(i = 0; i < buflen_sel; i++) { DEBUGP("pos = %u -- buf_sel[%u] = %u\n", pos, i, *(*buf + pos + i)); @@ -215,7 +218,7 @@ void compressed_seq_dump(compressed_seq_t * cs, char ** buf, cmph_uint32 * bufle // dumping length_rems memcpy(*buf + pos, cs->length_rems, length_rems_size); - #ifdef DEBUG + #ifdef DEBUG for(i = 0; i < length_rems_size; i++) { DEBUGP("pos = %u -- length_rems_size = %u -- length_rems[%u] = %u\n", pos, length_rems_size, i, *(*buf + pos + i)); @@ -226,7 +229,7 @@ void compressed_seq_dump(compressed_seq_t * cs, char ** buf, cmph_uint32 * bufle // dumping store_table memcpy(*buf + pos, cs->store_table, store_table_size); - #ifdef DEBUG + #ifdef DEBUG for(i = 0; i < store_table_size; i++) { DEBUGP("pos = %u -- store_table_size = %u -- store_table[%u] = %u\n", pos, store_table_size, i, *(*buf + pos + i)); @@ -241,6 +244,9 @@ void compressed_seq_load(compressed_seq_t * cs, const char * buf, cmph_uint32 bu cmph_uint32 buflen_sel = 0; register cmph_uint32 length_rems_size = 0; register cmph_uint32 store_table_size = 0; +#ifdef DEBUG + cmph_uint32 i; +#endif // loading n, rem_r and total_length memcpy(&(cs->n), buf, sizeof(cmph_uint32)); @@ -261,8 +267,8 @@ void compressed_seq_load(compressed_seq_t * cs, const char * buf, cmph_uint32 bu DEBUGP("buflen_sel = %u\n", buflen_sel); select_load(&cs->sel, buf + pos, buflen_sel); - #ifdef DEBUG - cmph_uint32 i = 0; + #ifdef DEBUG + i = 0; for(i = 0; i < buflen_sel; i++) { DEBUGP("pos = %u -- buf_sel[%u] = %u\n", pos, i, *(buf + pos + i)); @@ -280,7 +286,7 @@ void compressed_seq_load(compressed_seq_t * cs, const char * buf, cmph_uint32 bu length_rems_size *= 4; memcpy(cs->length_rems, buf + pos, length_rems_size); - #ifdef DEBUG + #ifdef DEBUG for(i = 0; i < length_rems_size; i++) { DEBUGP("pos = %u -- length_rems_size = %u -- length_rems[%u] = %u\n", pos, length_rems_size, i, *(buf + pos + i)); @@ -298,7 +304,7 @@ void compressed_seq_load(compressed_seq_t * cs, const char * buf, cmph_uint32 bu store_table_size *= 4; memcpy(cs->store_table, buf + pos, store_table_size); - #ifdef DEBUG + #ifdef DEBUG for(i = 0; i < store_table_size; i++) { DEBUGP("pos = %u -- store_table_size = %u -- store_table[%u] = %u\n", pos, store_table_size, i, *(buf + pos + i)); @@ -336,19 +342,19 @@ cmph_uint32 compressed_seq_query_packed(void * cs_packed, cmph_uint32 idx) register cmph_uint32 *ptr = (cmph_uint32 *)cs_packed; register cmph_uint32 n = *ptr++; register cmph_uint32 rem_r = *ptr++; + register cmph_uint32 buflen_sel, length_rems_size, enc_idx, enc_length; + // compressed sequence query computation + register cmph_uint32 rems_mask, stored_value, sel_res; + register cmph_uint32 *sel_packed, *length_rems, *store_table; + ptr++; // skipping total_length // register cmph_uint32 total_length = *ptr++; - register cmph_uint32 buflen_sel = *ptr++; - register cmph_uint32 * sel_packed = ptr; - register cmph_uint32 * length_rems = (ptr += (buflen_sel >> 2)); - register cmph_uint32 length_rems_size = BITS_TABLE_SIZE(n, rem_r); - register cmph_uint32 * store_table = (ptr += length_rems_size); + buflen_sel = *ptr++; + sel_packed = ptr; + length_rems = (ptr += (buflen_sel >> 2)); + length_rems_size = BITS_TABLE_SIZE(n, rem_r); + store_table = (ptr += length_rems_size); - // compressed sequence query computation - register cmph_uint32 enc_idx, enc_length; - register cmph_uint32 rems_mask; - register cmph_uint32 stored_value; - register cmph_uint32 sel_res; rems_mask = (1U << rem_r) - 1U; diff --git a/cmph/fch.c b/cmph/fch.c index f6e16e346..33b959e24 100644 --- a/cmph/fch.c +++ b/cmph/fch.c @@ -10,6 +10,7 @@ #include #include #include + #define INDEX 0 /* alignment index within a bucket */ //#define DEBUG #include "debug.h" @@ -320,6 +321,10 @@ int fch_dump(cmph_t *mphf, FILE *fd) register size_t nbytes; fch_data_t *data = (fch_data_t *)mphf->data; + +#ifdef DEBUG + cmph_uint32 i; +#endif __cmph_dump(mphf, fd); hash_state_dump(data->h1, &buf, &buflen); @@ -340,12 +345,11 @@ int fch_dump(cmph_t *mphf, FILE *fd) nbytes = fwrite(&(data->p1), sizeof(double), (size_t)1, fd); nbytes = fwrite(&(data->p2), sizeof(double), (size_t)1, fd); nbytes = fwrite(data->g, sizeof(cmph_uint32)*(data->b), (size_t)1, fd); - if (nbytes == 0 && ferror(fd)) { + if (nbytes == 0 && ferror(fd)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); return 0; } #ifdef DEBUG - cmph_uint32 i; fprintf(stderr, "G: "); for (i = 0; i < data->b; ++i) fprintf(stderr, "%u ", data->g[i]); fprintf(stderr, "\n"); @@ -359,6 +363,9 @@ void fch_load(FILE *f, cmph_t *mphf) cmph_uint32 buflen; register size_t nbytes; fch_data_t *fch = (fch_data_t *)malloc(sizeof(fch_data_t)); +#ifdef DEBUG + cmph_uint32 i; +#endif //DEBUGP("Loading fch mphf\n"); mphf->data = fch; @@ -392,12 +399,12 @@ void fch_load(FILE *f, cmph_t *mphf) fch->g = (cmph_uint32 *)malloc(sizeof(cmph_uint32)*fch->b); nbytes = fread(fch->g, fch->b*sizeof(cmph_uint32), (size_t)1, f); - if (nbytes == 0 && ferror(f)) { + if (nbytes == 0 && ferror(f)) { fprintf(stderr, "ERROR: %s\n", strerror(errno)); return; } + #ifdef DEBUG - cmph_uint32 i; fprintf(stderr, "G: "); for (i = 0; i < fch->b; ++i) fprintf(stderr, "%u ", fch->g[i]); fprintf(stderr, "\n"); @@ -436,6 +443,7 @@ void fch_pack(cmph_t *mphf, void *packed_mphf) // packing h1 type CMPH_HASH h1_type = hash_get_type(data->h1); + CMPH_HASH h2_type; *((cmph_uint32 *) ptr) = h1_type; ptr += sizeof(cmph_uint32); @@ -444,7 +452,7 @@ void fch_pack(cmph_t *mphf, void *packed_mphf) ptr += hash_state_packed_size(h1_type); // packing h2 type - CMPH_HASH h2_type = hash_get_type(data->h2); + h2_type = hash_get_type(data->h2); *((cmph_uint32 *) ptr) = h2_type; ptr += sizeof(cmph_uint32); @@ -499,27 +507,32 @@ cmph_uint32 fch_search_packed(void *packed_mphf, const char *key, cmph_uint32 ke { register cmph_uint8 *h1_ptr = packed_mphf; register CMPH_HASH h1_type = *((cmph_uint32 *)h1_ptr); + register cmph_uint8 *h2_ptr; + register CMPH_HASH h2_type; + register cmph_uint32 *g_ptr; + register cmph_uint32 m, b, h1, h2; + register double p1, p2; + h1_ptr += 4; - register cmph_uint8 *h2_ptr = h1_ptr + hash_state_packed_size(h1_type); - register CMPH_HASH h2_type = *((cmph_uint32 *)h2_ptr); + h2_ptr = h1_ptr + hash_state_packed_size(h1_type); + h2_type = *((cmph_uint32 *)h2_ptr); h2_ptr += 4; - register cmph_uint32 *g_ptr = (cmph_uint32 *)(h2_ptr + hash_state_packed_size(h2_type)); + g_ptr = (cmph_uint32 *)(h2_ptr + hash_state_packed_size(h2_type)); - register cmph_uint32 m = *g_ptr++; + m = *g_ptr++; - register cmph_uint32 b = *g_ptr++; + b = *g_ptr++; - register double p1 = (double)(*((cmph_uint64 *)g_ptr)); + p1 = (double)(*((cmph_uint64 *)g_ptr)); g_ptr += 2; - register double p2 = (double)(*((cmph_uint64 *)g_ptr)); + p2 = (double)(*((cmph_uint64 *)g_ptr)); g_ptr += 2; - register cmph_uint32 h1 = hash_packed(h1_ptr, h1_type, key, keylen) % m; - register cmph_uint32 h2 = hash_packed(h2_ptr, h2_type, key, keylen) % m; - + h1 = hash_packed(h1_ptr, h1_type, key, keylen) % m; + h2 = hash_packed(h2_ptr, h2_type, key, keylen) % m; h1 = mixh10h11h12 (b, p1, p2, h1); return (h2 + g_ptr[h1]) % m; } From c449db7704751cd1acabdbbed9f9281422bef4c7 Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Tue, 24 Jul 2012 15:56:59 +0800 Subject: [PATCH 496/692] girffi.c: Don't include unistd.h unconditionally It does not exist on all platforms https://bugzilla.gnome.org/show_bug.cgi?id=681820 --- girffi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/girffi.c b/girffi.c index ec710c377..f4c80eaad 100644 --- a/girffi.c +++ b/girffi.c @@ -26,7 +26,9 @@ #include #include +#ifdef HAVE_UNISTD_H #include +#endif #include "girffi.h" #include "girepository.h" #include "girepository-private.h" From 08da5d65eeeba0fc2ebfc1e01c1f7e400ed8ac1e Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Tue, 24 Jul 2012 16:09:38 +0800 Subject: [PATCH 497/692] girepository: Remove C99ism and other updates -Make code using libgirepository_internals relocatable on Windows, like what is done in the GTK+ stack, and the girepository DLL. -Remove C99isms -"interface" is a reserved keyword on certain compilers, so change that to "giinterface" https://bugzilla.gnome.org/show_bug.cgi?id=681820 --- girmodule.c | 3 ++- girnode.c | 15 ++++++++++----- girnode.h | 2 +- giroffsets.c | 4 ++-- girparser.c | 33 +++++++++++++++++++++++++++------ 5 files changed, 42 insertions(+), 15 deletions(-) diff --git a/girmodule.c b/girmodule.c index af71f369b..05c8987fc 100644 --- a/girmodule.c +++ b/girmodule.c @@ -261,8 +261,9 @@ add_directory_index_section (guint8 *data, GIrModule *module, guint32 *offset2) for (i = 0; i < n_interfaces; i++) { + const char *str; entry = (DirEntry *)&data[header->directory + (i * header->entry_blob_size)]; - const char *str = (const char *) (&data[entry->name]); + str = (const char *) (&data[entry->name]); _gi_typelib_hash_builder_add_string (dirindex_builder, str, i); } diff --git a/girnode.c b/girnode.c index 881aa9be1..afb71e578 100644 --- a/girnode.c +++ b/girnode.c @@ -28,6 +28,11 @@ #include "girnode.h" #include "gitypelib-internal.h" +#ifdef _MSC_VER +#define strtoll _strtoi64 +#define strtoull _strtoui64 +#endif + static gulong string_count = 0; static gulong unique_string_count = 0; static gulong string_size = 0; @@ -228,7 +233,7 @@ _g_ir_node_free (GIrNode *node) _g_ir_node_free ((GIrNode *)type->parameter_type1); _g_ir_node_free ((GIrNode *)type->parameter_type2); - g_free (type->interface); + g_free (type->giinterface); g_strfreev (type->errors); } @@ -1244,7 +1249,7 @@ serialize_type (GIrTypelibBuild *build, GIrNode *iface; gchar *name; - iface = find_entry_node (build, node->interface, NULL); + iface = find_entry_node (build, node->giinterface, NULL); if (iface) { if (iface->type == G_IR_NODE_XREF) @@ -1253,8 +1258,8 @@ serialize_type (GIrTypelibBuild *build, } else { - g_warning ("Interface for type reference %s not found", node->interface); - name = node->interface; + g_warning ("Interface for type reference %s not found", node->giinterface); + name = node->giinterface; } g_string_append_printf (str, "%s%s", name, @@ -1483,7 +1488,7 @@ _g_ir_node_build_typelib (GIrNode *node, iface->reserved = 0; iface->tag = type->tag; iface->reserved2 = 0; - iface->interface = find_entry (build, type->interface); + iface->interface = find_entry (build, type->giinterface); } break; diff --git a/girnode.h b/girnode.h index d89847ac6..07b084c49 100644 --- a/girnode.h +++ b/girnode.h @@ -133,7 +133,7 @@ struct _GIrNodeType GIrNodeType *parameter_type1; GIrNodeType *parameter_type2; - gchar *interface; + gchar *giinterface; gchar **errors; }; diff --git a/giroffsets.c b/giroffsets.c index e3c9d7f51..368332eab 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -190,10 +190,10 @@ get_interface_size_alignment (GIrTypelibBuild *build, { GIrNode *iface; - iface = _g_ir_find_node (build, ((GIrNode*)type)->module, type->interface); + iface = _g_ir_find_node (build, ((GIrNode*)type)->module, type->giinterface); if (!iface) { - _g_ir_module_fatal (build, 0, "Can't resolve type '%s' for %s", type->interface, who); + _g_ir_module_fatal (build, 0, "Can't resolve type '%s' for %s", type->giinterface, who); *size = -1; *alignment = -1; return FALSE; diff --git a/girparser.c b/girparser.c index fa0de1f88..ce88a691b 100644 --- a/girparser.c +++ b/girparser.c @@ -36,6 +36,24 @@ */ #define SUPPORTED_GIR_VERSION "1.2" +#ifdef G_OS_WIN32 + +#include + +#ifdef GIR_DIR +#undef GIR_DIR +#endif + +/* GIR_DIR is used only in code called just once, + * so no problem leaking this + */ +#define GIR_DIR \ + g_build_filename (g_win32_get_package_installation_directory_of_module(NULL), \ + "share", \ + GIR_SUFFIX, \ + NULL) +#endif + struct _GIrParser { gchar **includes; @@ -329,10 +347,12 @@ state_switch (ParseContext *ctx, ParseState newstate) static GIrNode * pop_node (ParseContext *ctx) { + GSList *top; + GIrNode *node; g_assert (ctx->node_stack != 0); - GSList *top = ctx->node_stack; - GIrNode *node = top->data; + top = ctx->node_stack; + node = top->data; g_debug ("popping node %d %s", node->type, node->name); ctx->node_stack = top->next; @@ -552,8 +572,8 @@ parse_type_internal (GIrModule *module, if (*str == '<') { - (str)++; char *tmp, *end; + (str)++; end = strchr (str, '>'); tmp = g_strndup (str, end - str); @@ -565,9 +585,10 @@ parse_type_internal (GIrModule *module, } else { + const char *start; type->tag = GI_TYPE_TAG_INTERFACE; type->is_interface = TRUE; - const char *start = str; + start = str; /* must be an interface type */ while (g_ascii_isalnum (*str) || @@ -577,7 +598,7 @@ parse_type_internal (GIrModule *module, *str == ':') (str)++; - type->interface = g_strndup (start, str - start); + type->giinterface = g_strndup (start, str - start); } if (next) @@ -1965,7 +1986,7 @@ start_type (GMarkupParseContext *context, * doesn't look like a pointer, but is internally. */ if (typenode->tag == GI_TYPE_TAG_INTERFACE && - is_disguised_structure (ctx, typenode->interface)) + is_disguised_structure (ctx, typenode->giinterface)) pointer_depth++; if (pointer_depth > 0) From 671d1494f1768716dacb2c4e24e9cb664c0094d1 Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Fri, 10 Aug 2012 10:47:56 +0800 Subject: [PATCH 498/692] Add girepository.symbols This is the listing of symbols to export from the main libgirepository .dll/.so. This is used for example to generate the .lib file from the Windows DLL. https://bugzilla.gnome.org/show_bug.cgi?id=681820 --- girepository.symbols | 229 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 girepository.symbols diff --git a/girepository.symbols b/girepository.symbols new file mode 100644 index 000000000..c6dd1034c --- /dev/null +++ b/girepository.symbols @@ -0,0 +1,229 @@ +/* giarginfo.h */ +g_arg_info_get_closure +g_arg_info_get_destroy +g_arg_info_get_direction +g_arg_info_get_ownership_transfer +g_arg_info_get_scope +g_arg_info_get_type +g_arg_info_is_caller_allocates +g_arg_info_is_optional +g_arg_info_is_return_value +g_arg_info_is_skip +g_arg_info_load_type +g_arg_info_may_be_null + +/* gibaseinfo.h */ +g_base_info_equal +g_base_info_get_attribute +g_base_info_get_container +g_base_info_get_name +g_base_info_get_namespace +g_base_info_get_type +g_base_info_get_typelib +g_base_info_gtype_get_type +g_base_info_is_deprecated +g_base_info_iterate_attributes +g_base_info_ref +g_base_info_unref +g_info_new + +/* gicallableinfo.h */ +g_callable_info_get_arg +g_callable_info_get_caller_owns +g_callable_info_get_n_args +g_callable_info_get_return_attribute +g_callable_info_get_return_type +g_callable_info_invoke +g_callable_info_iterate_return_attributes +g_callable_info_load_arg +g_callable_info_load_return_type +g_callable_info_may_return_null +g_callable_info_skip_return + +/* giconstantinfo.h */ +g_constant_info_free_value +g_constant_info_get_type +g_constant_info_get_value + +/* gienuminfo.h */ +g_enum_info_get_error_domain +g_enum_info_get_method +g_enum_info_get_n_methods +g_enum_info_get_n_values +g_enum_info_get_storage_type +g_enum_info_get_value +g_value_info_get_value + +/* gifieldinfo.h */ +g_field_info_get_field +g_field_info_get_flags +g_field_info_get_offset +g_field_info_get_size +g_field_info_get_type +g_field_info_set_field + +/* gifunctioninfo.h */ +g_function_info_get_flags +g_function_info_get_property +g_function_info_get_symbol +g_function_info_get_vfunc +g_function_info_invoke +g_invoke_error_quark + +/* giinterfaceinfo.h */ +g_interface_info_find_method +g_interface_info_find_vfunc +g_interface_info_get_constant +g_interface_info_get_iface_struct +g_interface_info_get_method +g_interface_info_get_n_constants +g_interface_info_get_n_methods +g_interface_info_get_n_prerequisites +g_interface_info_get_n_properties +g_interface_info_get_prerequisite +g_interface_info_get_n_signals +g_interface_info_get_n_vfuncs +g_interface_info_get_property +g_interface_info_get_signal +g_interface_info_get_vfunc + +/* giobjectinfo.h */ +g_object_info_find_method +g_object_info_find_method_using_interfaces +g_object_info_find_signal +g_object_info_find_vfunc +g_object_info_find_vfunc_using_interfaces +g_object_info_get_abstract +g_object_info_get_class_struct +g_object_info_get_constant +g_object_info_get_field +g_object_info_get_fundamental +g_object_info_get_get_value_function +g_object_info_get_get_value_function_pointer +g_object_info_get_interface +g_object_info_get_method +g_object_info_get_n_constants +g_object_info_get_n_fields +g_object_info_get_n_interfaces +g_object_info_get_n_methods +g_object_info_get_n_properties +g_object_info_get_n_signals +g_object_info_get_n_vfuncs +g_object_info_get_parent +g_object_info_get_property +g_object_info_get_ref_function +g_object_info_get_ref_function_pointer +g_object_info_get_set_value_function +g_object_info_get_set_value_function_pointer +g_object_info_get_signal +g_object_info_get_type_init +g_object_info_get_type_name +g_object_info_get_unref_function +g_object_info_get_unref_function_pointer +g_object_info_get_vfunc + +/* gipropertyinfo.h */ +g_property_info_get_flags +g_property_info_get_ownership_transfer +g_property_info_get_type + +/* giregisteredtypeinfo.h */ +g_registered_type_info_get_g_type +g_registered_type_info_get_type_init +g_registered_type_info_get_type_name + +/* girepository.h */ +gi_cclosure_marshal_generic +g_irepository_dump +g_irepository_enumerate_versions +g_irepository_error_quark +g_irepository_find_by_error_domain +g_irepository_find_by_gtype +g_irepository_find_by_name +g_irepository_get_c_prefix +g_irepository_get_default +g_irepository_get_dependencies +g_irepository_get_info +g_irepository_get_loaded_namespaces +g_irepository_get_n_infos +g_irepository_get_option_group +g_irepository_get_search_path +g_irepository_get_shared_library +g_irepository_get_type +g_irepository_get_typelib_path +g_irepository_get_version +g_irepository_is_registered +g_irepository_load_typelib +g_irepository_prepend_search_path +g_irepository_require +g_irepository_require_private + +/* girffi.h */ +gi_type_info_extract_ffi_return_value +gi_type_tag_get_ffi_type +g_callable_info_free_closure +g_callable_info_prepare_closure +g_function_info_prep_invoker +g_function_invoker_destroy +g_function_invoker_new_for_address +g_type_info_get_ffi_type + +/*gisignalinfo.h */ +g_signal_info_get_class_closure +g_signal_info_get_flags +g_signal_info_true_stops_emit + +/* gustructinfo.h */ +g_struct_info_find_method +g_struct_info_get_alignment +g_struct_info_get_field +g_struct_info_get_method +g_struct_info_get_n_fields +g_struct_info_get_n_methods +g_struct_info_get_size +g_struct_info_is_foreign +g_struct_info_is_gtype_struct + +/* gitypeinfo.h */ +g_type_info_is_pointer +g_type_info_is_zero_terminated +g_type_info_get_array_fixed_size +g_type_info_get_array_length +g_type_info_get_array_type +g_type_info_get_interface +g_type_info_get_param_type +g_type_info_get_tag +g_type_tag_to_string +g_info_type_to_string + +/* gitypelib.h */ +g_typelib_check_sanity +g_typelib_error_quark +g_typelib_free +g_typelib_get_namespace +g_typelib_new_from_const_memory +g_typelib_new_from_mapped_file +g_typelib_new_from_memory +g_typelib_symbol +g_typelib_validate + +/* giunioninfo.h */ +g_union_info_find_method +g_union_info_get_alignment +g_union_info_get_discriminator +g_union_info_get_discriminator_offset +g_union_info_get_discriminator_type +g_union_info_get_field +g_union_info_get_method +g_union_info_get_n_fields +g_union_info_get_n_methods +g_union_info_get_size +g_union_info_is_discriminated + +/* givfuncinfo.h */ +g_vfunc_info_get_address +g_vfunc_info_get_invoker +g_vfunc_info_get_flags +g_vfunc_info_get_offset +g_vfunc_info_get_signal +g_vfunc_info_invoke From b7555303b319cb56ddf115dcaf4f1f9c158766bb Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 27 Oct 2012 12:24:12 -0400 Subject: [PATCH 499/692] girepository: Use girepository.symbols for Unix builds too Rather than having a regex for both builds, but *also* use a symbol file for the MSVC build which would bitrot quickly, force us to update the .symbols file by using it for Unix too. Add some missing symbols. --- girepository.symbols | 39 ++------------------------------------- 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/girepository.symbols b/girepository.symbols index c6dd1034c..11d2bb6d7 100644 --- a/girepository.symbols +++ b/girepository.symbols @@ -1,4 +1,3 @@ -/* giarginfo.h */ g_arg_info_get_closure g_arg_info_get_destroy g_arg_info_get_direction @@ -11,8 +10,6 @@ g_arg_info_is_return_value g_arg_info_is_skip g_arg_info_load_type g_arg_info_may_be_null - -/* gibaseinfo.h */ g_base_info_equal g_base_info_get_attribute g_base_info_get_container @@ -26,8 +23,7 @@ g_base_info_iterate_attributes g_base_info_ref g_base_info_unref g_info_new - -/* gicallableinfo.h */ +g_callable_info_can_throw_gerror g_callable_info_get_arg g_callable_info_get_caller_owns g_callable_info_get_n_args @@ -35,17 +31,14 @@ g_callable_info_get_return_attribute g_callable_info_get_return_type g_callable_info_invoke g_callable_info_iterate_return_attributes +g_callable_info_is_method g_callable_info_load_arg g_callable_info_load_return_type g_callable_info_may_return_null g_callable_info_skip_return - -/* giconstantinfo.h */ g_constant_info_free_value g_constant_info_get_type g_constant_info_get_value - -/* gienuminfo.h */ g_enum_info_get_error_domain g_enum_info_get_method g_enum_info_get_n_methods @@ -53,24 +46,18 @@ g_enum_info_get_n_values g_enum_info_get_storage_type g_enum_info_get_value g_value_info_get_value - -/* gifieldinfo.h */ g_field_info_get_field g_field_info_get_flags g_field_info_get_offset g_field_info_get_size g_field_info_get_type g_field_info_set_field - -/* gifunctioninfo.h */ g_function_info_get_flags g_function_info_get_property g_function_info_get_symbol g_function_info_get_vfunc g_function_info_invoke g_invoke_error_quark - -/* giinterfaceinfo.h */ g_interface_info_find_method g_interface_info_find_vfunc g_interface_info_get_constant @@ -86,8 +73,6 @@ g_interface_info_get_n_vfuncs g_interface_info_get_property g_interface_info_get_signal g_interface_info_get_vfunc - -/* giobjectinfo.h */ g_object_info_find_method g_object_info_find_method_using_interfaces g_object_info_find_signal @@ -121,18 +106,12 @@ g_object_info_get_type_name g_object_info_get_unref_function g_object_info_get_unref_function_pointer g_object_info_get_vfunc - -/* gipropertyinfo.h */ g_property_info_get_flags g_property_info_get_ownership_transfer g_property_info_get_type - -/* giregisteredtypeinfo.h */ g_registered_type_info_get_g_type g_registered_type_info_get_type_init g_registered_type_info_get_type_name - -/* girepository.h */ gi_cclosure_marshal_generic g_irepository_dump g_irepository_enumerate_versions @@ -157,8 +136,6 @@ g_irepository_load_typelib g_irepository_prepend_search_path g_irepository_require g_irepository_require_private - -/* girffi.h */ gi_type_info_extract_ffi_return_value gi_type_tag_get_ffi_type g_callable_info_free_closure @@ -167,13 +144,9 @@ g_function_info_prep_invoker g_function_invoker_destroy g_function_invoker_new_for_address g_type_info_get_ffi_type - -/*gisignalinfo.h */ g_signal_info_get_class_closure g_signal_info_get_flags g_signal_info_true_stops_emit - -/* gustructinfo.h */ g_struct_info_find_method g_struct_info_get_alignment g_struct_info_get_field @@ -183,8 +156,6 @@ g_struct_info_get_n_methods g_struct_info_get_size g_struct_info_is_foreign g_struct_info_is_gtype_struct - -/* gitypeinfo.h */ g_type_info_is_pointer g_type_info_is_zero_terminated g_type_info_get_array_fixed_size @@ -195,8 +166,6 @@ g_type_info_get_param_type g_type_info_get_tag g_type_tag_to_string g_info_type_to_string - -/* gitypelib.h */ g_typelib_check_sanity g_typelib_error_quark g_typelib_free @@ -206,8 +175,6 @@ g_typelib_new_from_mapped_file g_typelib_new_from_memory g_typelib_symbol g_typelib_validate - -/* giunioninfo.h */ g_union_info_find_method g_union_info_get_alignment g_union_info_get_discriminator @@ -219,8 +186,6 @@ g_union_info_get_n_fields g_union_info_get_n_methods g_union_info_get_size g_union_info_is_discriminated - -/* givfuncinfo.h */ g_vfunc_info_get_address g_vfunc_info_get_invoker g_vfunc_info_get_flags From f4e33baf3bdb2c94dbdb9ef3b918eed17efdddaf Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 30 Oct 2012 18:23:09 -0400 Subject: [PATCH 500/692] cmph: Remove leftover statement-without-effect Compiler warning introduced from MSVC patches. --- cmph/brz.c | 1 - 1 file changed, 1 deletion(-) diff --git a/cmph/brz.c b/cmph/brz.c index d1079c227..cd35c8d8e 100755 --- a/cmph/brz.c +++ b/cmph/brz.c @@ -672,7 +672,6 @@ static cmph_uint32 brz_bmz8_search(brz_data_t *brz, const char *key, cmph_uint32 n = (cmph_uint32)ceil(brz->c * m); h1 = hash(brz->h1[h0], key, keylen) % n; h2 = hash(brz->h2[h0], key, keylen) % n; - mphf_bucket; if (h1 == h2 && ++h2 >= n) h2 = 0; mphf_bucket = (cmph_uint8)(brz->g[h0][h1] + brz->g[h0][h2]); From 430826e82560e3f66a424990d0af3383a94e74ea Mon Sep 17 00:00:00 2001 From: Dieter Verfaillie Date: Thu, 15 Nov 2012 20:56:54 +0100 Subject: [PATCH 501/692] docs: don't mark non GTK-Doc as being a GTK-Doc comment block This patch silences another gtkdoc-mkdb warning. https://bugzilla.gnome.org/show_bug.cgi?id=688418 --- gthash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gthash.c b/gthash.c index b50ea6f0e..ecc3b1040 100644 --- a/gthash.c +++ b/gthash.c @@ -29,7 +29,7 @@ #define ALIGN_VALUE(this, boundary) \ (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) -/** +/* * String hashing in the typelib. We have a set of static (fixed) strings, * and given one, we need to find its index number. This problem is perfect * hashing: http://en.wikipedia.org/wiki/Perfect_hashing From 35091ec7df80b1dc6f60676c7ca0392797bc0c4d Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 17 Dec 2012 09:50:28 -0500 Subject: [PATCH 502/692] repo: Drop deprecated GStaticMutex usage In favor of GOnce, since we just want initialize-once semantics. --- girepository.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/girepository.c b/girepository.c index b5c30297a..ccdd36113 100644 --- a/girepository.c +++ b/girepository.c @@ -35,7 +35,6 @@ #include "config.h" -static GStaticMutex globals_lock = G_STATIC_MUTEX_INIT; static GIRepository *default_repository = NULL; static GSList *search_path = NULL; static GSList *override_search_path = NULL; @@ -134,12 +133,13 @@ g_irepository_class_init (GIRepositoryClass *class) static void init_globals (void) { - g_static_mutex_lock (&globals_lock); + static gsize initialized = 0; + + if (!g_once_init_enter (&initialized)) + return; if (default_repository == NULL) - { - default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL); - } + default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL); if (search_path == NULL) { @@ -184,7 +184,7 @@ init_globals (void) search_path = g_slist_reverse (search_path); } - g_static_mutex_unlock (&globals_lock); + g_once_init_leave (&initialized, 1); } void From f57dc1a133154ea93ed94c4c26fd51ae1b4ffe02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20Sch=C3=B6nfeld?= Date: Mon, 7 Jan 2013 17:35:47 +0100 Subject: [PATCH 503/692] build: Properly export g_interface_info_find_signal It was missing from girepository.symbols. --- girepository.symbols | 1 + 1 file changed, 1 insertion(+) diff --git a/girepository.symbols b/girepository.symbols index 11d2bb6d7..8cb6c8396 100644 --- a/girepository.symbols +++ b/girepository.symbols @@ -59,6 +59,7 @@ g_function_info_get_vfunc g_function_info_invoke g_invoke_error_quark g_interface_info_find_method +g_interface_info_find_signal g_interface_info_find_vfunc g_interface_info_get_constant g_interface_info_get_iface_struct From 259c10f7874b8cd65e78ac7f8420f073f75d967b Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Fri, 11 Jan 2013 08:42:27 +0100 Subject: [PATCH 504/692] girepository: gchar is a signed type gchar is signed, not unsigned. Add "guchar" alias as unsigned for completeness (but usually it appears as guint8). https://bugzilla.gnome.org/show_bug.cgi?id=691524 --- girparser.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index ce88a691b..1a83c2390 100644 --- a/girparser.c +++ b/girparser.c @@ -379,7 +379,8 @@ typedef struct { } IntegerAliasInfo; static IntegerAliasInfo integer_aliases[] = { - { "gchar", SIZEOF_CHAR, 0 }, + { "gchar", SIZEOF_CHAR, 1 }, + { "guchar", SIZEOF_CHAR, 0 }, { "gshort", SIZEOF_SHORT, 1 }, { "gushort", SIZEOF_SHORT, 0 }, { "gint", SIZEOF_INT, 1 }, From 37791c82671056a3a4f6f2a067c2daa9fe08b28e Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 31 Jan 2013 22:59:23 -0500 Subject: [PATCH 505/692] girparser: Move handling to passthrough https://bugzilla.gnome.org/show_bug.cgi?id=693040 --- girparser.c | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/girparser.c b/girparser.c index 1a83c2390..6015a0432 100644 --- a/girparser.c +++ b/girparser.c @@ -95,7 +95,6 @@ typedef enum STATE_ALIAS, /* 30 */ STATE_TYPE, STATE_ATTRIBUTE, - STATE_DOC, STATE_PASSTHROUGH } ParseState; @@ -2116,22 +2115,6 @@ end_type (ParseContext *ctx) } } -static gboolean -start_doc (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - ParseContext *ctx, - GError **error) -{ - if (strcmp (element_name, "doc") != 0) - return FALSE; - - state_switch (ctx, STATE_DOC); - - return TRUE; -} - static gboolean start_attribute (GMarkupParseContext *context, const gchar *element_name, @@ -2765,9 +2748,12 @@ start_element_handler (GMarkupParseContext *context, attribute_names, attribute_values, ctx, error)) goto out; - else if (start_doc (context, element_name, attribute_names, - attribute_values, ctx, error)) - goto out; + if (strcmp (element_name, "doc") == 0) + { + state_switch (ctx, STATE_PASSTHROUGH); + ctx->unknown_depth = 1; + goto out; + } break; case 'e': @@ -3413,13 +3399,6 @@ end_element_handler (GMarkupParseContext *context, } break; - case STATE_DOC: - if (strcmp ("doc", element_name) == 0) - { - state_switch (ctx, ctx->prev_state); - } - break; - case STATE_PASSTHROUGH: ctx->unknown_depth -= 1; g_assert (ctx->unknown_depth >= 0); From 06dfbc7dcb0ec3e68ad6760c5e61c6a9e808cc19 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 31 Jan 2013 23:02:02 -0500 Subject: [PATCH 506/692] girparser: Clean up passthrough handling Instead of remembering to have to set unknown_depth, smarten up state_switch to do it for us. https://bugzilla.gnome.org/show_bug.cgi?id=693040 --- girparser.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/girparser.c b/girparser.c index 6015a0432..d1bc81f5d 100644 --- a/girparser.c +++ b/girparser.c @@ -341,6 +341,9 @@ state_switch (ParseContext *ctx, ParseState newstate) g_assert (ctx->state != newstate); ctx->prev_state = ctx->state; ctx->state = newstate; + + if (ctx->state == STATE_PASSTHROUGH) + ctx->unknown_depth = 1; } static GIrNode * @@ -724,10 +727,7 @@ introspectable_prelude (GMarkupParseContext *context, if (introspectable) state_switch (ctx, new_state); else - { - state_switch (ctx, STATE_PASSTHROUGH); - ctx->unknown_depth = 1; - } + state_switch (ctx, STATE_PASSTHROUGH); return introspectable; } @@ -2751,7 +2751,6 @@ start_element_handler (GMarkupParseContext *context, if (strcmp (element_name, "doc") == 0) { state_switch (ctx, STATE_PASSTHROUGH); - ctx->unknown_depth = 1; goto out; } break; @@ -3014,7 +3013,6 @@ start_element_handler (GMarkupParseContext *context, ctx->file_path, line_number, char_number, element_name, ctx->state); state_switch (ctx, STATE_PASSTHROUGH); - ctx->unknown_depth = 1; } out: From ee4ee72ac35feae16ae802bcdf57a87800c0bcbd Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Thu, 31 Jan 2013 09:36:07 -0500 Subject: [PATCH 507/692] girparser: Serialize and read back the instance_parameter g-ir-doc-tool wants to use the instance parameter to read docs and the parameter name, so it needs to be shuttled through the GIR. https://bugzilla.gnome.org/show_bug.cgi?id=693040 --- girparser.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/girparser.c b/girparser.c index d1bc81f5d..5aaa6dd0d 100644 --- a/girparser.c +++ b/girparser.c @@ -2831,6 +2831,11 @@ start_element_handler (GMarkupParseContext *context, attribute_names, attribute_values, ctx, error)) goto out; + else if (strcmp (element_name, "instance-parameter") == 0) + { + state_switch (ctx, STATE_PASSTHROUGH); + goto out; + } else if (strcmp (element_name, "c:include") == 0) { state_switch (ctx, STATE_C_INCLUDE); From a7a47f4375313aed8fd93704de0a8a8f9cf1ebb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20Sch=C3=B6nfeld?= Date: Thu, 14 Feb 2013 20:51:57 +0100 Subject: [PATCH 508/692] girepository: Document g_enum_info_get_error_domain https://bugzilla.gnome.org/show_bug.cgi?id=693838 --- gienuminfo.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/gienuminfo.c b/gienuminfo.c index a9b7c1df6..400a56d65 100644 --- a/gienuminfo.c +++ b/gienuminfo.c @@ -67,6 +67,18 @@ g_enum_info_get_n_values (GIEnumInfo *info) return blob->n_values; } +/** + * g_enum_info_get_error_domain: + * @info: a #GIEnumInfo + * + * Obtain the string form of the quark for the error domain associated with + * this enum, if any. + * + * Returns: (transfer none): the string form of the error domain associated + * with this enum, or %NULL. + * + * Since: 1.29.17 + */ const gchar * g_enum_info_get_error_domain (GIEnumInfo *info) { From 50638cf403959b8352e9d60f27a7b8fed6f097e8 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Fri, 22 Feb 2013 01:50:48 +0100 Subject: [PATCH 509/692] GIRepository: add API for extending library paths Previously we would require applications that shipped with private typelibs to add the private path to LD_LIBRARY_PATH, or to have a launcher binary with the right RPATH. Now they can just call GIRepository.prepend_library_path() before they access the module. https://bugzilla.gnome.org/show_bug.cgi?id=694485 --- girepository.h | 1 + girepository.symbols | 1 + gitypelib.c | 91 ++++++++++++++++++++++++++++++++------------ 3 files changed, 69 insertions(+), 24 deletions(-) diff --git a/girepository.h b/girepository.h index eb990a278..2b2b17138 100644 --- a/girepository.h +++ b/girepository.h @@ -90,6 +90,7 @@ typedef enum GType g_irepository_get_type (void) G_GNUC_CONST; GIRepository *g_irepository_get_default (void); void g_irepository_prepend_search_path (const char *directory); +void g_irepository_prepend_library_path (const char *directory); GSList * g_irepository_get_search_path (void); const char * g_irepository_load_typelib (GIRepository *repository, GITypelib *typelib, diff --git a/girepository.symbols b/girepository.symbols index 8cb6c8396..5f01adffd 100644 --- a/girepository.symbols +++ b/girepository.symbols @@ -134,6 +134,7 @@ g_irepository_get_typelib_path g_irepository_get_version g_irepository_is_registered g_irepository_load_typelib +g_irepository_prepend_library_path g_irepository_prepend_search_path g_irepository_require g_irepository_require_private diff --git a/gitypelib.c b/gitypelib.c index 2af17e969..76a55de81 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -2062,6 +2062,72 @@ g_typelib_error_quark (void) return quark; } +static GSList *library_paths; + +/** + * g_irepository_prepend_library_path: + * @directory: (type filename): a single directory to scan for shared libraries + * + * Prepends @directory to the search path that is used to + * search shared libraries referenced by imported namespaces. + * Multiple calls to this function all contribute to the final + * list of paths. + * The list of paths is unique and shared for all #GIRepository + * instances across the process, but it doesn't affect namespaces + * imported before the call. + * + * If the library is not found in the directories configured + * in this way, loading will fall back to the system library + * path (ie. LD_LIBRARY_PATH and DT_RPATH in ELF systems). + * See the documentation of your dynamic linker for full details. + * + * Since: 1.35.8 + */ +void +g_irepository_prepend_library_path (const char *directory) +{ + library_paths = g_slist_prepend (library_paths, + g_strdup (directory)); +} + +/* Note on the GModule flags used by this function: + + * Glade's autoconnect feature and OpenGL's extension mechanism + * as used by Clutter rely on g_module_open(NULL) to work as a means of + * accessing the app's symbols. This keeps us from using + * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well; + * in general libraries are not expecting multiple copies of + * themselves and are not expecting to be unloaded. So we just + * load modules globally for now. + */ +static GModule * +load_one_shared_library (const char *shlib) +{ + GSList *p; + GModule *m; + + if (!g_path_is_absolute (shlib)) + { + /* First try in configured library paths */ + for (p = library_paths; p; p = p->next) + { + char *path = g_build_filename (p->data, shlib, NULL); + + m = g_module_open (path, G_MODULE_BIND_LAZY); + + g_free (path); + if (m != NULL) + return m; + } + } + + /* Then try loading from standard paths */ + /* Do not attempt to fix up shlib to replace .la with .so: + it's done by GModule anyway. + */ + return g_module_open (shlib, G_MODULE_BIND_LAZY); +} + static void _g_typelib_do_dlopen (GITypelib *typelib) { @@ -2091,30 +2157,7 @@ _g_typelib_do_dlopen (GITypelib *typelib) { GModule *module; - /* Glade's autoconnect feature and OpenGL's extension mechanism - * as used by Clutter rely on g_module_open(NULL) to work as a means of - * accessing the app's symbols. This keeps us from using - * G_MODULE_BIND_LOCAL. BIND_LOCAL may have other issues as well; - * in general libraries are not expecting multiple copies of - * themselves and are not expecting to be unloaded. So we just - * load modules globally for now. - */ - - module = g_module_open (shlibs[i], G_MODULE_BIND_LAZY); - - if (module == NULL) - { - GString *shlib_full = g_string_new (shlibs[i]); - - module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); - if (module == NULL) - { - g_string_overwrite (shlib_full, strlen (shlib_full->str)-2, SHLIB_SUFFIX); - module = g_module_open (shlib_full->str, G_MODULE_BIND_LAZY); - } - - g_string_free (shlib_full, TRUE); - } + module = load_one_shared_library (shlibs[i]); if (module == NULL) { From 4779b03a2176c5a82f4944b3619edd9a8103246e Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 19 Nov 2012 21:42:44 -0500 Subject: [PATCH 510/692] girepository: Use g_atomic for refcounting They could be freed in separate threads (e.g. language binding GC thread). But no particular reason to change other than noticing it during code inspection for a different bug. https://bugzilla.gnome.org/show_bug.cgi?id=688694 --- gibaseinfo.c | 25 ++++++++++++------------- girepository-private.h | 9 +++++++-- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/gibaseinfo.c b/gibaseinfo.c index ff9c9395a..37893e6c2 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -226,7 +226,7 @@ g_base_info_ref (GIBaseInfo *info) GIRealInfo *rinfo = (GIRealInfo*)info; g_assert (rinfo->ref_count != INVALID_REFCOUNT); - ((GIRealInfo*)info)->ref_count++; + g_atomic_int_inc (&rinfo->ref_count); return info; } @@ -244,21 +244,20 @@ g_base_info_unref (GIBaseInfo *info) GIRealInfo *rinfo = (GIRealInfo*)info; g_assert (rinfo->ref_count > 0 && rinfo->ref_count != INVALID_REFCOUNT); - rinfo->ref_count--; - if (!rinfo->ref_count) - { - if (rinfo->container && ((GIRealInfo *) rinfo->container)->ref_count != INVALID_REFCOUNT) - g_base_info_unref (rinfo->container); + if (!g_atomic_int_dec_and_test (&rinfo->ref_count)) + return; - if (rinfo->repository) - g_object_unref (rinfo->repository); + if (rinfo->container && ((GIRealInfo *) rinfo->container)->ref_count != INVALID_REFCOUNT) + g_base_info_unref (rinfo->container); - if (rinfo->type == GI_INFO_TYPE_UNRESOLVED) - g_slice_free (GIUnresolvedInfo, (GIUnresolvedInfo *) rinfo); - else - g_slice_free (GIRealInfo, rinfo); - } + if (rinfo->repository) + g_object_unref (rinfo->repository); + + if (rinfo->type == GI_INFO_TYPE_UNRESOLVED) + g_slice_free (GIUnresolvedInfo, (GIUnresolvedInfo *) rinfo); + else + g_slice_free (GIRealInfo, rinfo); } /** diff --git a/girepository-private.h b/girepository-private.h index 275776d8a..bbd34e3ec 100644 --- a/girepository-private.h +++ b/girepository-private.h @@ -33,6 +33,11 @@ typedef struct _GIRealInfo GIRealInfo; +/* We changed a gint32 -> gint in the structure below, which should be + * valid everywhere we care about. + */ +G_STATIC_ASSERT (sizeof (int) == sizeof (gint32)); + /* * We just use one structure for all of the info object * types; in general, we should be reading data directly @@ -43,7 +48,7 @@ struct _GIRealInfo { /* Keep this part in sync with GIUnresolvedInfo below */ gint32 type; - gint32 ref_count; + volatile gint ref_count; GIRepository *repository; GIBaseInfo *container; @@ -62,7 +67,7 @@ struct _GIUnresolvedInfo { /* Keep this part in sync with GIBaseInfo above */ gint32 type; - gint32 ref_count; + volatile gint ref_count; GIRepository *repository; GIBaseInfo *container; From 33afebb2d7d49f7b0c195aecc617e1c927546b4a Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Tue, 19 Mar 2013 11:04:42 -0600 Subject: [PATCH 511/692] Optimize g_irepository_find_by_gtype When g_irepository_find_by_gtype() doesn't succeed on a simple prefix match (the current 'fastpass' mechanism), it ends up taking a considerable amount of CPU time, traversing the contents of all typelibs. I imagine that the reasons to have the exhaustive search fallback are not as strong as they used to be. For example, the case mentioned (Clutter including Cogl) no longer seems to be true. Also, typelibs (as generated by g-ir-scanner) now provide comma-separated C prefix info for cases when the typelib includes introspection info for multiple prefixes. For example, the Sugar typelib has a c_prefix string of Sugar,EggSM,Gsm,Acme. So I imagine there are not many remaining justified cases where the exhaustive search is needed. With that in mind, I found two ways to optimize this function: 1. Support comma-separated C prefixes 2. Don't bother with an exhaustive search if we did find a typelib claiming support for the prefix. For example, if we're looking for GdkDeviceManagerXI2 (currently non-introspectable) and we already found typelib files providing the 'Gdk' prefix that didn't offer this, lets not bother with the exhaustive search, we aren't going to find anything. --- girepository.c | 107 +++++++++++++++++++++++++++++-------------- gitypelib-internal.h | 8 ++-- gitypelib.c | 84 ++++++++++++++++----------------- 3 files changed, 119 insertions(+), 80 deletions(-) diff --git a/girepository.c b/girepository.c index ccdd36113..0922fb096 100644 --- a/girepository.c +++ b/girepository.c @@ -593,28 +593,39 @@ g_irepository_get_info (GIRepository *repository, } typedef struct { - GIRepository *repository; - GType type; - - gboolean fastpass; + const gchar *gtype_name; GITypelib *result_typelib; - DirEntry *result; + gboolean found_prefix; } FindByGTypeData; -static void -find_by_gtype_foreach (gpointer key, - gpointer value, - gpointer datap) +static DirEntry * +find_by_gtype (GHashTable *table, FindByGTypeData *data, gboolean check_prefix) { - GITypelib *typelib = (GITypelib*)value; - FindByGTypeData *data = datap; + GHashTableIter iter; + gpointer key, value; + DirEntry *ret; - if (data->result != NULL) - return; + g_hash_table_iter_init (&iter, table); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + GITypelib *typelib = (GITypelib*)value; + if (check_prefix) + { + if (!g_typelib_matches_gtype_name_prefix (typelib, data->gtype_name)) + continue; - data->result = g_typelib_get_dir_entry_by_gtype (typelib, data->fastpass, data->type); - if (data->result) - data->result_typelib = typelib; + data->found_prefix = TRUE; + } + + ret = g_typelib_get_dir_entry_by_gtype_name (typelib, data->gtype_name); + if (ret) + { + data->result_typelib = typelib; + return ret; + } + } + + return NULL; } /** @@ -637,6 +648,7 @@ g_irepository_find_by_gtype (GIRepository *repository, { FindByGTypeData data; GIBaseInfo *cached; + DirEntry *entry; repository = get_repository (repository); @@ -646,30 +658,55 @@ g_irepository_find_by_gtype (GIRepository *repository, if (cached != NULL) return g_base_info_ref (cached); - data.repository = repository; - data.fastpass = TRUE; - data.type = gtype; + data.gtype_name = g_type_name (gtype); data.result_typelib = NULL; - data.result = NULL; + data.found_prefix = FALSE; - g_hash_table_foreach (repository->priv->typelibs, find_by_gtype_foreach, &data); - if (data.result == NULL) - g_hash_table_foreach (repository->priv->lazy_typelibs, find_by_gtype_foreach, &data); + /* There is a corner case regarding GdkRectangle. GdkRectangle is a + * boxed type, but it is just an alias to boxed struct + * CairoRectangleInt. Scanner automatically converts all references + * to GdkRectangle to CairoRectangleInt, so GdkRectangle does not + * appear in the typelibs at all, although user code might query it. + * So if we get such query, we also change it to lookup of + * CairoRectangleInt. + * https://bugzilla.gnome.org/show_bug.cgi?id=655423 + */ + if (G_UNLIKELY (!strcmp (data.gtype_name, "GdkRectangle"))) + data.gtype_name = "CairoRectangleInt"; - /* We do two passes; see comment in find_interface */ - if (data.result == NULL) + /* Inside each typelib, we include the "C prefix" which acts as + * a namespace mechanism. For GtkTreeView, the C prefix is Gtk. + * Given the assumption that GTypes for a library also use the + * C prefix, we know we can skip examining a typelib if our + * target type does not have this typelib's C prefix. Use this + * assumption as our first attempt at locating the DirEntry. + */ + entry = find_by_gtype (repository->priv->typelibs, &data, TRUE); + if (entry == NULL) + entry = find_by_gtype (repository->priv->lazy_typelibs, &data, TRUE); + + /* If we have no result, but we did find a typelib claiming to + * offer bindings for such a prefix, bail out now on the assumption + * that a more exhaustive search would not produce any results. + */ + if (entry == NULL && data.found_prefix) + return NULL; + + /* Not ever class library necessarily specifies a correct c_prefix, + * so take a second pass. This time we will try a global lookup, + * ignoring prefixes. + * See http://bugzilla.gnome.org/show_bug.cgi?id=564016 + */ + if (entry == NULL) + entry = find_by_gtype (repository->priv->typelibs, &data, FALSE); + if (entry == NULL) + entry = find_by_gtype (repository->priv->lazy_typelibs, &data, FALSE); + + if (entry != NULL) { - data.fastpass = FALSE; - g_hash_table_foreach (repository->priv->typelibs, find_by_gtype_foreach, &data); - } - if (data.result == NULL) - g_hash_table_foreach (repository->priv->lazy_typelibs, find_by_gtype_foreach, &data); - - if (data.result != NULL) - { - cached = _g_info_new_full (data.result->blob_type, + cached = _g_info_new_full (entry->blob_type, repository, - NULL, data.result_typelib, data.result->offset); + NULL, data.result_typelib, entry->offset); g_hash_table_insert (repository->priv->info_by_gtype, (gpointer) gtype, diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 04662b4a0..ac71008d8 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -1126,13 +1126,15 @@ DirEntry *g_typelib_get_dir_entry (GITypelib *typelib, DirEntry *g_typelib_get_dir_entry_by_name (GITypelib *typelib, const char *name); -DirEntry *g_typelib_get_dir_entry_by_gtype (GITypelib *typelib, - gboolean fastpass, - GType gtype); +DirEntry *g_typelib_get_dir_entry_by_gtype_name (GITypelib *typelib, + const gchar *gtype_name); DirEntry *g_typelib_get_dir_entry_by_error_domain (GITypelib *typelib, GQuark error_domain); +gboolean g_typelib_matches_gtype_name_prefix (GITypelib *typelib, + const gchar *gtype_name); + void g_typelib_check_sanity (void); #define g_typelib_get_string(typelib,offset) ((const gchar*)&(typelib->data)[(offset)]) diff --git a/gitypelib.c b/gitypelib.c index 76a55de81..2512e5245 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -198,55 +198,17 @@ g_typelib_get_dir_entry_by_name (GITypelib *typelib, } DirEntry * -g_typelib_get_dir_entry_by_gtype (GITypelib *typelib, - gboolean fastpass, - GType gtype) +g_typelib_get_dir_entry_by_gtype_name (GITypelib *typelib, + const gchar *gtype_name) { Header *header = (Header *)typelib->data; - guint n_entries = header->n_local_entries; - const char *gtype_name = g_type_name (gtype); - DirEntry *entry; guint i; - const char *c_prefix; - /* There is a corner case regarding GdkRectangle. GdkRectangle is a - boxed type, but it is just an alias to boxed struct - CairoRectangleInt. Scanner automatically converts all references - to GdkRectangle to CairoRectangleInt, so GdkRectangle does not - appear in the typelibs at all, although user code might query it. - So if we get such query, we also change it to lookup of - CairoRectangleInt. - https://bugzilla.gnome.org/show_bug.cgi?id=655423 */ - if (!fastpass && !strcmp (gtype_name, "GdkRectangle")) - gtype_name = "CairoRectangleInt"; - - /* Inside each typelib, we include the "C prefix" which acts as - * a namespace mechanism. For GtkTreeView, the C prefix is Gtk. - * Given the assumption that GTypes for a library also use the - * C prefix, we know we can skip examining a typelib if our - * target type does not have this typelib's C prefix. - * - * However, not every class library necessarily conforms to this, - * e.g. Clutter has Cogl inside it. So, we split this into two - * passes. First we try a lookup, skipping things which don't - * have the prefix. If that fails then we try a global lookup, - * ignoring the prefix. - * - * See http://bugzilla.gnome.org/show_bug.cgi?id=564016 - */ - c_prefix = g_typelib_get_string (typelib, header->c_prefix); - if (fastpass && c_prefix != NULL) - { - if (g_ascii_strncasecmp (c_prefix, gtype_name, strlen (c_prefix)) != 0) - return NULL; - } - - for (i = 1; i <= n_entries; i++) + for (i = 1; i <= header->n_local_entries; i++) { RegisteredTypeBlob *blob; const char *type; - - entry = g_typelib_get_dir_entry (typelib, i); + DirEntry *entry = g_typelib_get_dir_entry (typelib, i); if (!BLOB_IS_REGISTERED_TYPE (entry)) continue; @@ -261,6 +223,44 @@ g_typelib_get_dir_entry_by_gtype (GITypelib *typelib, return NULL; } +gboolean +g_typelib_matches_gtype_name_prefix (GITypelib *typelib, + const gchar *gtype_name) +{ + Header *header = (Header *)typelib->data; + const char *c_prefix; + gchar **prefixes; + gchar **prefix; + gboolean ret = FALSE; + + c_prefix = g_typelib_get_string (typelib, header->c_prefix); + if (c_prefix == NULL) + return FALSE; + + /* c_prefix is a comma separated string of supported prefixes + * in the typelib. + * We match the specified gtype_name if the gtype_name starts + * with the prefix, and is followed by a capital letter. + * For example, a typelib offering the 'Gdk' prefix does match + * GdkX11Cursor, however a typelib offering the 'G' prefix does not. + */ + prefixes = g_strsplit (c_prefix, ",", 0); + for (prefix = prefixes; *prefix; prefix++) + { + size_t len = strlen (*prefix); + if (strncmp (*prefix, gtype_name, len)) + continue; + + if (strlen (gtype_name) > len && g_ascii_isupper (gtype_name[len])) + { + ret = TRUE; + break; + } + } + g_strfreev(prefixes); + return ret; +} + DirEntry * g_typelib_get_dir_entry_by_error_domain (GITypelib *typelib, GQuark error_domain) From f84db0d30de6786a9061a320f3057a35558798e3 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 7 Apr 2013 13:18:29 -0400 Subject: [PATCH 512/692] typelib: Only malloc once during string iteration Just more efficient. --- gitypelib.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 8 deletions(-) diff --git a/gitypelib.c b/gitypelib.c index 2512e5245..10bb98e09 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -223,20 +223,68 @@ g_typelib_get_dir_entry_by_gtype_name (GITypelib *typelib, return NULL; } +typedef struct { + const char *s; + const char *separator; + GString buf; +} StrSplitIter; + +static void +strsplit_iter_init (StrSplitIter *iter, + const char *s, + const char *separator) +{ + iter->s = s; + iter->separator = separator; + iter->buf.str = NULL; + iter->buf.len = 0; + iter->buf.allocated_len = 0; +} + +static gboolean +strsplit_iter_next (StrSplitIter *iter, + char **out_val) +{ + const char *s = iter->s; + const char *next; + gsize len; + + if (!s) + return FALSE; + next = strstr (s, iter->separator); + iter->s = next; + if (next) + len = next - s; + else + len = strlen (s); + g_string_overwrite_len (&iter->buf, 0, s, (gssize)len); + *out_val = iter->buf.str; + return TRUE; +} + +static void +strsplit_iter_clear (StrSplitIter *iter) +{ + g_free (iter->buf.str); +} + gboolean g_typelib_matches_gtype_name_prefix (GITypelib *typelib, const gchar *gtype_name) { Header *header = (Header *)typelib->data; const char *c_prefix; - gchar **prefixes; - gchar **prefix; + gchar *prefix; gboolean ret = FALSE; + StrSplitIter split_iter; + gsize gtype_name_len; c_prefix = g_typelib_get_string (typelib, header->c_prefix); if (c_prefix == NULL) return FALSE; + gtype_name_len = strlen (gtype_name); + /* c_prefix is a comma separated string of supported prefixes * in the typelib. * We match the specified gtype_name if the gtype_name starts @@ -244,20 +292,24 @@ g_typelib_matches_gtype_name_prefix (GITypelib *typelib, * For example, a typelib offering the 'Gdk' prefix does match * GdkX11Cursor, however a typelib offering the 'G' prefix does not. */ - prefixes = g_strsplit (c_prefix, ",", 0); - for (prefix = prefixes; *prefix; prefix++) + strsplit_iter_init (&split_iter, c_prefix, ","); + while (strsplit_iter_next (&split_iter, &prefix)) { - size_t len = strlen (*prefix); - if (strncmp (*prefix, gtype_name, len)) + size_t len = strlen (prefix); + + if (gtype_name_len < len) continue; - if (strlen (gtype_name) > len && g_ascii_isupper (gtype_name[len])) + if (strncmp (prefix, gtype_name, len) != 0) + continue; + + if (g_ascii_isupper (gtype_name[len])) { ret = TRUE; break; } } - g_strfreev(prefixes); + strsplit_iter_clear (&split_iter); return ret; } From d0462e6a3c9f6fd1945ab536ced5bbfed63eb56f Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 8 Apr 2013 14:44:32 -0400 Subject: [PATCH 513/692] typelib: Fix logic error in previous commit --- gitypelib.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/gitypelib.c b/gitypelib.c index 10bb98e09..f7d07e3f8 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -252,11 +252,16 @@ strsplit_iter_next (StrSplitIter *iter, if (!s) return FALSE; next = strstr (s, iter->separator); - iter->s = next; if (next) - len = next - s; + { + iter->s = next + 1; + len = next - s; + } else - len = strlen (s); + { + iter->s = NULL; + len = strlen (s); + } g_string_overwrite_len (&iter->buf, 0, s, (gssize)len); *out_val = iter->buf.str; return TRUE; From 5bea9385b08d867d8bca9f9d05068c36afb985a0 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 8 Apr 2013 15:32:15 -0400 Subject: [PATCH 514/692] gitypelib: And another fix for empty strings --- gitypelib.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/gitypelib.c b/gitypelib.c index f7d07e3f8..a643cde19 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -226,6 +226,7 @@ g_typelib_get_dir_entry_by_gtype_name (GITypelib *typelib, typedef struct { const char *s; const char *separator; + gsize sep_len; GString buf; } StrSplitIter; @@ -236,6 +237,7 @@ strsplit_iter_init (StrSplitIter *iter, { iter->s = s; iter->separator = separator; + iter->sep_len = strlen (separator); iter->buf.str = NULL; iter->buf.len = 0; iter->buf.allocated_len = 0; @@ -254,7 +256,7 @@ strsplit_iter_next (StrSplitIter *iter, next = strstr (s, iter->separator); if (next) { - iter->s = next + 1; + iter->s = next + iter->sep_len; len = next - s; } else @@ -262,8 +264,15 @@ strsplit_iter_next (StrSplitIter *iter, iter->s = NULL; len = strlen (s); } - g_string_overwrite_len (&iter->buf, 0, s, (gssize)len); - *out_val = iter->buf.str; + if (len == 0) + { + *out_val = ""; + } + else + { + g_string_overwrite_len (&iter->buf, 0, s, (gssize)len); + *out_val = iter->buf.str; + } return TRUE; } From 2e4e98c97860475392f995f1e4a490b72244ba37 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 12 Apr 2013 13:31:53 -0400 Subject: [PATCH 515/692] girparser: Also honor legacy c:prefix vala generates this, and we need to honor it now that we're using the c:prefix as an optimization when searching for gtypes. https://bugzilla.gnome.org/697759 --- girparser.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/girparser.c b/girparser.c index 5aaa6dd0d..f96cfb1e0 100644 --- a/girparser.c +++ b/girparser.c @@ -2872,6 +2872,9 @@ start_element_handler (GMarkupParseContext *context, version = find_attribute ("version", attribute_names, attribute_values); shared_library = find_attribute ("shared-library", attribute_names, attribute_values); cprefix = find_attribute ("c:identifier-prefixes", attribute_names, attribute_values); + /* Backwards compatibility; vala currently still generates this */ + if (cprefix == NULL) + cprefix = find_attribute ("c:prefix", attribute_names, attribute_values); if (name == NULL) MISSING_ATTRIBUTE (context, error, element_name, "name"); From 273178600c667f96d02a9479b8466068741c0b2c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 12 Apr 2013 13:39:21 -0400 Subject: [PATCH 516/692] typelib: Also ignore typelibs with empty c:prefix As seen in xlib.gir at least; this is something we should probably ban though. https://bugzilla.gnome.org/697759 --- gitypelib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitypelib.c b/gitypelib.c index a643cde19..d88924a6d 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -294,7 +294,7 @@ g_typelib_matches_gtype_name_prefix (GITypelib *typelib, gsize gtype_name_len; c_prefix = g_typelib_get_string (typelib, header->c_prefix); - if (c_prefix == NULL) + if (c_prefix == NULL || strlen (c_prefix) == 0) return FALSE; gtype_name_len = strlen (gtype_name); From 55efc6e90e1f18ae335ccf67b07964efbc6012d6 Mon Sep 17 00:00:00 2001 From: Christian Persch Date: Sun, 21 Apr 2013 18:56:19 +0200 Subject: [PATCH 517/692] Add printf attribute This fixes a compiler warning when using -Wmissing-format-attribute. https://bugzilla.gnome.org/show_bug.cgi?id=698521 --- gdump.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gdump.c b/gdump.c index 7e02d391f..88942f3aa 100644 --- a/gdump.c +++ b/gdump.c @@ -37,6 +37,9 @@ #include +static void +escaped_printf (GOutputStream *out, const char *fmt, ...) G_GNUC_PRINTF (2, 3); + static void escaped_printf (GOutputStream *out, const char *fmt, ...) { From 236d3375c6ea6cd61dc08ec040db05d211678aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Wed, 5 Jun 2013 13:28:30 +0200 Subject: [PATCH 518/692] g_irepository_dump: Update doc to match code The input file no longer only consists of names of get_type-functions, instead begins with either "get-type:" or "error-quark:". https://bugzilla.gnome.org/show_bug.cgi?id=701639 --- gdump.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gdump.c b/gdump.c index 88942f3aa..a72841fe4 100644 --- a/gdump.c +++ b/gdump.c @@ -425,8 +425,10 @@ dump_error_quark (GQuark quark, const char *symbol, GOutputStream *out) * * Argument specified is a comma-separated pair of filenames; i.e. of * the form "input.txt,output.xml". The input file should be a - * UTF-8 Unix-line-ending text file, with each line containing the name - * of a GType _get_type function. + * UTF-8 Unix-line-ending text file, with each line containing either + * "get-type:" followed by the name of a GType _get_type function, or + * "error-quark:" followed by the name of an error quark function. No + * extra whitespace is allowed. * * The output file should already exist, but be empty. This function will * overwrite its contents. From 67ee43b667cb338c9608d2b4bbf1793c09b55fbc Mon Sep 17 00:00:00 2001 From: Simon Feltman Date: Sat, 5 Oct 2013 01:40:20 -0700 Subject: [PATCH 519/692] Use case insensitive compare for signal "when" attribute Update parser to use g_ascii_strcasecmp instead of strcmp. This fixes incorrect flags being set when the incomming gir is using lowercase values for the "when" attribute. https://bugzilla.gnome.org/show_bug.cgi?id=709462 --- girparser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/girparser.c b/girparser.c index f96cfb1e0..6fbf2a6b2 100644 --- a/girparser.c +++ b/girparser.c @@ -2301,9 +2301,9 @@ start_glib_signal (GMarkupParseContext *context, signal->run_first = FALSE; signal->run_last = FALSE; signal->run_cleanup = FALSE; - if (when == NULL || strcmp (when, "LAST") == 0) + if (when == NULL || g_ascii_strcasecmp (when, "LAST") == 0) signal->run_last = TRUE; - else if (strcmp (when, "FIRST") == 0) + else if (g_ascii_strcasecmp (when, "FIRST") == 0) signal->run_first = TRUE; else signal->run_cleanup = TRUE; From c9b088c24f30020ee814adadbbd86f8200079935 Mon Sep 17 00:00:00 2001 From: Dieter Verfaillie Date: Wed, 21 Aug 2013 12:19:40 +0200 Subject: [PATCH 520/692] giscanner: store code before and after comment block so we can later use them to re-write source files containing broken GTK-Doc comment blocks where /** is preceded by and/or */ is followed by code... --- gitypes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitypes.h b/gitypes.h index a90ed4c85..660a98f95 100644 --- a/gitypes.h +++ b/gitypes.h @@ -225,7 +225,7 @@ typedef enum GI_INFO_TYPE_OBJECT, GI_INFO_TYPE_INTERFACE, GI_INFO_TYPE_CONSTANT, - GI_INFO_TYPE_INVALID_0, /* 10 */ /** DELETED - used to be ERROR_DOMAIN **/ + GI_INFO_TYPE_INVALID_0, /* 10 */ /* DELETED - used to be ERROR_DOMAIN */ GI_INFO_TYPE_UNION, GI_INFO_TYPE_VALUE, GI_INFO_TYPE_SIGNAL, From c87579bbb67e3b9f091877f1f3b8150e7505cec9 Mon Sep 17 00:00:00 2001 From: Dieter Verfaillie Date: Tue, 21 May 2013 10:47:11 +0200 Subject: [PATCH 521/692] giscanner: fix description field storage in .gir files GTK-Doc description fields for tags can contain multiple lines and even multiple paragraphs. Whitespace cannot be preserved in XML attributes, so we move the "deprecated" description text into a "" element right next to where we already have the "" element. Keep the "deprecated" attribute around for backwards compatibility though, but set its value to "1" (analogous to the "writable", "contruct", etc attributes) if the annotated symbol is marked as deprecated. While at it, add and which was not yet available in the .gir files... This takes care of the "Since:", "Stability:" and "Deprecated:" GTK-Doc tags. Nothing needs to be done for the "Returns:" tag as as we already write a "" child element on "". --- girparser.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index 6fbf2a6b2..82005fc0f 100644 --- a/girparser.c +++ b/girparser.c @@ -2748,7 +2748,8 @@ start_element_handler (GMarkupParseContext *context, attribute_names, attribute_values, ctx, error)) goto out; - if (strcmp (element_name, "doc") == 0) + if (strcmp ("doc", element_name) == 0 || strcmp ("doc-deprecated", element_name) == 0 || + strcmp ("doc-stability", element_name) == 0 || strcmp ("doc-version", element_name) == 0) { state_switch (ctx, STATE_PASSTHROUGH); goto out; From a50bfe5ec3978290005b3fb6aa0ec3b8caf1834f Mon Sep 17 00:00:00 2001 From: Dieter Verfaillie Date: Fri, 20 Sep 2013 17:51:29 +0200 Subject: [PATCH 522/692] girepository: remove glib-compat We depend on glib-2.0 >= 2.36.0, so no need to keep a 2.22.X compatibility symbol around... --- girepository.c | 1 - gitypelib.c | 1 - glib-compat.h | 25 ------------------------- 3 files changed, 27 deletions(-) delete mode 100644 glib-compat.h diff --git a/girepository.c b/girepository.c index 0922fb096..93c237282 100644 --- a/girepository.c +++ b/girepository.c @@ -31,7 +31,6 @@ #include "girepository.h" #include "gitypelib-internal.h" #include "girepository-private.h" -#include "glib-compat.h" #include "config.h" diff --git a/gitypelib.c b/gitypelib.c index d88924a6d..1436caf1e 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -27,7 +27,6 @@ #include "config.h" #include "gitypelib-internal.h" -#include "glib-compat.h" typedef struct { GITypelib *typelib; diff --git a/glib-compat.h b/glib-compat.h deleted file mode 100644 index 2518092ca..000000000 --- a/glib-compat.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * GObject introspection: Compatibility definitions - * - * Copyright (C) 2009 Javier Jardón - * - * 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. - */ - - -#if !GLIB_CHECK_VERSION(2,22,0) -#define g_mapped_file_unref(x) g_mapped_file_free(x) -#endif From bb7f8d57c284a30472419b6b68000f0742d680d9 Mon Sep 17 00:00:00 2001 From: Dieter Verfaillie Date: Thu, 10 Oct 2013 22:21:18 +0200 Subject: [PATCH 523/692] docs: fix up reference docs a bit - require GTK-Doc 1.19 - remove sgml mode - automatically generate gi.types (needs GTK-Doc 1.19) - fix https://bugzilla.gnome.org/show_bug.cgi?id=700025 [WIP] - rearange sections a bit [WIP] - add gi-building, gi-programming sections [WIP] - mark missing docs with TODO, which is only marginaly better than nothing but at least can be grepped :) https://bugzilla.gnome.org/show_bug.cgi?id=571648 --- docs.c | 33 ++ giarginfo.c | 11 +- giarginfo.h | 6 + gibaseinfo.c | 16 +- gibaseinfo.h | 5 + gicallableinfo.c | 35 +- gicallableinfo.h | 6 + giconstantinfo.c | 4 +- giconstantinfo.h | 6 + gienuminfo.c | 25 +- gienuminfo.h | 12 + gifieldinfo.c | 10 +- gifieldinfo.h | 7 + gifunctioninfo.c | 11 +- gifunctioninfo.h | 11 + giinterfaceinfo.c | 7 +- giinterfaceinfo.h | 6 + ginvoke.c | 34 +- giobjectinfo.c | 6 +- giobjectinfo.h | 8 +- gipropertyinfo.c | 6 +- gipropertyinfo.h | 6 + giregisteredtypeinfo.c | 4 +- giregisteredtypeinfo.h | 6 + girepository.c | 105 ++++-- girepository.h | 31 +- girffi.c | 31 +- girffi.h | 18 +- giroffsets.c | 2 +- gisignalinfo.c | 4 +- gisignalinfo.h | 6 + gistructinfo.c | 12 +- gistructinfo.h | 6 + gitypeinfo.c | 5 +- gitypeinfo.h | 12 + gitypelib-internal.h | 732 +++++++++++++++++++++++------------------ gitypelib.c | 92 +++++- gitypelib.h | 13 + gitypes.h | 95 +++++- giunioninfo.c | 6 +- giunioninfo.h | 6 + givfuncinfo.c | 4 +- givfuncinfo.h | 6 + 43 files changed, 1018 insertions(+), 449 deletions(-) create mode 100644 docs.c diff --git a/docs.c b/docs.c new file mode 100644 index 000000000..a4798c41f --- /dev/null +++ b/docs.c @@ -0,0 +1,33 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Dump introspection data + * + * Copyright (C) 2013 Dieter Verfaillie + * + * 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. + */ + +/* This file collects documentation for macros, typedefs and + * the like, which have no good home in any of the 'real' source + * files. + */ + +/** + * SECTION:gicommontypes + * @title: common types + * @short_description: TODO + * + * TODO + */ diff --git a/giarginfo.c b/giarginfo.c index d61f4be24..572839c3f 100644 --- a/giarginfo.c +++ b/giarginfo.c @@ -26,12 +26,12 @@ #include "girepository-private.h" -/* GIArgInfo function */ +/* GIArgInfo functions */ /** * SECTION:giarginfo - * @Short_description: Struct representing an argument - * @Title: GIArgInfo + * @title: GIArgInfo + * @short_description: Struct representing an argument * * GIArgInfo represents an argument. An argument is always * part of a #GICallableInfo. @@ -293,8 +293,9 @@ g_arg_info_get_destroy (GIArgInfo *info) * * Obtain the type information for @info. * - * Returns: (transfer full): the #GIArgInfo, free it with - * g_base_info_unref() when done. + * Returns: (transfer full): the #GITypeInfo holding the type + * information for @info, free it with g_base_info_unref() + * when done. */ GITypeInfo * g_arg_info_get_type (GIArgInfo *info) diff --git a/giarginfo.h b/giarginfo.h index 3f4163e30..4045ab9c3 100644 --- a/giarginfo.h +++ b/giarginfo.h @@ -31,6 +31,12 @@ G_BEGIN_DECLS +/** + * GI_IS_ARG_INFO + * @info: an info structure + * + * Checks if @info is a GIArgInfo. + */ #define GI_IS_ARG_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ARG) diff --git a/gibaseinfo.c b/gibaseinfo.c index 37893e6c2..4bbe850a0 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -71,6 +71,17 @@ _g_info_new_full (GIInfoType type, return (GIBaseInfo*)info; } +/** + * g_info_new: + * @type: TODO + * @container: TODO + * @typelib: TODO + * @offset: TODO + * + * TODO + * + * Returns: TODO + */ GIBaseInfo * g_info_new (GIInfoType type, GIBaseInfo *container, @@ -169,8 +180,8 @@ _g_type_info_init (GIBaseInfo *info, /** * SECTION:gibaseinfo - * @Short_description: Base struct for all GITypelib structs - * @Title: GIBaseInfo + * @title: GIBaseInfo + * @short_description: Base struct for all GITypelib structs * * GIBaseInfo is the common base struct of all other *Info structs * accessible through the #GIRepository API. @@ -209,7 +220,6 @@ _g_type_info_init (GIBaseInfo *info, * +----GITypeInfo * * - * */ /** diff --git a/gibaseinfo.h b/gibaseinfo.h index 54c8ee4f3..a49dd506f 100644 --- a/gibaseinfo.h +++ b/gibaseinfo.h @@ -33,6 +33,11 @@ G_BEGIN_DECLS +/** + * GIBaseInfoStub: + * + * TODO + */ struct _GIBaseInfoStub { /* */ gint32 dummy1; diff --git a/gicallableinfo.c b/gicallableinfo.c index 28c5950ed..e69e3e9d2 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -33,8 +33,8 @@ /** * SECTION:gicallableinfo - * @Short_description: Struct representing a callable - * @Title: GICallableInfo + * @title: GICallableInfo + * @short_description: Struct representing a callable * * GICallableInfo represents an entity which is callable. * Currently a function (#GIFunctionInfo), virtual function, @@ -85,9 +85,10 @@ signature_offset (GICallableInfo *info) * g_callable_info_can_throw_gerror: * @info: a #GICallableInfo * - * Returns: %TRUE if this #GICallableInfo can throw a #GError + * TODO * * Since: 1.34 + * Returns: %TRUE if this #GICallableInfo can throw a #GError */ gboolean g_callable_info_can_throw_gerror (GICallableInfo *info) @@ -128,6 +129,7 @@ g_callable_info_can_throw_gerror (GICallableInfo *info) * is one more C argument than is exposed by introspection: the "self" * or "this" object. * + * Returns: %TRUE if @info is a method, %FALSE otherwise * Since: 1.34 */ gboolean @@ -430,11 +432,17 @@ g_callable_info_iterate_return_attributes (GICallableInfo *info, return TRUE; } -/* Extract the correct bits from an ffi_arg return value into +/** + * gi_type_info_extract_ffi_return_value: + * @return_info: TODO + * @ffi_value: TODO + * @arg: (out caller-allocates): TODO + * + * Extract the correct bits from an ffi_arg return value into * GIArgument: https://bugzilla.gnome.org/show_bug.cgi?id=665152 * - * Also see the ffi_call man page - the storage requirements for return - * values are "special". + * Also see ffi_call3 + * - the storage requirements for return values are "special". */ void gi_type_info_extract_ffi_return_value (GITypeInfo *return_info, @@ -501,6 +509,21 @@ gi_type_info_extract_ffi_return_value (GITypeInfo *return_info, } } +/** + * g_callable_info_invoke: + * @info: TODO + * @function: TODO + * @in_args: TODO + * @n_in_args: TODO + * @out_args: TODO + * @n_out_args: TODO + * @return_value: TODO + * @is_method: TODO + * @throws: TODO + * @error: TODO + * + * TODO + */ gboolean g_callable_info_invoke (GIFunctionInfo *info, gpointer function, diff --git a/gicallableinfo.h b/gicallableinfo.h index a7d7079a7..71f9d0c62 100644 --- a/gicallableinfo.h +++ b/gicallableinfo.h @@ -31,6 +31,12 @@ G_BEGIN_DECLS +/** + * GI_IS_CALLABLE_INFO + * @info: an info structure + * + * Checks if @info is a #GICallableInfo or derived from it. + */ #define GI_IS_CALLABLE_INFO(info) \ ((g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FUNCTION) || \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_CALLBACK) || \ diff --git a/giconstantinfo.c b/giconstantinfo.c index 88220b4e8..7b2f716c9 100644 --- a/giconstantinfo.c +++ b/giconstantinfo.c @@ -29,8 +29,8 @@ /** * SECTION:giconstantinfo - * @Short_description: Struct representing a constant - * @Title: GIConstantInfo + * @title: GIConstantInfo + * @short_description: Struct representing a constant * * GIConstantInfo represents a constant. A constant has a type associated * which can be obtained by calling g_constant_info_get_type() and a value, diff --git a/giconstantinfo.h b/giconstantinfo.h index 2bbf95699..2ce1dcad6 100644 --- a/giconstantinfo.h +++ b/giconstantinfo.h @@ -31,6 +31,12 @@ G_BEGIN_DECLS +/** + * GI_IS_CONSTANT_INFO + * @info: an info structure + * + * Checks if @info is a #GIConstantInfo. + */ #define GI_IS_CONSTANT_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_CONSTANT) diff --git a/gienuminfo.c b/gienuminfo.c index 400a56d65..253ec6848 100644 --- a/gienuminfo.c +++ b/gienuminfo.c @@ -28,8 +28,8 @@ /** * SECTION:gienuminfo - * @Short_description: Structs representing an enumeration and its values - * @Title: GIEnumInfo + * @title: GIEnumInfo + * @short_description: Structs representing an enumeration and its values * * A GIEnumInfo represents an enumeration and a GIValueInfo struct represents a value * of an enumeration. The GIEnumInfo contains a set of values and a type @@ -46,13 +46,13 @@ */ /** -* g_enum_info_get_n_values: -* @info: a #GIEnumInfo -* -* Obtain the number of values this enumeration contains. -* -* Returns: the number of enumeration values -*/ + * g_enum_info_get_n_values: + * @info: a #GIEnumInfo + * + * Obtain the number of values this enumeration contains. + * + * Returns: the number of enumeration values + */ gint g_enum_info_get_n_values (GIEnumInfo *info) { @@ -76,7 +76,6 @@ g_enum_info_get_n_values (GIEnumInfo *info) * * Returns: (transfer none): the string form of the error domain associated * with this enum, or %NULL. - * * Since: 1.29.17 */ const gchar * @@ -131,7 +130,6 @@ g_enum_info_get_value (GIEnumInfo *info, * Obtain the number of methods that this enum type has. * * Returns: number of methods - * * Since: 1.29.17 */ gint @@ -157,7 +155,6 @@ g_enum_info_get_n_methods (GIEnumInfo *info) * * Returns: (transfer full): the #GIFunctionInfo. Free the struct by calling * g_base_info_unref() when done. - * * Since: 1.29.17 */ GIFunctionInfo * @@ -189,12 +186,12 @@ g_enum_info_get_method (GIEnumInfo *info, * * Obtain the tag of the type used for the enum in the C ABI. This will * will be a signed or unsigned integral type. - + * * Note that in the current implementation the width of the type is * computed correctly, but the signed or unsigned nature of the type * may not match the sign of the type used by the C compiler. * - * Return Value: the storage type for the enumeration + * Returns: the storage type for the enumeration */ GITypeTag g_enum_info_get_storage_type (GIEnumInfo *info) diff --git a/gienuminfo.h b/gienuminfo.h index 0b9a9e1be..257e4c120 100644 --- a/gienuminfo.h +++ b/gienuminfo.h @@ -31,10 +31,22 @@ G_BEGIN_DECLS +/** + * GI_IS_ENUM_INFO + * @info: an info structure + * + * Checks if @info is a #GIEnumInfo. + */ #define GI_IS_ENUM_INFO(info) \ ((g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ENUM) || \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FLAGS)) +/** + * GI_IS_VALUE_INFO + * @info: an info structure + * + * Checks if @info is a #GIValueInfo. + */ #define GI_IS_VALUE_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_VALUE) diff --git a/gifieldinfo.c b/gifieldinfo.c index 1d9a20ddc..2bbc0214f 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -29,13 +29,13 @@ /** * SECTION:gifieldinfo - * @Short_description: Struct representing a struct or union field - * @Title: GIFieldInfo + * @title: GIFieldInfo + * @short_description: Struct representing a struct or union field * * A GIFieldInfo struct represents a field of a struct (see #GIStructInfo), * union (see #GIUnionInfo) or an object (see #GIObjectInfo). The GIFieldInfo * is fetched by calling g_struct_info_get_field(), g_union_info_get_field() - * or g_object_info_get_value(). + * or g_object_info_get_field(). * A field has a size, type and a struct offset asssociated and a set of flags, * which is currently #GI_FIELD_IS_READABLE or #GI_FIELD_IS_WRITABLE. * @@ -167,7 +167,7 @@ g_field_info_get_type (GIFieldInfo *info) * @mem: pointer to a block of memory representing a C structure or union * @value: a #GIArgument into which to store the value retrieved * - * Reads a field identified by a #GFieldInfo from a C structure or + * Reads a field identified by a #GIFieldInfo from a C structure or * union. This only handles fields of simple C types. It will fail * for a field of a composite type like a nested structure or union * even if that is actually readable. @@ -355,7 +355,7 @@ g_field_info_get_field (GIFieldInfo *field_info, * @mem: pointer to a block of memory representing a C structure or union * @value: a #GIArgument holding the value to store * - * Writes a field identified by a #GFieldInfo to a C structure or + * Writes a field identified by a #GIFieldInfo to a C structure or * union. This only handles fields of simple C types. It will fail * for a field of a composite type like a nested structure or union * even if that is actually writable. Note also that that it will refuse diff --git a/gifieldinfo.h b/gifieldinfo.h index 4ca540932..56a2e22ea 100644 --- a/gifieldinfo.h +++ b/gifieldinfo.h @@ -31,6 +31,13 @@ G_BEGIN_DECLS +/** + * GI_IS_FIELD_INFO + * @info: an info structure + * + * Checks if @info is a #GIFieldInfo. + * + */ #define GI_IS_FIELD_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FIELD) diff --git a/gifunctioninfo.c b/gifunctioninfo.c index a5858c76b..ecd612755 100644 --- a/gifunctioninfo.c +++ b/gifunctioninfo.c @@ -30,8 +30,8 @@ /** * SECTION:gifunctioninfo - * @Short_description: Struct representing a function - * @Title: GIFunctionInfo + * @title: GIFunctionInfo + * @short_description: Struct representing a function * * GIFunctionInfo represents a function, method or constructor. * To find out what kind of entity a #GIFunctionInfo represents, call @@ -205,6 +205,13 @@ g_function_info_get_vfunc (GIFunctionInfo *info) return g_interface_info_get_vfunc (container, blob->index); } +/** + * g_invoke_error_quark: + * + * TODO + * + * Returns: TODO + */ GQuark g_invoke_error_quark (void) { diff --git a/gifunctioninfo.h b/gifunctioninfo.h index 7a9ecae01..7987c9260 100644 --- a/gifunctioninfo.h +++ b/gifunctioninfo.h @@ -31,6 +31,12 @@ G_BEGIN_DECLS +/** + * GI_IS_FUNCTION_INFO + * @info: an info structure + * + * Checks if @info is a #GIFunctionInfo. + */ #define GI_IS_FUNCTION_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FUNCTION) @@ -39,6 +45,11 @@ GIFunctionInfoFlags g_function_info_get_flags (GIFunctionInfo *info); GIPropertyInfo * g_function_info_get_property (GIFunctionInfo *info); GIVFuncInfo * g_function_info_get_vfunc (GIFunctionInfo *info); +/** + * G_INVOKE_ERROR: + * + * TODO + */ #define G_INVOKE_ERROR (g_invoke_error_quark ()) GQuark g_invoke_error_quark (void); diff --git a/giinterfaceinfo.c b/giinterfaceinfo.c index f998da446..481fc54e5 100644 --- a/giinterfaceinfo.c +++ b/giinterfaceinfo.c @@ -28,8 +28,8 @@ /** * SECTION:giinterfaceinfo - * @Short_description: Struct representing a GInterface - * @Title: GIInterfaceInfo + * @title: GIInterfaceInfo + * @short_description: Struct representing a GInterface * * GIInterfaceInfo represents a #GInterface type. * @@ -297,9 +297,10 @@ g_interface_info_get_signal (GIInterfaceInfo *info, * @info: a #GIInterfaceInfo * @name: Name of signal * + * TODO + * * Returns: (transfer full): Info for the signal with name @name in @info, or * %NULL on failure. - * * Since: 1.34 */ GISignalInfo * diff --git a/giinterfaceinfo.h b/giinterfaceinfo.h index ce40cda7e..ec33a6300 100644 --- a/giinterfaceinfo.h +++ b/giinterfaceinfo.h @@ -31,6 +31,12 @@ G_BEGIN_DECLS +/** + * GI_IS_INTERFACE_INFO + * @info: an info structure + * + * Checks if @info is a #GIInterfaceInfo. + */ #define GI_IS_INTERFACE_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_INTERFACE) diff --git a/ginvoke.c b/ginvoke.c index 5c0ace4c8..6eba9fcc7 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -28,6 +28,13 @@ #include "girffi.h" #include "config.h" +/** + * value_to_ffi_type: + * @gvalue: TODO + * @value: TODO + * + * TODO + */ static ffi_type * value_to_ffi_type (const GValue *gvalue, gpointer *value) { @@ -89,7 +96,14 @@ value_to_ffi_type (const GValue *gvalue, gpointer *value) return rettype; } -/* See comment aboe set_gargument_from_ffi_return_value() */ +/** + * g_value_to_ffi_return_type: + * @gvalue: TODO + * @ffi_value: TODO + * @value: TODO + * + * TODO + */ static ffi_type * g_value_to_ffi_return_type (const GValue *gvalue, const GIArgument *ffi_value, @@ -153,6 +167,13 @@ g_value_to_ffi_return_type (const GValue *gvalue, return rettype; } +/** + * g_value_from_ffi_value: + * @gvalue: TODO + * @value: TODO + * + * TODO + */ static void g_value_from_ffi_value (GValue *gvalue, const GIArgument *value) @@ -210,6 +231,17 @@ g_value_from_ffi_value (GValue *gvalue, } +/** + * gi_cclosure_marshal_generic: + * @closure: TODO + * @return_gvalue: TODO + * @n_param_values: TODO + * @param_values: TODO + * @invocation_hint: TODO + * @marshal_data: TODO + * + * TODO + */ void gi_cclosure_marshal_generic (GClosure *closure, GValue *return_gvalue, diff --git a/giobjectinfo.c b/giobjectinfo.c index 7ba2a93b8..b0aff37cd 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -28,8 +28,8 @@ /** * SECTION:giobjectinfo - * @Short_description: Struct representing a GObject - * @Title: GIObjectInfo + * @title: GIObjectInfo + * @short_description: Struct representing a GObject * * GIObjectInfo represents a #GObject. This doesn't represent a specific * instance of a GObject, instead this represent the object type (eg class). @@ -534,6 +534,8 @@ g_object_info_get_signal (GIObjectInfo *info, * @info: a #GIObjectInfo * @name: Name of signal * + * TODO + * * Returns: Info for the signal with name @name in @info, or %NULL on failure. */ GISignalInfo * diff --git a/giobjectinfo.h b/giobjectinfo.h index ee4b8a823..06206776d 100644 --- a/giobjectinfo.h +++ b/giobjectinfo.h @@ -46,7 +46,6 @@ typedef void * (*GIObjectInfoRefFunction) (void *object); * @object: object instance pointer * * Decreases the reference count of an object instance. - * */ typedef void (*GIObjectInfoUnrefFunction) (void *object); @@ -56,7 +55,6 @@ typedef void (*GIObjectInfoUnrefFunction) (void *object); * @object: object instance pointer * * Update @value and attach the object instance pointer @object to it. - * */ typedef void (*GIObjectInfoSetValueFunction) (GValue *value, void *object); @@ -70,6 +68,12 @@ typedef void (*GIObjectInfoSetValueFunction) (GValue *value, void *object); */ typedef void * (*GIObjectInfoGetValueFunction) (const GValue *value); +/** + * GI_IS_OBJECT_INFO + * @info: an info structure + * + * Checks if @info is a #GIObjectInfo. + */ #define GI_IS_OBJECT_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_OBJECT) diff --git a/gipropertyinfo.c b/gipropertyinfo.c index 61316cb9c..77a11cb86 100644 --- a/gipropertyinfo.c +++ b/gipropertyinfo.c @@ -28,8 +28,8 @@ /** * SECTION:gipropertyinfo - * @Short_description: Struct representing a property - * @Title: GIPropertyInfo + * @title: GIPropertyInfo + * @short_description: Struct representing a property * * GIPropertyInfo represents a property. A property belongs to * either a #GIObjectInfo or a #GIInterfaceInfo. @@ -47,7 +47,7 @@ * g_property_info_get_flags: * @info: a #GIPropertyInfo * - * Obtain the flags for this property info. See #GParamFags for + * Obtain the flags for this property info. See #GParamFlags for * more information about possible flag values. * * Returns: the flags diff --git a/gipropertyinfo.h b/gipropertyinfo.h index 14b18b417..7644664bd 100644 --- a/gipropertyinfo.h +++ b/gipropertyinfo.h @@ -31,6 +31,12 @@ G_BEGIN_DECLS +/** + * GI_IS_PROPERTY_INFO + * @info: an info structure + * + * Checks if @info is a #GIPropertyInfo. + */ #define GI_IS_PROPERTY_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_PROPERTY) diff --git a/giregisteredtypeinfo.c b/giregisteredtypeinfo.c index 6e3d31e2a..e45e06038 100644 --- a/giregisteredtypeinfo.c +++ b/giregisteredtypeinfo.c @@ -30,8 +30,8 @@ /** * SECTION:giregisteredtypeinfo - * @Short_description: Struct representing a struct with a GType - * @Title: GIRegisteredTypeInfo + * @title: GIRegisteredTypeInfo + * @short_description: Struct representing a struct with a GType * * GIRegisteredTypeInfo represents an entity with a GType associated. Could * be either a #GIEnumInfo, #GIInterfaceInfo, #GIObjectInfo, #GIStructInfo or a diff --git a/giregisteredtypeinfo.h b/giregisteredtypeinfo.h index d46d738bd..e5db25b4d 100644 --- a/giregisteredtypeinfo.h +++ b/giregisteredtypeinfo.h @@ -32,6 +32,12 @@ G_BEGIN_DECLS +/** + * GI_IS_REGISTERED_TYPE_INFO + * @info: an info structure + * + * Checks if @info is a #GIRegisteredTypeInfo or derived from it. + */ #define GI_IS_REGISTERED_TYPE_INFO(info) \ ((g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_BOXED) || \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ENUM) || \ diff --git a/girepository.c b/girepository.c index 93c237282..6fc7c77e9 100644 --- a/girepository.c +++ b/girepository.c @@ -34,6 +34,17 @@ #include "config.h" + +/** + * SECTION:girepository + * @short_description: GObject Introspection repository manager + * @include: girepository.h + * + * #GIRepository is used to manage repositories of namespaces. Namespaces + * are represented on disk by type libraries (.typelib files). + */ + + static GIRepository *default_repository = NULL; static GSList *search_path = NULL; static GSList *override_search_path = NULL; @@ -146,8 +157,9 @@ init_globals (void) char *typelib_dir; const gchar *type_lib_path_env; - /* This variable is intended to take precedence over both the default - * search path, as well as anything written into code with g_irepository_prepend_search_path. + /* This variable is intended to take precedence over both: + * - the default search path; + * - all g_irepository_prepend_search_path() calls. */ type_lib_path_env = g_getenv ("GI_TYPELIB_PATH"); @@ -186,6 +198,14 @@ init_globals (void) g_once_init_leave (&initialized, 1); } +/** + * g_irepository_prepend_search_path: + * @directory: (type filename): directory name to prepend to the typelib + * search path + * + * Prepends @directory to the typelib search path. + * See g_irepository_get_search_path(). + */ void g_irepository_prepend_search_path (const char *directory) { @@ -196,11 +216,11 @@ g_irepository_prepend_search_path (const char *directory) /** * g_irepository_get_search_path: * - * Returns the search path the GIRepository will use when looking for typelibs. - * The string is internal to GIRespository and should not be freed, nor should - * the elements. + * Returns the current search path #GIRepository will use when loading + * typelib files. The list is internal to #GIRespository and should not + * be freed, nor should its string elements. * - * Return value: (element-type filename) (transfer none): list of strings + * Returns: (element-type filename) (transfer none): #GSList of strings */ GSList * g_irepository_get_search_path (void) @@ -412,17 +432,19 @@ register_internal (GIRepository *repository, /** * g_irepository_get_dependencies: - * @repository: (allow-none): A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * process-global default #GIRepository * @namespace_: Namespace of interest * - * Return an array of all (transitive) dependencies for namespace - * @namespace_, including version. The returned strings are of the - * form namespace-version. + * Return an array of all (transitive) versioned dependencies for + * @namespace_. Returned strings are of the form + * namespace-version. * - * Note: The namespace must have already been loaded using a function + * Note: @namespace_ must have already been loaded using a function * such as g_irepository_require() before calling this function. * - * Returns: (transfer full): Zero-terminated string array of versioned dependencies + * Returns: (transfer full): Zero-terminated string array of versioned + * dependencies */ char ** g_irepository_get_dependencies (GIRepository *repository, @@ -440,6 +462,16 @@ g_irepository_get_dependencies (GIRepository *repository, return get_typelib_dependencies (typelib); } +/** + * g_irepository_load_typelib: + * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * process-global default #GIRepository + * @typelib: TODO + * @flags: TODO + * @error: TODO + * + * TODO + */ const char * g_irepository_load_typelib (GIRepository *repository, GITypelib *typelib, @@ -478,7 +510,8 @@ g_irepository_load_typelib (GIRepository *repository, /** * g_irepository_is_registered: - * @repository: (allow-none): A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * process-global default #GIRepository * @namespace_: Namespace of interest * @version: (allow-none): Required version, may be %NULL for latest * @@ -503,13 +536,13 @@ g_irepository_is_registered (GIRepository *repository, /** * g_irepository_get_default: * - * Returns the singleton process-global default #GIRepository. It is + * Returns the singleton process-global default #GIRepository. It is * not currently supported to have multiple repositories in a * particular process, but this function is provided in the unlikely * eventuality that it would become possible, and as a convenience for * higher level language bindings to conform to the GObject method * call conventions. - + * * All methods on #GIRepository also accept %NULL as an instance * parameter to mean this default repository, which is usually more * convenient for C. @@ -524,7 +557,8 @@ g_irepository_get_default (void) /** * g_irepository_get_n_infos: - * @repository: (allow-none): A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * process-global default #GIRepository * @namespace_: Namespace to inspect * * This function returns the number of metadata entries in @@ -555,7 +589,8 @@ g_irepository_get_n_infos (GIRepository *repository, /** * g_irepository_get_info: - * @repository: (allow-none): A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * process-global default #GIRepository * @namespace_: Namespace to inspect * @index: 0-based offset into namespace metadata for entry * @@ -629,7 +664,8 @@ find_by_gtype (GHashTable *table, FindByGTypeData *data, gboolean check_prefix) /** * g_irepository_find_by_gtype: - * @repository: (allow-none): A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * process-global default #GIRepository * @gtype: GType to search for * * Searches all loaded namespaces for a particular #GType. Note that @@ -717,7 +753,8 @@ g_irepository_find_by_gtype (GIRepository *repository, /** * g_irepository_find_by_name: - * @repository: (allow-none): A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * process-global default #GIRepository * @namespace_: Namespace which will be searched * @name: Entry name to find * @@ -776,7 +813,8 @@ find_by_error_domain_foreach (gpointer key, /** * g_irepository_find_by_error_domain: - * @repository: (allow-none): A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * process-global default #GIRepository * @domain: a #GError domain * * Searches for the enum type corresponding to the given #GError @@ -786,7 +824,6 @@ find_by_error_domain_foreach (gpointer key, * * Returns: (transfer full): #GIEnumInfo representing metadata about @domain's * enum type, or %NULL - * * Since: 1.29.17 */ GIEnumInfo * @@ -839,7 +876,8 @@ collect_namespaces (gpointer key, /** * g_irepository_get_loaded_namespaces: - * @repository: (allow-none): A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * process-global default #GIRepository * * Return the list of currently loaded namespaces. * @@ -868,7 +906,8 @@ g_irepository_get_loaded_namespaces (GIRepository *repository) /** * g_irepository_get_version: - * @repository: (allow-none): A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * process-global default #GIRepository * @namespace_: Namespace to inspect * * This function returns the loaded version associated with the given @@ -900,7 +939,8 @@ g_irepository_get_version (GIRepository *repository, /** * g_irepository_get_shared_library: - * @repository: (allow-none): A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * process-global default #GIRepository * @namespace_: Namespace to inspect * * This function returns the full path to the shared C library @@ -937,7 +977,8 @@ g_irepository_get_shared_library (GIRepository *repository, /** * g_irepository_get_c_prefix: - * @repository: (allow-none): A #GIRepository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * process-global default #GIRepository * @namespace_: Namespace to inspect * * This function returns the "C prefix", or the C level namespace @@ -973,13 +1014,14 @@ g_irepository_get_c_prefix (GIRepository *repository, /** * g_irepository_get_typelib_path: - * @repository: (allow-none): Repository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * process-global default #GIRepository * @namespace_: GI namespace to use, e.g. "Gtk" * * If namespace @namespace_ is loaded, return the full path to the * .typelib file it was loaded from. If the typelib for * namespace @namespace_ was included in a shared library, return - * the special string "$lt;builtin$gt;". + * the special string "<builtin>". * * Returns: Filesystem path (or $lt;builtin$gt;) if successful, %NULL if namespace is not loaded */ @@ -1248,7 +1290,8 @@ find_namespace_latest (const gchar *namespace, /** * g_irepository_enumerate_versions: - * @repository: (allow-none): the repository + * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * process-global default #GIRepository * @namespace_: GI namespace, e.g. "Gtk" * * Obtain an unordered list of versions (either currently loaded or @@ -1408,7 +1451,8 @@ require_internal (GIRepository *repository, /** * g_irepository_require: - * @repository: (allow-none): Repository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * process-global default #GIRepository * @namespace_: GI namespace to use, e.g. "Gtk" * @version: (allow-none): Version of namespace, may be %NULL for latest * @flags: Set of %GIRepositoryLoadFlags, may be 0 @@ -1442,7 +1486,8 @@ g_irepository_require (GIRepository *repository, /** * g_irepository_require_private: - * @repository: (allow-none): Repository, may be %NULL for the default + * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * process-global default #GIRepository * @typelib_dir: Private directory where to find the requested typelib * @namespace_: GI namespace to use, e.g. "Gtk" * @version: (allow-none): Version of namespace, may be %NULL for latest diff --git a/girepository.h b/girepository.h index 2b2b17138..dea250dfa 100644 --- a/girepository.h +++ b/girepository.h @@ -56,29 +56,34 @@ G_BEGIN_DECLS #define G_IS_IREPOSITORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_IREPOSITORY)) #define G_IREPOSITORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_IREPOSITORY, GIRepositoryClass)) +/** + * GIRepository: + * + * The GIRepository structure contains private data and should only be + * accessed using the provided API. + */ typedef struct _GIRepository GIRepository; typedef struct _GIRepositoryClass GIRepositoryClass; typedef struct _GIRepositoryPrivate GIRepositoryPrivate; struct _GIRepository { - GObject parent; - /*< private >*/ + GObject parent; GIRepositoryPrivate *priv; }; struct _GIRepositoryClass { + /*< private >*/ GObjectClass parent; }; /** * GIRepositoryLoadFlags: - * @G_IREPOSITORY_LOAD_FLAG_LAZY: Load the types lazily. + * @G_IREPOSITORY_LOAD_FLAG_LAZY: Lazily load the typelib. * - * Flags that controlls how a typelib is loaded by - * GIRepositry, used by g_irepository_load_typelib(). + * Flags that control how a typelib is loaded. */ typedef enum { @@ -144,11 +149,14 @@ gboolean g_irepository_dump (const char *arg, GError **error); * GIRepositoryError: * @G_IREPOSITORY_ERROR_TYPELIB_NOT_FOUND: the typelib could not be found. * @G_IREPOSITORY_ERROR_NAMESPACE_MISMATCH: the namespace does not match the - * requested namespace. + * requested namespace. * @G_IREPOSITORY_ERROR_NAMESPACE_VERSION_CONFLICT: the version of the - * typelib does not match the requested version. + * typelib does not match the requested version. * @G_IREPOSITORY_ERROR_LIBRARY_NOT_FOUND: the library used by the typelib - * could not be found. + * could not be found. + * + * An error code used with #G_IREPOSITORY_ERROR in a #GError returned + * from a #GIRepository routine. */ typedef enum { @@ -158,6 +166,13 @@ typedef enum G_IREPOSITORY_ERROR_LIBRARY_NOT_FOUND } GIRepositoryError; +/** + * G_IREPOSITORY_ERROR: + * + * Error domain for #GIRepository. Errors in this domain will be from the + * #GIRepositoryError enumeration. See #GError for more information on + * error domains. + */ #define G_IREPOSITORY_ERROR (g_irepository_error_quark ()) GQuark g_irepository_error_quark (void); diff --git a/girffi.c b/girffi.c index f4c80eaad..30642fe18 100644 --- a/girffi.c +++ b/girffi.c @@ -33,6 +33,14 @@ #include "girepository.h" #include "girepository-private.h" +/** + * SECTION:girffi + * @short_description: TODO + * @title: girffi + * + * TODO + */ + static ffi_type * gi_type_tag_get_ffi_type_internal (GITypeTag tag, gboolean is_pointer, @@ -103,22 +111,26 @@ gi_type_tag_get_ffi_type_internal (GITypeTag tag, /** * gi_type_tag_get_ffi_type: - * @tag: A #GITypeTag + * @type_tag: A #GITypeTag * @is_pointer: Whether or not this is a pointer type * + * TODO + * * Returns: A #ffi_type corresponding to the platform default C ABI for @tag and @is_pointer. */ ffi_type * -gi_type_tag_get_ffi_type (GITypeTag tag, +gi_type_tag_get_ffi_type (GITypeTag type_tag, gboolean is_pointer) { - return gi_type_tag_get_ffi_type_internal (tag, is_pointer, FALSE); + return gi_type_tag_get_ffi_type_internal (type_tag, is_pointer, FALSE); } /** * g_type_info_get_ffi_type: * @info: A #GITypeInfo * + * TODO + * * Returns: A #ffi_type corresponding to the platform default C ABI for @info. */ ffi_type * @@ -150,7 +162,9 @@ g_type_info_get_ffi_type (GITypeInfo *info) * @callable_info: a callable info from a typelib * @n_args_p: (out): The number of arguments * - * Return value: an array of ffi_type*. The array itself + * TODO + * + * Returns: an array of ffi_type*. The array itself * should be freed using g_free() after use. */ static ffi_type ** @@ -217,7 +231,8 @@ g_callable_info_get_ffi_arg_types (GICallableInfo *callable_info, * * Fetches the ffi_type for a corresponding return value of * a #GICallableInfo - * Return value: the ffi_type for the return value + * + * Returns: the ffi_type for the return value */ static ffi_type * g_callable_info_get_ffi_return_type (GICallableInfo *callable_info) @@ -316,7 +331,7 @@ g_function_invoker_new_for_address (gpointer addr, } /** - * g_function_info_invoker_destroy: + * g_function_invoker_destroy: * @invoker: A #GIFunctionInvoker * * Release all resources allocated for the internals of @invoker; callers @@ -343,8 +358,8 @@ typedef struct { * * Prepares a callback for ffi invocation. * - * Return value: the ffi_closure or NULL on error. - * The return value should be freed by calling g_callable_info_free_closure(). + * Returns: the ffi_closure or NULL on error. The return value + * should be freed by calling g_callable_info_free_closure(). */ ffi_closure * g_callable_info_prepare_closure (GICallableInfo *callable_info, diff --git a/girffi.h b/girffi.h index 56caff732..50cabb170 100644 --- a/girffi.h +++ b/girffi.h @@ -27,6 +27,15 @@ G_BEGIN_DECLS +/** + * GIFFIClosureCallback: + * @Param1: TODO + * @Param2: TODO + * @Param3: TODO + * @Param4: TODO + * + * TODO + */ typedef void (*GIFFIClosureCallback) (ffi_cif *, void *, void **, @@ -35,7 +44,9 @@ typedef void (*GIFFIClosureCallback) (ffi_cif *, /** * GIFunctionInvoker: * @cif: the cif - * @native_address: the native adress + * @native_address: the native address + * + * TODO */ typedef struct _GIFunctionInvoker GIFunctionInvoker; @@ -46,6 +57,11 @@ struct _GIFunctionInvoker { gpointer padding[3]; }; +/** + * GIFFIReturnValue: + * + * TODO + */ typedef GIArgument GIFFIReturnValue; ffi_type * gi_type_tag_get_ffi_type (GITypeTag type_tag, gboolean is_pointer); diff --git a/giroffsets.c b/giroffsets.c index 368332eab..84278b897 100644 --- a/giroffsets.c +++ b/giroffsets.c @@ -497,7 +497,7 @@ check_needs_computation (GIrTypelibBuild *build, return alignment == 0; } -/** +/* * _g_ir_node_compute_offsets: * @build: Current typelib build * @node: a #GIrNode diff --git a/gisignalinfo.c b/gisignalinfo.c index f4110c382..be75276e9 100644 --- a/gisignalinfo.c +++ b/gisignalinfo.c @@ -28,8 +28,8 @@ /** * SECTION:gisignalinfo - * @Short_description: Struct representing a signal - * @Title: GISignalInfo + * @title: GISignalInfo + * @short_description: Struct representing a signal * * GISignalInfo represents a signal. It's a sub-struct of #GICallableInfo * and contains a set of flags and a class closure. diff --git a/gisignalinfo.h b/gisignalinfo.h index e3a1e4a49..8502610c4 100644 --- a/gisignalinfo.h +++ b/gisignalinfo.h @@ -32,6 +32,12 @@ G_BEGIN_DECLS +/** + * GI_IS_SIGNAL_INFO + * @info: an info structure + * + * Checks if @info is a #GISignalInfo. + */ #define GI_IS_SIGNAL_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_SIGNAL) diff --git a/gistructinfo.c b/gistructinfo.c index dc17e3223..f205e7cf5 100644 --- a/gistructinfo.c +++ b/gistructinfo.c @@ -28,8 +28,8 @@ /** * SECTION:gistructinfo - * @Short_description: Struct representing a C structure - * @Title: GIStructInfo + * @title: GIStructInfo + * @short_description: Struct representing a C structure * * GIStructInfo represents a generic C structure type. * @@ -212,6 +212,14 @@ g_struct_info_get_alignment (GIStructInfo *info) return blob->alignment; } +/** + * g_struct_info_is_foreign: + * @info: TODO + * + * TODO + * + * Returns: TODO + */ gboolean g_struct_info_is_foreign (GIStructInfo *info) { diff --git a/gistructinfo.h b/gistructinfo.h index 1d10708eb..4300534d6 100644 --- a/gistructinfo.h +++ b/gistructinfo.h @@ -31,6 +31,12 @@ G_BEGIN_DECLS +/** + * GI_IS_STRUCT_INFO + * @info: an info structure + * + * Checks if @info is a #GIStructInfo. + */ #define GI_IS_STRUCT_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_STRUCT) diff --git a/gitypeinfo.c b/gitypeinfo.c index a43fbc1bb..3c17f5647 100644 --- a/gitypeinfo.c +++ b/gitypeinfo.c @@ -28,8 +28,8 @@ /** * SECTION:gitypeinfo - * @Short_description: Struct representing a type - * @Title: GITypeInfo + * @title: GITypeInfo + * @short_description: Struct representing a type * * GITypeInfo represents a type. You can retrieve a type info from * an argument (see #GIArgInfo), a functions return value (see #GIFunctionInfo), @@ -48,7 +48,6 @@ * +----GITypeInfo * * - * */ /** diff --git a/gitypeinfo.h b/gitypeinfo.h index ef834b12b..7591799a4 100644 --- a/gitypeinfo.h +++ b/gitypeinfo.h @@ -31,9 +31,21 @@ G_BEGIN_DECLS +/** + * GI_IS_TYPE_INFO + * @info: an info structure + * + * Checks if @info is a #GITypeInfo. + */ #define GI_IS_TYPE_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_TYPE) +/** + * G_TYPE_TAG_IS_BASIC + * @tag: a type tag + * + * Checks if @tag is a basic type. + */ #define G_TYPE_TAG_IS_BASIC(tag) (tag < GI_TYPE_TAG_ARRAY || tag == GI_TYPE_TAG_UNICHAR) const gchar* g_type_tag_to_string (GITypeTag type); diff --git a/gitypelib-internal.h b/gitypelib-internal.h index ac71008d8..23f4d625e 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -30,7 +30,8 @@ G_BEGIN_DECLS /** - * SECTION:gtypelib + * SECTION:gitypelib-internal + * @title: GITypelib * @short_description: Layout and accessors for typelib * @stability: Stable * @@ -42,32 +43,31 @@ G_BEGIN_DECLS * * Some of the differences to XPCOM include: * - Type information is stored not quite as compactly (XPCOM stores it inline - * in function descriptions in variable-sized blobs of 1 to n bytes. We store - * 16 bits of type information for each parameter, which is enough to encode - * simple types inline. Complex (e.g. recursive) types are stored out of line - * in a separate list of types. + * in function descriptions in variable-sized blobs of 1 to n bytes. We store + * 16 bits of type information for each parameter, which is enough to encode + * simple types inline. Complex (e.g. recursive) types are stored out of line + * in a separate list of types. * - String and complex type data is stored outside of typelib entry blobs, - * references are stored as offsets relative to the start of the typelib. - * One possibility is to store the strings and types in a pools at the end - * of the typelib. + * references are stored as offsets relative to the start of the typelib. + * One possibility is to store the strings and types in a pools at the end + * of the typelib. * - * The typelib has the following general format. + * The typelib has the following general format: * - * typelib ::= header, section-index, directory, blobs, attributes, attributedata + * typelib ::= header, section-index, directory, blobs, attributes, attributedata * - * directory ::= list of entries + * directory ::= list of entries * - * entry ::= blob type, name, namespace, offset - * blob ::= function|callback|struct|boxed|enum|flags|object|interface|constant|union - * attributes ::= list of attributes, sorted by offset - * attribute ::= offset, key, value - * attributedata ::= string data for attributes + * entry ::= blob type, name, namespace, offset + * blob ::= function|callback|struct|boxed|enum|flags|object|interface|constant|union + * attribute ::= offset, key, value + * attributedata ::= string data for attributes * * Details * * We describe the fragments that make up the typelib in the form of C structs - * (although some fall short of being valid C structs since they contain multiple - * flexible arrays). + * (although some fall short of being valid C structs since they contain + * multiple flexible arrays). */ /* @@ -157,10 +157,11 @@ Changes since 0.1: * @BLOB_TYPE_OBJECT: An #ObjectBlob * @BLOB_TYPE_INTERFACE: An #InterfaceBlob * @BLOB_TYPE_CONSTANT: A #ConstantBlob + * @BLOB_TYPE_INVALID_0: Deleted, used to be ErrorDomain. * @BLOB_TYPE_UNION: A #UnionBlob * - * The integral value of this enumeration appears in each "Blob" - * component of a typelib to identify its type. + * The integral value of this enumeration appears in each "Blob" component of + * a typelib to identify its type. */ typedef enum { BLOB_TYPE_INVALID, @@ -173,7 +174,7 @@ typedef enum { BLOB_TYPE_OBJECT, BLOB_TYPE_INTERFACE, BLOB_TYPE_CONSTANT, - BLOB_TYPE_INVALID_0, /* DELETED - used to be ErrorDomain */ + BLOB_TYPE_INVALID_0, BLOB_TYPE_UNION } GTypelibBlobType; @@ -188,52 +189,54 @@ typedef enum { /** * Header: * @magic: See #G_IR_MAGIC. - * @major_version: The version of the typelib format. Minor version changes indicate - * compatible changes and should still allow the typelib to be parsed - * by a parser designed for the same major_version. - * @minor_version: See major_version. + * @major_version: The major version number of the typelib format. Major version + * number changes indicate incompatible changes to the tyeplib format. + * @minor_version: The minor version number of the typelib format. Minor version + * number changes indicate compatible changes and should still allow the + * typelib to be parsed by a parser designed for the same @major_version. + * @reserved: Reserved for future use. * @n_entries: The number of entries in the directory. - * @n_local_entries: The number of entries referring to blobs in this typelib. The - * local entries must occur before the unresolved entries. + * @n_local_entries: The number of entries referring to blobs in this typelib. + * The local entries must occur before the unresolved entries. * @directory: Offset of the directory in the typelib. * @n_attributes: Number of attribute blocks * @attributes: Offset of the list of attributes in the typelib. - * @dependencies: Offset of a single string, which is the list of - * dependencies, separated by the '|' character. The - * dependencies are required in order to avoid having programs - * consuming a typelib check for an "Unresolved" type return - * from every API call. + * @dependencies: Offset of a single string, which is the list of dependencies, + * separated by the '|' character. The dependencies are required in order + * to avoid having programs consuming a typelib check for an "Unresolved" + * type return from every API call. * @size: The size in bytes of the typelib. * @namespace: Offset of the namespace string in the typelib. * @nsversion: Offset of the namespace version string in the typelib. - * @shared_library: This field is the set of shared libraries associated - * with the typelib. The entries are separated by the '|' (pipe) character. + * @shared_library: This field is the set of shared libraries associated with + * the typelib. The entries are separated by the '|' (pipe) character. * @c_prefix: The prefix for the function names of the library - * @entry_blob_size: The sizes of fixed-size blobs. Recording this information here - * allows to write parser which continue to work if the format is - * extended by adding new fields to the end of the fixed-size blobs. - * @function_blob_size: See above. - * @callback_blob_size: See above. - * @signal_blob_size: See above. - * @vfunc_blob_size: See above. - * @arg_blob_size: See above. - * @property_blob_size: See above. - * @field_blob_size: See above. - * @value_blob_size: See above. - * @attribute_blob_size: See above. - * @constant_blob_size: See above. - * @object_blob_size: See above. - * @union_blob_size: See above. - * @signature_blob_size: See above. - * @enum_blob_size: See above. - * @struct_blob_size: See above. - * @error_domain_blob_size: See above. - * @interface_blob_size: For variable-size blobs, the size of the struct up to the first - * flexible array member. Recording this information here allows to - * write parser which continue to work if the format is extended by - * adding new fields before the first flexible array member in - * variable-size blobs. + * @entry_blob_size: The sizes of fixed-size blobs. Recording this information + * here allows to write parser which continue to work if the format is + * extended by adding new fields to the end of the fixed-size blobs. + * @function_blob_size: See @entry_blob_size. + * @callback_blob_size: See @entry_blob_size. + * @signal_blob_size: See @entry_blob_size. + * @vfunc_blob_size: See @entry_blob_size. + * @arg_blob_size: See @entry_blob_size. + * @property_blob_size: See @entry_blob_size. + * @field_blob_size: See @entry_blob_size. + * @value_blob_size: See @entry_blob_size. + * @attribute_blob_size: See @entry_blob_size. + * @constant_blob_size: See @entry_blob_size. + * @error_domain_blob_size: See @entry_blob_size. + * @signature_blob_size: See @entry_blob_size. + * @enum_blob_size: See @entry_blob_size. + * @struct_blob_size: See @entry_blob_size. + * @object_blob_size: See @entry_blob_size. + * @interface_blob_size: For variable-size blobs, the size of the struct up to + * the first flexible array member. Recording this information here allows + * to write parser which continue to work if the format is extended by + * adding new fields before the first flexible array member in + * variable-size blobs. + * @union_blob_size: See @entry_blob_size. * @sections: Offset of section blob array + * @padding: TODO * * The header structure appears exactly once at the beginning of a typelib. It is a * collection of meta-information, such as the number of entries and dependencies. @@ -242,9 +245,7 @@ typedef struct { gchar magic[16]; guint8 major_version; guint8 minor_version; - /* */ guint16 reserved; - /* */ guint16 n_entries; guint16 n_local_entries; guint32 directory; @@ -281,10 +282,16 @@ typedef struct { guint32 sections; - /* */ guint16 padding[6]; } Header; +/** + * SectionType: + * @GI_SECTION_END: TODO + * @GI_SECTION_DIRECTORY_INDEX: TODO + * + * TODO + */ typedef enum { GI_SECTION_END = 0, GI_SECTION_DIRECTORY_INDEX = 1 @@ -299,7 +306,6 @@ typedef enum { * and may or may not be present in the typelib. Presently, just used * for the directory index. This allows a form of dynamic extensibility * with different tradeoffs from the format minor version. - * */ typedef struct { guint32 id; @@ -311,10 +317,11 @@ typedef struct { * DirEntry: * @blob_type: A #GTypelibBlobType * @local: Whether this entry refers to a blob in this typelib. + * @reserved: Reserved for future use. * @name: The name of the entry. - * @offset: If is_local is set, this is the offset of the blob in the typelib. - * Otherwise, it is the offset of the namespace in which the blob has - * to be looked up by name. + * @offset: If is_local is set, this is the offset of the blob in the typelib. + * Otherwise, it is the offset of the namespace in which the blob has to be + * looked up by name. * * References to directory entries are stored as 1-based 16-bit indexes. * @@ -325,91 +332,100 @@ typedef struct { guint16 blob_type; guint16 local : 1; - /* */ guint16 reserved :15; - /* */ guint32 name; guint32 offset; } DirEntry; /** - * SimpleTypeBlob: - * @is_pointer: Indicates whether the type is passed by reference. + * SimpleTypeBlobFlags: + * @reserved: Reserved for future use. + * @reserved2: Reserved for future use. + * @pointer: TODO + * @reserved3: Reserved for future use. * @tag: A #GITypeTag - * @offset: Offset relative to header->types that points to a TypeBlob. - * Unlike other offsets, this is in words (ie 32bit units) rather - * than bytes. * - * The SimpleTypeBlob is the general purpose "reference to a type" construct, used - * in method parameters, returns, callback definitions, fields, constants, etc. - * It's actually just a 32 bit integer which you can see from the union definition. - * This is for efficiency reasons, since there are so many references to types. - * - * SimpleTypeBlob is divided into two cases; first, if "reserved" and "reserved2", the - * type tag for a basic type is embedded in the "tag" bits. This allows e.g. - * GI_TYPE_TAG_UTF8, GI_TYPE_TAG_INT and the like to be embedded directly without - * taking up extra space. - * - * References to "interfaces" (objects, interfaces) are more complicated; In this case, - * the integer is actually an offset into the directory (see above). Because the header - * is larger than 2^8=256 bits, all offsets will have one of the upper 24 bits set. + * TODO */ -typedef union +typedef struct { + guint reserved : 8; + guint reserved2 :16; + guint pointer : 1; + guint reserved3 : 2; + guint tag : 5; +} SimpleTypeBlobFlags; + +union _SimpleTypeBlob { - struct - { - /* */ - guint reserved : 8; - guint reserved2 :16; - /* */ - guint pointer : 1; - /* */ - guint reserved3 : 2; - /* */ - guint tag : 5; - } flags; + SimpleTypeBlobFlags flags; guint32 offset; -} SimpleTypeBlob; +}; + +/** + * SimpleTypeBlob: + * @flags: TODO + * @offset: Offset relative to header->types that points to a TypeBlob. + * Unlike other offsets, this is in words (ie 32bit units) rather + * than bytes. + * + * The SimpleTypeBlob is the general purpose "reference to a type" construct, + * used in method parameters, returns, callback definitions, fields, constants, + * etc. It's actually just a 32 bit integer which you can see from the union + * definition. This is for efficiency reasons, since there are so many + * references to types. + * + * SimpleTypeBlob is divided into two cases; first, if "reserved" and + * "reserved2", the type tag for a basic type is embedded in the "tag" bits. + * This allows e.g. GI_TYPE_TAG_UTF8, GI_TYPE_TAG_INT and the like to be + * embedded directly without taking up extra space. + * + * References to "interfaces" (objects, interfaces) are more complicated; + * In this case, the integer is actually an offset into the directory (see + * above). Because the header is larger than 2^8=256 bits, all offsets will + * have one of the upper 24 bits set. + */ +typedef union _SimpleTypeBlob SimpleTypeBlob; /** * ArgBlob: * @name: A suggested name for the parameter. * @in: The parameter is an input to the function - * @out: The parameter is used to return an output of the function. - * Parameters can be both in and out. Out parameters implicitly - * add another level of indirection to the parameter type. Ie if - * the type is uint32 in an out parameter, the function actually - * takes an uint32*. - * @caller_allocates: The parameter is a pointer to a struct or object that will - * receive an output of the function. - * @allow_none: Only meaningful for types which are passed as pointers. - * For an in parameter, indicates if it is ok to pass NULL in, for - * an out parameter, whether it may return NULL. Note that NULL is a - * valid GList and GSList value, thus allow_none will normally be set - * for parameters of these types. + * @out: The parameter is used to return an output of the function. Parameters + * can be both in and out. Out parameters implicitly add another level of + * indirection to the parameter type. Ie if the type is uint32 in an out + * parameter, the function actually takes an uint32*. + * @caller_allocates: The parameter is a pointer to a struct or object that + * will receive an output of the function. + * @allow_none: Only meaningful for types which are passed as pointers. For an + * in parameter, indicates if it is ok to pass NULL in. Gor an out + * parameter, indicates whether it may return NULL. Note that NULL is a + * valid GList and GSList value, thus allow_none will normally be set + * for parameters of these types. * @optional: For an out parameter, indicates that NULL may be passed in - * if the value is not needed. - * @transfer_ownership: For an in parameter, indicates that the function takes over - * ownership of the parameter value. For an out parameter, it - * indicates that the caller is responsible for freeing the return - * value. + * if the value is not needed. + * @transfer_ownership: For an in parameter, indicates that the function takes + * over ownership of the parameter value. For an out parameter, it indicates + * that the caller is responsible for freeing the return value. * @transfer_container_ownership: For container types, indicates that the - * ownership of the container, but not of its contents is transferred. This is typically the case - * for out parameters returning lists of statically allocated things. - * @return_value: The parameter should be considered the return value of the function. - * Only out parameters can be marked as return value, and there can be - * at most one per function call. If an out parameter is marked as - * return value, the actual return value of the function should be - * either void or a boolean indicating the success of the call. - * @scope: A #GIScopeType. If the parameter is of a callback type, this denotes the scope - * of the user_data and the callback function pointer itself - * (for languages that emit code at run-time). - * @closure: Index of the closure (user_data) parameter associated with the callback, - * or -1. - * @destroy: Index of the destroy notfication callback parameter associated with - * the callback, or -1. - * @arg_type: Describes the type of the parameter. See details below. + * ownership of the container, but not of its contents is transferred. + * This is typically the case for out parameters returning lists of + * statically allocated things. + * @return_value: The parameter should be considered the return value of the + * function. Only out parameters can be marked as return value, and there + * can be at most one per function call. If an out parameter is marked as + * return value, the actual return value of the function should be either + * void or a boolean indicating the success of the call. + * @scope: A #GIScopeType. If the parameter is of a callback type, this denotes + * the scope of the user_data and the callback function pointer itself + * (for languages that emit code at run-time). * @skip: Indicates that the parameter is only useful in C and should be skipped. + * @reserved: Reserved for future use. + * @closure: Index of the closure (user_data) parameter associated with the + * callback, or -1. + * @destroy: Index of the destroy notfication callback parameter associated + * with the callback, or -1. + * @padding: TODO + * @arg_type: Describes the type of the parameter. See details below. * * Types are specified by four bytes. If the three high bytes are zero, * the low byte describes a basic type, otherwise the 32bit number is an @@ -428,15 +444,11 @@ typedef struct { guint return_value : 1; guint scope : 3; guint skip : 1; - /* */ guint reserved :20; - /* */ - gint8 closure; - gint8 destroy; + gint8 closure; + gint8 destroy; - /* */ - guint16 padding; - /* */ + guint16 padding; SimpleTypeBlob arg_type; } ArgBlob; @@ -444,17 +456,21 @@ typedef struct { /** * SignatureBlob: * @return_type: Describes the type of the return value. See details below. - * @may_return_null: Only relevant for pointer types. Indicates whether the caller - * must expect NULL as a return value. - * @caller_owns_return_value: If set, the caller is responsible for freeing the return value - * if it is no longer needed. - * @caller_owns_return_container: This flag is only relevant if the return type is a container type. - * If the flag is set, the caller is resonsible for freeing the - * container, but not its contents. - * @skip_return: Indicates that the return value is only useful in C and should be skipped. - * @n_arguments: The number of arguments that this function expects, also the length - * of the array of ArgBlobs. + * @may_return_null: Only relevant for pointer types. Indicates whether the + * caller must expect NULL as a return value. + * @caller_owns_return_value: If set, the caller is responsible for freeing + * the return value if it is no longer needed. + * @caller_owns_return_container: This flag is only relevant if the return type + * is a container type. If the flag is set, the caller is resonsible for + * freeing the container, but not its contents. + * @skip_return: Indicates that the return value is only useful in C and should + * be skipped. + * @reserved: Reserved for future use. + * @n_arguments: The number of arguments that this function expects, also the + * length of the array of ArgBlobs. * @arguments: An array of ArgBlob for the arguments of the function. + * + * TODO */ typedef struct { SimpleTypeBlob return_type; @@ -474,43 +490,50 @@ typedef struct { * CommonBlob: * @blob_type: A #GTypelibBlobType * @deprecated: Whether the blob is deprecated. + * @reserved: Reserved for future use. * @name: The name of the blob. * * The #CommonBlob is shared between #FunctionBlob, * #CallbackBlob, #SignalBlob. + * + * TODO */ typedef struct { guint16 blob_type; /* 1 */ guint16 deprecated : 1; - /* */ guint16 reserved :15; - /* */ guint32 name; } CommonBlob; /** * FunctionBlob: - * @blob_Type: #BLOB_TYPE_FUNCTION - * @symbol: The symbol which can be used to obtain the function pointer with - * dlsym(). + * @blob_type: #BLOB_TYPE_FUNCTION * @deprecated: The function is deprecated. * @setter: The function is a setter for a property. Language bindings may - * prefer to not bind individual setters and rely on the generic - * g_object_set(). + * prefer to not bind individual setters and rely on the generic + * g_object_set(). * @getter: The function is a getter for a property. Language bindings may - * prefer to not bind individual getters and rely on the generic - * g_object_get(). - * @constructor:The function acts as a constructor for the object it is contained - * in. + * prefer to not bind individual getters and rely on the generic + * g_object_get(). + * @constructor: The function acts as a constructor for the object it is + * contained in. * @wraps_vfunc: The function is a simple wrapper for a virtual function. + * @throws: TODO * @index: Index of the property that this function is a setter or getter of - * in the array of properties of the containing interface, or index - * of the virtual function that this function wraps. + * in the array of properties of the containing interface, or index + * of the virtual function that this function wraps. + * @name: TODO + * @symbol: The symbol which can be used to obtain the function pointer with + * dlsym(). * @signature: Offset of the SignatureBlob describing the parameter types and the - * return value type. + * return value type. * @is_static: The function is a "static method"; in other words it's a pure - * function whose name is conceptually scoped to the object. + * function whose name is conceptually scoped to the object. + * @reserved: Reserved for future use. + * @reserved2: Reserved for future use. + * + * TODO */ typedef struct { guint16 blob_type; /* 1 */ @@ -537,16 +560,20 @@ typedef struct { /** * CallbackBlob: - * @signature: Offset of the #SignatureBlob describing the parameter types and the - * return value type. + * @blob_type: TODO + * @deprecated: TODO + * @reserved: Reserved for future use. + * @name: TODO + * @signature: Offset of the #SignatureBlob describing the parameter types and + * the return value type. + * + * TODO */ typedef struct { guint16 blob_type; /* 2 */ guint16 deprecated : 1; - /* */ guint16 reserved :15; - /* */ guint32 name; guint32 signature; } CallbackBlob; @@ -554,41 +581,52 @@ typedef struct { /** * InterfaceTypeBlob: * @pointer: Whether this type represents an indirection + * @reserved: Reserved for future use. * @tag: A #GITypeTag + * @reserved2: Reserved for future use. * @interface: Index of the directory entry for the interface. * * If the interface is an enum of flags type, is_pointer is 0, otherwise it is 1. */ typedef struct { guint8 pointer :1; - /* */ guint8 reserved :2; - /* */ guint8 tag :5; - /* */ guint8 reserved2; - /* */ guint16 interface; } InterfaceTypeBlob; +/** + * ArrayTypeDimension: + * @length: TODO + * @size: TODO + * + * TODO + */ +typedef union { + guint16 length; + guint16 size; +} ArrayTypeDimension; + /** * ArrayTypeBlob: - * @zero_terminated: Indicates that the array must be terminated by a suitable #NULL - * value. - * @has_length: Indicates that length points to a parameter specifying the length - * of the array. If both has_length and zero_terminated are set, the - * convention is to pass -1 for the length if the array is - * zero-terminated. + * @pointer: TODO + * @reserved: Reserved for future use. + * @tag: TODO + * @zero_terminated: Indicates that the array must be terminated by a suitable + * #NULL value. + * @has_length: Indicates that length points to a parameter specifying the + * length of the array. If both has_length and zero_terminated are set, the + * convention is to pass -1 for the length if the array is zero-terminated. * @has_size: Indicates that size is the fixed size of the array. * @array_type: Indicates whether this is a C array, GArray, GPtrArray, or - * GByteArray. If something other than a C array, the length and element size - * are implicit in the structure. - * @length: The index of the parameter which is used to pass the length of the - * array. The parameter must be an integer type and have the same - * direction as this one. - * @size: The fixed size of the array. - * @type: The type of the array elements. - * Arrays are passed by reference, thus is_pointer is always 1. + * GByteArray. If something other than a C array, the length and element + * size are implicit in the structure. + * @reserved2: Reserved for future use. + * @dimensions: TODO + * @type: TODO + * + * TODO */ typedef struct { guint16 pointer :1; @@ -601,19 +639,21 @@ typedef struct { guint16 array_type :2; guint16 reserved2 :3; - union { - guint16 length; - guint16 size; - } dimensions; + ArrayTypeDimension dimensions; SimpleTypeBlob type; } ArrayTypeBlob; /** * ParamTypeBlob: + * @pointer: TODO + * @reserved: Reserved for future use. + * @tag: TODO + * @reserved2: Reserved for future use. * @n_types: The number of parameter types to follow. * @type: Describes the type of the list elements. * + * TODO */ typedef struct { guint8 pointer :1; @@ -628,6 +668,14 @@ typedef struct { /** * ErrorTypeBlob: + * @pointer: TODO + * @reserved: TODO + * @tag: TODO + * @reserved2: TODO + * @n_domains: TODO: must be 0 + * @domains: TODO + * + * TODO */ typedef struct { guint8 pointer :1; @@ -644,17 +692,16 @@ typedef struct { * ValueBlob: * @deprecated: Whether this value is deprecated * @unsigned_value: if set, value is a 32-bit unsigned integer cast to gint32 - * @value: The numerical value + * @reserved: Reserved for future use. * @name: Name of blob + * @value: The numerical value * * Values commonly occur in enums and flags. */ typedef struct { guint32 deprecated : 1; guint32 unsigned_value : 1; - /* */ guint32 reserved :30; - /* */ guint32 name; gint32 value; } ValueBlob; @@ -662,15 +709,18 @@ typedef struct { /** * FieldBlob: * @name: The name of the field. - * @readable: + * @readable: TODO * @writable: How the field may be accessed. * @has_embedded_type: An anonymous type follows the FieldBlob. + * @reserved: Reserved for future use. * @bits: If this field is part of a bitfield, the number of bits which it - * uses, otherwise 0. - * @struct_offset: - * The offset of the field in the struct. The value 0xFFFF indicates - * that the struct offset is unknown. + * uses, otherwise 0. + * @struct_offset: The offset of the field in the struct. The value 0xFFFF + * indicates that the struct offset is unknown. + * @reserved2: Reserved for future use. * @type: The type of the field. + * + * TODO */ typedef struct { guint32 name; @@ -690,8 +740,16 @@ typedef struct { /** * RegisteredTypeBlob: + * @blob_type: TODO + * @deprecated: TODO + * @unregistered: TODO + * @reserved: Reserved for future use. + * @name: TODO * @gtype_name: The name under which the type is registered with GType. - * @gtype_init: The symbol name of the get_type() function which registers the type. + * @gtype_init: The symbol name of the get_type() function which registers the + * type. + * + * TODO */ typedef struct { guint16 blob_type; @@ -709,16 +767,22 @@ typedef struct { * @blob_type: #BLOB_TYPE_STRUCT * @deprecated: Whether this structure is deprecated * @unregistered: If this is set, the type is not registered with GType. + * @is_gtype_struct: Whether this structure is the class or interface layout + * for a GObject * @alignment: The byte boundary that the struct is aligned to in memory - * @is_gtype_struct: Whether this structure is the class or interface layout for a GObject * @foreign: If the type is foreign, eg if it's expected to be overridden by - * a native language binding instead of relying of introspected bindings. - * @size: The size of the struct in bytes. + * a native language binding instead of relying of introspected bindings. + * @reserved: Reserved for future use. + * @name: TODO * @gtype_name: String name of the associated #GType * @gtype_init: String naming the symbol which gets the runtime #GType - * @n_fields: - * @fields: An array of n_fields FieldBlobs. - * should be considered as methods of the struct. + * @size: The size of the struct in bytes. + * @n_fields: TODO + * @n_methods: TODO + * @reserved2: Reserved for future use. + * @reserved3: Reserved for future use. + * + * TODO */ typedef struct { guint16 blob_type; @@ -742,29 +806,30 @@ typedef struct { guint32 reserved2; guint32 reserved3; - -#if 0 - /* variable-length parts of the blob */ - FieldBlob fields[]; - FunctionBlob methods[]; -#endif } StructBlob; /** * UnionBlob: + * @blob_type: TODO + * @deprecated: TODO * @unregistered: If this is set, the type is not registered with GType. * @discriminated: Is set if the union is discriminated * @alignment: The byte boundary that the union is aligned to in memory - * @size: The size of the union in bytes. + * @reserved: Reserved for future use. + * @name: TODO * @gtype_name: String name of the associated #GType * @gtype_init: String naming the symbol which gets the runtime #GType + * @size: TODO * @n_fields: Length of the arrays + * @n_functions: TODO + * @reserved2: Reserved for future use. + * @reserved3: Reserved for future use. * @discriminator_offset: Offset from the beginning of the union where the - * discriminator of a discriminated union is located. - * The value 0xFFFF indicates that the discriminator offset - * is unknown. + * discriminator of a discriminated union is located. The value 0xFFFF + * indicates that the discriminator offset is unknown. * @discriminator_type: Type of the discriminator - * @fields: Array of FieldBlobs describing the alternative branches of the union + * + * TODO */ typedef struct { guint16 blob_type; @@ -788,27 +853,25 @@ typedef struct { gint32 discriminator_offset; SimpleTypeBlob discriminator_type; - -#if 0 - FieldBlob fields[]; - FunctionBlob functions[]; - ConstantBlob discriminator_values[] -#endif } UnionBlob; /** * EnumBlob: + * @blob_type: TODO + * @deprecated: TODO * @unregistered: If this is set, the type is not registered with GType. * @storage_type: The tag of the type used for the enum in the C ABI - * (will be a signed or unsigned integral type) + * (will be a signed or unsigned integral type) + * @reserved: Reserved for future use. + * @name: TODO * @gtype_name: String name of the associated #GType * @gtype_init: String naming the symbol which gets the runtime #GType - * @error_domain: String naming the #GError domain this enum is - * associated with * @n_values: The length of the values array. * @n_methods: The length of the methods array. - * @values: Describes the enum values. - * @methods: Describes the enum methods. + * @error_domain: String naming the #GError domain this enum is associated with + * @values: TODO + * + * TODO */ typedef struct { guint16 blob_type; @@ -829,25 +892,28 @@ typedef struct { guint32 error_domain; ValueBlob values[]; -#if 0 - FunctionBlob methods[]; -#endif } EnumBlob; /** * PropertyBlob: - * @name: The name of the property. - * @readable: - * @writable: - * @construct: + * @name: The name of the property. + * @deprecated: TODO + * @readable: TODO + * @writable: TODO + * @construct: TODO * @construct_only: The ParamFlags used when registering the property. * @transfer_ownership: When writing, the type containing the property takes - * ownership of the value. When reading, the returned value needs to be released - * by the caller. + * ownership of the value. When reading, the returned value needs to be + * released by the caller. * @transfer_container_ownership: For container types indicates that the - * ownership of the container, but not of its contents, is transferred. This is - * typically the case when reading lists of statically allocated things. + * ownership of the container, but not of its contents, is transferred. + * This is typically the case when reading lists of statically allocated + * things. + * @reserved: Reserved for future use. + * @reserved2: Reserved for future use. * @type: Describes the type of the property. + * + * TODO */ typedef struct { guint32 name; @@ -868,20 +934,25 @@ typedef struct { /** * SignalBlob: - * @name: The name of the signal. - * @run_first: - * @run_last: - * @run_cleanup: - * @no_recurse: - * @detailed: - * @action: + * @deprecated: TODO + * @run_first: TODO + * @run_last: TODO + * @run_cleanup: TODO + * @no_recurse: TODO + * @detailed: TODO + * @action: TODO * @no_hooks: The flags used when registering the signal. * @has_class_closure: Set if the signal has a class closure. * @true_stops_emit: Whether the signal has true-stops-emit semantics - * @class_closure: The index of the class closure in the list of virtual functions - * of the object or interface on which the signal is defined. - * @signature: Offset of the SignatureBlob describing the parameter types and the - * return value type. + * @reserved: Reserved for future use. + * @class_closure: The index of the class closure in the list of virtual + * functions of the object or interface on which the signal is defined. + * @name: The name of the signal. + * @reserved2: Reserved for future use. + * @signature: Offset of the SignatureBlob describing the parameter types + * and the return value type. + * + * TODO */ typedef struct { guint16 deprecated : 1; @@ -909,19 +980,28 @@ typedef struct { * VFuncBlob: * @name: The name of the virtual function. * @must_chain_up: If set, every implementation of this virtual function must - * chain up to the implementation of the parent class. - * @must_be_implemented: If set, every derived class must override this virtual function. - * @must_not_be_implemented: If set, derived class must not override this virtual function. - * @class_closure: Set if this virtual function is the class closure of a signal. + * chain up to the implementation of the parent class. + * @must_be_implemented: If set, every derived class must override this virtual + * function. + * @must_not_be_implemented: If set, derived class must not override this + * virtual function. + * @class_closure: Set if this virtual function is the class closure of a + * signal. + * @throws: TODO + * @reserved: Reserved for future use. * @signal: The index of the signal in the list of signals of the object or - * interface to which this virtual function belongs. - * @struct_offset: The offset of the function pointer in the class struct. The value - * 0xFFFF indicates that the struct offset is unknown. - * @invoker: If a method invoker for this virtual exists, this is the offset in the - * class structure of the method. If no method is known, this value will be 0x3ff. - * @signature: - * Offset of the SignatureBlob describing the parameter types and the - * return value type. + * interface to which this virtual function belongs. + * @struct_offset: The offset of the function pointer in the class struct. + * The value 0xFFFF indicates that the struct offset is unknown. + * @invoker: If a method invoker for this virtual exists, this is the offset + * in the class structure of the method. If no method is known, this value + * will be 0x3ff. + * @reserved2: Reserved for future use. + * @reserved3: Reserved for future use. + * @signature: Offset of the SignatureBlob describing the parameter types and + * the return value type. + * + * TODO */ typedef struct { guint32 name; @@ -945,36 +1025,41 @@ typedef struct { /** * ObjectBlob: * @blob_type: #BLOB_TYPE_OBJECT + * @deprecated: TODO + * @abstract: TODO * @fundamental: this object is not a GObject derived type, instead it's - * an additional fundamental type. + * an additional fundamental type. + * @reserved: Reserved for future use. + * @name: TODO * @gtype_name: String name of the associated #GType * @gtype_init: String naming the symbol which gets the runtime #GType * @parent: The directory index of the parent type. This is only set for - * objects. If an object does not have a parent, it is zero. - * @n_interfaces: - * @n_fields: - * @n_properties: - * @n_methods: - * @n_signals: - * @n_vfuncs: - * @n_constants: The lengths of the arrays.Up to 16bits of padding may be inserted - * between the arrays to ensure that they start on a 32bit boundary. - * @interfaces: An array of indices of directory entries for the implemented - * interfaces. - * @fields: Describes the fields. - * @methods: Describes the methods, constructors, setters and getters. - * @properties: Describes the properties. - * @signals: Describes the signals. - * @vfuncs: Describes the virtual functions. - * @constants: Describes the constants. + * objects. If an object does not have a parent, it is zero. + * @gtype_struct: TODO + * @n_interfaces: TODO + * @n_fields: TODO + * @n_properties: TODO + * @n_methods: TODO + * @n_signals: TODO + * @n_vfuncs: TODO + * @n_constants: The lengths of the arrays.Up to 16bits of padding may be + * inserted between the arrays to ensure that they start on a 32bit + * boundary. + * @reserved2: Reserved for future use. * @ref_func: String pointing to a function which can be called to increase - * the reference count for an instance of this object type. + * the reference count for an instance of this object type. * @unref_func: String pointing to a function which can be called to decrease - * the reference count for an instance of this object type. + * the reference count for an instance of this object type. * @set_value_func: String pointing to a function which can be called to - * convert a pointer of this object to a GValue + * convert a pointer of this object to a GValue * @get_value_func: String pointing to a function which can be called to - * convert extract a pointer to this object from a GValue + * convert extract a pointer to this object from a GValue + * @reserved3: Reserved for future use. + * @reserved4: Reserved for future use. + * @interfaces: An array of indices of directory entries for the implemented + * interfaces. + * + * TODO */ typedef struct { guint16 blob_type; /* 7 */ @@ -1008,35 +1093,32 @@ typedef struct { guint32 reserved4; guint16 interfaces[]; - -#if 0 - /* variable-length parts of the blob */ - FieldBlob fields[]; - PropertyBlob properties[]; - FunctionBlob methods[]; - SignalBlob signals[]; - VFuncBlob vfuncs[]; - ConstantBlob constants[]; -#endif } ObjectBlob; /** * InterfaceBlob: + * @blob_type: TODO + * @deprecated: TODO + * @reserved: Reserved for future use. + * @name: TODO + * @gtype_name: TODO + * @gtype_init: TODO * @gtype_struct: Name of the interface "class" C structure * @n_prerequisites: Number of prerequisites * @n_properties: Number of properties * @n_methods: Number of methods * @n_signals: Number of signals * @n_vfuncs: Number of virtual functions - * @n_constants: The lengths of the arrays. - * Up to 16bits of padding may be inserted between the arrays to ensure that they - * start on a 32bit boundary. - * @prerequisites: An array of indices of directory entries for required interfaces. - * @methods: Describes the methods, constructors, setters and getters. - * @properties: Describes the properties. - * @signals: Describes the signals. - * @vfuncs: Describes the virtual functions. - * @constants: Describes the constants. + * @n_constants: The lengths of the arrays. Up to 16bits of padding may be + * inserted between the arrays to ensure that they start on a 32bit + * boundary. + * @padding: TODO + * @reserved2: Reserved for future use. + * @reserved3: Reserved for future use. + * @prerequisites: An array of indices of directory entries for required + * interfaces. + * + * TODO */ typedef struct { guint16 blob_type; @@ -1061,23 +1143,21 @@ typedef struct { guint32 reserved3; guint16 prerequisites[]; - -#if 0 - /* variable-length parts of the blob */ - PropertyBlob properties[]; - FunctionBlob methods[]; - SignalBlob signals[]; - VFuncBlob vfuncs[]; - ConstantBlob constants[]; -#endif } InterfaceBlob; /** * ConstantBlob: - * @type: The type of the value. In most cases this should be a numeric - * type or string. + * @blob_type: TODO + * @deprecated: TODO + * @reserved: Reserved for future use. + * @name: TODO + * @type: The type of the value. In most cases this should be a numeric type + * or string. * @size: The size of the value in bytes. * @offset: The offset of the value in the typelib. + * @reserved2: Reserved for future use. + * + * TODO */ typedef struct { guint16 blob_type; @@ -1096,10 +1176,12 @@ typedef struct { /** * AttributeBlob: * @offset: The offset of the typelib entry to which this attribute refers. - * Attributes are kept sorted by offset, so that the attributes - * of an entry can be found by a binary search. + * Attributes are kept sorted by offset, so that the attributes of an + * entry can be found by a binary search. * @name: The name of the attribute, a string. * @value: The value of the attribute (also a string) + * + * TODO */ typedef struct { guint32 offset; @@ -1107,9 +1189,6 @@ typedef struct { guint32 value; } AttributeBlob; -/** - * GITypelib: - */ struct _GITypelib { /* */ guchar *data; @@ -1137,6 +1216,15 @@ gboolean g_typelib_matches_gtype_name_prefix (GITypelib *typelib, void g_typelib_check_sanity (void); +/** + * g_typelib_get_string: + * @typelib: TODO + * @offset: TODO + * + * TODO + * + * Returns: TODO + */ #define g_typelib_get_string(typelib,offset) ((const gchar*)&(typelib->data)[(offset)]) @@ -1159,6 +1247,11 @@ typedef enum G_TYPELIB_ERROR_INVALID_BLOB } GITypelibError; +/** + * G_TYPELIB_ERROR: + * + * TODO + */ #define G_TYPELIB_ERROR (g_typelib_error_quark ()) GQuark g_typelib_error_quark (void); @@ -1171,6 +1264,11 @@ gboolean g_typelib_validate (GITypelib *typelib, AttributeBlob *_attribute_blob_find_first (GIBaseInfo *info, guint32 blob_offset); +/** + * GITypelibHashBuilder: + * + * TODO + */ typedef struct _GITypelibHashBuilder GITypelibHashBuilder; GITypelibHashBuilder * _gi_typelib_hash_builder_new (void); diff --git a/gitypelib.c b/gitypelib.c index 1436caf1e..8883496e3 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -130,6 +130,15 @@ get_type_blob (GITypelib *typelib, return (InterfaceTypeBlob*) get_blob (typelib, simple->offset, error); } +/** + * g_typelib_get_dir_entry: + * @typelib: TODO + * @index: TODO + * + * TODO + * + * Returns: TODO + */ DirEntry * g_typelib_get_dir_entry (GITypelib *typelib, guint16 index) @@ -159,6 +168,15 @@ get_section_by_id (GITypelib *typelib, return NULL; } +/** + * g_typelib_get_dir_entry_by_name: + * @typelib: TODO + * @name: TODO + * + * TODO + * + * Returns: TODO + */ DirEntry * g_typelib_get_dir_entry_by_name (GITypelib *typelib, const char *name) @@ -196,6 +214,15 @@ g_typelib_get_dir_entry_by_name (GITypelib *typelib, } } +/** + * g_typelib_get_dir_entry_by_gtype_name: + * @typelib: TODO + * @gtype_name: TODO + * + * TODO + * + * Returns: TODO + */ DirEntry * g_typelib_get_dir_entry_by_gtype_name (GITypelib *typelib, const gchar *gtype_name) @@ -281,6 +308,15 @@ strsplit_iter_clear (StrSplitIter *iter) g_free (iter->buf.str); } +/** + * g_typelib_matches_gtype_name_prefix: + * @typelib: TODO + * @gtype_name: TODO + * + * TODO + * + * Returns: TODO + */ gboolean g_typelib_matches_gtype_name_prefix (GITypelib *typelib, const gchar *gtype_name) @@ -326,6 +362,15 @@ g_typelib_matches_gtype_name_prefix (GITypelib *typelib, return ret; } +/** + * g_typelib_get_dir_entry_by_error_domain: + * @typelib: TODO + * @error_domain: TODO + * + * TODO + * + * Returns: TODO + */ DirEntry * g_typelib_get_dir_entry_by_error_domain (GITypelib *typelib, GQuark error_domain) @@ -356,6 +401,11 @@ g_typelib_get_dir_entry_by_error_domain (GITypelib *typelib, return NULL; } +/** + * g_typelib_check_sanity: + * + * TODO + */ void g_typelib_check_sanity (void) { @@ -2089,6 +2139,15 @@ prefix_with_context (GError **error, g_free (buf); } +/** + * g_typelib_validate: + * @typelib: TODO + * @error: TODO + * + * TODO + * + * Returns: TODO + */ gboolean g_typelib_validate (GITypelib *typelib, GError **error) @@ -2118,6 +2177,13 @@ g_typelib_validate (GITypelib *typelib, return TRUE; } +/** + * g_typelib_error_quark: + * + * TODO + * + * Returns: TODO + */ GQuark g_typelib_error_quark (void) { @@ -2271,8 +2337,8 @@ _g_typelib_ensure_open (GITypelib *typelib) * pointed to by @typelib will be automatically g_free()d when the * repository is destroyed. * - * Return value: the new #GITypelib - **/ + * Returns: the new #GITypelib + */ GITypelib * g_typelib_new_from_memory (guint8 *memory, gsize len, @@ -2300,8 +2366,8 @@ g_typelib_new_from_memory (guint8 *memory, * * Creates a new #GITypelib from a memory location. * - * Return value: the new #GITypelib - **/ + * Returns: the new #GITypelib + */ GITypelib * g_typelib_new_from_const_memory (const guchar *memory, gsize len, @@ -2328,8 +2394,8 @@ g_typelib_new_from_const_memory (const guchar *memory, * * Creates a new #GITypelib from a #GMappedFile. * - * Return value: the new #GITypelib - **/ + * Returns: the new #GITypelib + */ GITypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile, GError **error) @@ -2355,7 +2421,7 @@ g_typelib_new_from_mapped_file (GMappedFile *mfile, * @typelib: a #GITypelib * * Free a #GITypelib. - **/ + */ void g_typelib_free (GITypelib *typelib) { @@ -2372,6 +2438,14 @@ g_typelib_free (GITypelib *typelib) g_slice_free (GITypelib, typelib); } +/** + * g_typelib_get_namespace: + * @typelib: TODO + * + * TODO + * + * Returns: TODO + */ const gchar * g_typelib_get_namespace (GITypelib *typelib) { @@ -2386,8 +2460,8 @@ g_typelib_get_namespace (GITypelib *typelib) * * Loads a symbol from #GITypelib. * - * Return value: #TRUE on success - **/ + * Returns: #TRUE on success + */ gboolean g_typelib_symbol (GITypelib *typelib, const char *symbol_name, gpointer *symbol) { diff --git a/gitypelib.h b/gitypelib.h index 52c5c4006..0726bf19b 100644 --- a/gitypelib.h +++ b/gitypelib.h @@ -31,6 +31,19 @@ G_BEGIN_DECLS +/** + * SECTION:gitypelib + * @title: gitypelib + * @short_description: TODO + * + * TODO + */ + +/** + * GITypelib: + * + * TODO + */ typedef struct _GITypelib GITypelib; GITypelib * g_typelib_new_from_memory (guint8 *memory, diff --git a/gitypes.h b/gitypes.h index 660a98f95..cb8cb344a 100644 --- a/gitypes.h +++ b/gitypes.h @@ -29,7 +29,9 @@ G_BEGIN_DECLS +#ifndef __GTK_DOC_IGNORE__ typedef struct _GIBaseInfoStub GIBaseInfo; +#endif /** * GICallableInfo: @@ -46,6 +48,25 @@ typedef GIBaseInfo GICallableInfo; */ typedef GIBaseInfo GIFunctionInfo; +/** + * SECTION:gicallbackinfo + * @title: GICallbackInfo + * @short_description: Struct representing a callback + * + * GICallbackInfo represents a callback. + * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GICallableInfo + * +----GIFunctionInfo + * +----GISignalInfo + * +----GIVFuncInfo + * + * + */ + /** * GICallbackInfo: * @@ -102,6 +123,22 @@ typedef GIBaseInfo GIInterfaceInfo; */ typedef GIBaseInfo GIConstantInfo; +/** + * SECTION:givalueinfo + * @title: GIValueInfo + * @short_description: Struct representing a value + * + * GIValueInfo represents a value. + * + * + * Struct hierarchy + * + * GIBaseInfo + * +----GIValueInfo + * + * + */ + /** * GIValueInfo: * @@ -158,12 +195,7 @@ typedef GIBaseInfo GITypeInfo; */ typedef struct _GIUnresolvedInfo GIUnresolvedInfo; -/** - * GIArgument: - * - * Stores an argument of varying type - */ -typedef union +union _GIArgument { gboolean v_boolean; gint8 v_int8; @@ -186,7 +218,35 @@ typedef union gsize v_size; gchar * v_string; gpointer v_pointer; -} GIArgument; +}; + +/** + * GIArgument: + * @v_boolean: TODO + * @v_int8: TODO + * @v_uint8: TODO + * @v_int16: TODO + * @v_uint16: TODO + * @v_int32: TODO + * @v_uint32: TODO + * @v_int64: TODO + * @v_uint64: TODO + * @v_float: TODO + * @v_double: TODO + * @v_short: TODO + * @v_ushort: TODO + * @v_int: TODO + * @v_uint: TODO + * @v_long: TODO + * @v_ulong: TODO + * @v_ssize: TODO + * @v_size: TODO + * @v_string: TODO + * @v_pointer: TODO + * + * Stores an argument of varying type + */ +typedef union _GIArgument GIArgument; /** * GIInfoType: @@ -200,6 +260,7 @@ typedef union * @GI_INFO_TYPE_OBJECT: object, see #GIObjectInfo * @GI_INFO_TYPE_INTERFACE: interface, see #GIInterfaceInfo * @GI_INFO_TYPE_CONSTANT: contant, see #GIConstantInfo + * @GI_INFO_TYPE_INVALID_0: deleted, used to be GI_INFO_TYPE_ERROR_DOMAIN. * @GI_INFO_TYPE_UNION: union, see #GIUnionInfo * @GI_INFO_TYPE_VALUE: enum value, see #GIValueInfo * @GI_INFO_TYPE_SIGNAL: signal, see #GISignalInfo @@ -209,7 +270,7 @@ typedef union * @GI_INFO_TYPE_ARG: argument of a function or callback, see #GIArgInfo * @GI_INFO_TYPE_TYPE: type information, see #GITypeInfo * @GI_INFO_TYPE_UNRESOLVED: unresolved type, a type which is not present in - * the typelib, or any of its dependencies. + * the typelib, or any of its dependencies. * * The type of a GIBaseInfo struct. */ @@ -225,7 +286,7 @@ typedef enum GI_INFO_TYPE_OBJECT, GI_INFO_TYPE_INTERFACE, GI_INFO_TYPE_CONSTANT, - GI_INFO_TYPE_INVALID_0, /* 10 */ /* DELETED - used to be ERROR_DOMAIN */ + GI_INFO_TYPE_INVALID_0, /* 10 */ GI_INFO_TYPE_UNION, GI_INFO_TYPE_VALUE, GI_INFO_TYPE_SIGNAL, @@ -319,17 +380,17 @@ typedef enum { * @GI_TYPE_TAG_UINT64: 64-bit unsigned integer * @GI_TYPE_TAG_FLOAT: float * @GI_TYPE_TAG_DOUBLE: double floating point - * @GI_TYPE_TAG_UNICHAR: Unicode character * @GI_TYPE_TAG_GTYPE: a #GType * @GI_TYPE_TAG_UTF8: a UTF-8 encoded string * @GI_TYPE_TAG_FILENAME: a filename, encoded in the same encoding - * as the native filesystem is using. + * as the native filesystem is using. * @GI_TYPE_TAG_ARRAY: an array * @GI_TYPE_TAG_INTERFACE: an extended interface object * @GI_TYPE_TAG_GLIST: a #GList * @GI_TYPE_TAG_GSLIST: a #GSList * @GI_TYPE_TAG_GHASH: a #GHashTable * @GI_TYPE_TAG_ERROR: a #GError + * @GI_TYPE_TAG_UNICHAR: Unicode character * * The type tag of a #GITypeInfo. */ @@ -359,12 +420,17 @@ typedef enum { GI_TYPE_TAG_ERROR = 20, /* Another basic type */ GI_TYPE_TAG_UNICHAR = 21 - /* Note - there is only room currently for 32 tags. - * See docs/typelib-format.txt SimpleTypeBlob definition */ + /* Note - there is currently only room for 32 tags */ } GITypeTag; +/** + * GI_TYPE_TAG_N_TYPES: + * + * TODO + */ #define GI_TYPE_TAG_N_TYPES (GI_TYPE_TAG_UNICHAR+1) +#ifndef __GTK_DOC_IGNORE__ /* These were removed and no longer appear in the typelib; * instead, the machine-specific versions like INT32 are * always used. @@ -372,6 +438,7 @@ typedef enum { #define GI_TYPE_TAG_SHORT GI_TYPE_TAG_SHORT_WAS_REMOVED #define GI_TYPE_TAG_INT GI_TYPE_TAG_INT_WAS_REMOVED #define GI_TYPE_TAG_LONG GI_TYPE_TAG_LONG_WAS_REMOVED +#endif /** * GIArrayType: @@ -442,10 +509,12 @@ typedef enum } GIFunctionInfoFlags; #ifndef __GI_SCANNER__ +#ifndef __GTK_DOC_IGNORE__ /* backwards compatibility */ typedef GIArgument GArgument; typedef struct _GITypelib GTypelib; #endif +#endif G_END_DECLS diff --git a/giunioninfo.c b/giunioninfo.c index 95b71123f..8ae1e915b 100644 --- a/giunioninfo.c +++ b/giunioninfo.c @@ -28,8 +28,8 @@ /** * SECTION:giunioninfo - * @Short_description: Struct representing a union. - * @Title: GIUnionInfo + * @title: GIUnionInfo + * @short_description: Struct representing a union. * * GIUnionInfo represents a union type. * @@ -147,7 +147,7 @@ g_union_info_is_discriminated (GIUnionInfo *info) } /** - * g_union_info_get_discrimintor_offset: + * g_union_info_get_discriminator_offset: * @info: a #GIUnionInfo * * Returns offset of the discriminator field in the structure. diff --git a/giunioninfo.h b/giunioninfo.h index 83696f765..5359346af 100644 --- a/giunioninfo.h +++ b/giunioninfo.h @@ -31,6 +31,12 @@ G_BEGIN_DECLS +/** + * GI_IS_UNION_INFO + * @info: an info structure + * + * Checks if @info is a #GIUnionInfo. + */ #define GI_IS_UNION_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_UNION) diff --git a/givfuncinfo.c b/givfuncinfo.c index 9d6ea39db..eaf523d2a 100644 --- a/givfuncinfo.c +++ b/givfuncinfo.c @@ -30,8 +30,8 @@ /** * SECTION:givfuncinfo - * @Short_description: Struct representing a virtual function - * @Title: GIVFuncInfo + * @title: GIVFuncInfo + * @short_description: Struct representing a virtual function * * GIVfuncInfo represents a virtual function. A property belongs to * either a #GIObjectInfo or a #GIInterfaceInfo. diff --git a/givfuncinfo.h b/givfuncinfo.h index d8a8533b8..f22517a6e 100644 --- a/givfuncinfo.h +++ b/givfuncinfo.h @@ -31,6 +31,12 @@ G_BEGIN_DECLS +/** + * GI_IS_VFUNC_INFO + * @info: an info structure + * + * Checks if @info is a #GIVfuncInfo. + */ #define GI_IS_VFUNC_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_VFUNC) From 67358cdaf4ae223a31985da58827d84e9f956f10 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Sun, 13 Oct 2013 02:02:22 +0200 Subject: [PATCH 524/692] GIVFuncInfo: allow retrieving the address of an interface vfunc Don't assume that the parent of a GIVFuncInfo is a GIObjectInfo, it could be a GIInterfaceInfo, if the vfunc is part of interface instead of a class. https://bugzilla.gnome.org/show_bug.cgi?id=688375 --- givfuncinfo.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/givfuncinfo.c b/givfuncinfo.c index eaf523d2a..8a5b71a17 100644 --- a/givfuncinfo.c +++ b/givfuncinfo.c @@ -216,15 +216,28 @@ g_vfunc_info_get_address (GIVFuncInfo *vfunc_info, GType implementor_gtype, GError **error) { + GIBaseInfo *container_info; + GIInterfaceInfo *interface_info; GIObjectInfo *object_info; GIStructInfo *struct_info; GIFieldInfo *field_info = NULL; int length, i, offset; - gpointer implementor_vtable; + gpointer implementor_class, implementor_vtable; gpointer func = NULL; - object_info = (GIObjectInfo *) g_base_info_get_container (vfunc_info); - struct_info = g_object_info_get_class_struct (object_info); + container_info = g_base_info_get_container (vfunc_info); + if (g_base_info_get_type (container_info) == GI_INFO_TYPE_OBJECT) + { + object_info = (GIObjectInfo*) container_info; + interface_info = NULL; + struct_info = g_object_info_get_class_struct (object_info); + } + else + { + interface_info = (GIInterfaceInfo*) container_info; + object_info = NULL; + struct_info = g_interface_info_get_iface_struct (interface_info); + } length = g_struct_info_get_n_fields (struct_info); for (i = 0; i < length; i++) @@ -250,10 +263,23 @@ g_vfunc_info_get_address (GIVFuncInfo *vfunc_info, goto out; } - implementor_vtable = g_type_class_ref (implementor_gtype); + implementor_class = g_type_class_ref (implementor_gtype); + + if (object_info) + { + implementor_vtable = implementor_class; + } + else + { + GType interface_type; + + interface_type = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo*) interface_info); + implementor_vtable = g_type_interface_peek (implementor_class, interface_type); + } + offset = g_field_info_get_offset (field_info); func = *(gpointer*) G_STRUCT_MEMBER_P (implementor_vtable, offset); - g_type_class_unref (implementor_vtable); + g_type_class_unref (implementor_class); g_base_info_unref (field_info); if (func == NULL) From 4dfcf7bc21c57f89b770741c248f79d54066c2ea Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Wed, 6 Nov 2013 11:37:50 +0000 Subject: [PATCH 525/692] =?UTF-8?q?girnode:=20Fix=20a=20NULL=20pointer=20d?= =?UTF-8?q?eference=20if=20a=20namespace=20can=E2=80=99t=20be=20found?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://bugzilla.gnome.org/show_bug.cgi?id=711541 --- girnode.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/girnode.c b/girnode.c index afb71e578..436147420 100644 --- a/girnode.c +++ b/girnode.c @@ -1151,6 +1151,10 @@ _g_ir_find_node (GIrTypelibBuild *build, target_name = names[1]; } + /* find_namespace() may return NULL. */ + if (target_module == NULL) + goto done; + for (l = target_module->entries; l; l = l->next) { GIrNode *node = (GIrNode *)l->data; @@ -1162,6 +1166,7 @@ _g_ir_find_node (GIrTypelibBuild *build, } } +done: g_strfreev (names); return return_node; From eb6b6f4fd518e506f0c900e2249e0458ff7d6bcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 29 Nov 2013 01:12:40 +0100 Subject: [PATCH 526/692] scanner: Support boolean constants Aliasing TRUE or FALSE is not very common, but done occasionally for extra clarity. Namely G_SOURCE_REMOVE / G_SOURCE_CONTINUE are self-explanatory, unlike the "raw" booleans. https://bugzilla.gnome.org/show_bug.cgi?id=719566 --- girnode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/girnode.c b/girnode.c index 436147420..093a37836 100644 --- a/girnode.c +++ b/girnode.c @@ -1010,10 +1010,10 @@ parse_float_value (const gchar *str) static gboolean parse_boolean_value (const gchar *str) { - if (strcmp (str, "TRUE") == 0) + if (g_ascii_strcasecmp (str, "TRUE") == 0) return TRUE; - if (strcmp (str, "FALSE") == 0) + if (g_ascii_strcasecmp (str, "FALSE") == 0) return FALSE; return parse_int_value (str) ? TRUE : FALSE; From f76e4ef683dcc4f64fa4684ed4be96841fc73023 Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Sat, 28 Dec 2013 19:37:18 -0500 Subject: [PATCH 527/692] typelib compiler: properly initialise memory The typelib compiler was writing uninitialised memory to the output file. There were two sources of this uninitialised memory: the hash writer included some uninitialised memory in its output, and the bytes added after the hash output for padding were also not being initialised. Fix this by passing the padded size to the hash code writer function and having that function initialise the entire memory region to zero before writing. https://bugzilla.gnome.org/show_bug.cgi?id=721177 --- girmodule.c | 3 ++- gthash.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/girmodule.c b/girmodule.c index 05c8987fc..e3897c34d 100644 --- a/girmodule.c +++ b/girmodule.c @@ -279,8 +279,9 @@ add_directory_index_section (guint8 *data, GIrModule *module, guint32 *offset2) alloc_section (data, GI_SECTION_DIRECTORY_INDEX, *offset2); required_size = _gi_typelib_hash_builder_get_buffer_size (dirindex_builder); + required_size = ALIGN_VALUE (required_size, 4); - new_offset = *offset2 + ALIGN_VALUE (required_size, 4); + new_offset = *offset2 + required_size; data = g_realloc (data, new_offset); diff --git a/gthash.c b/gthash.c index ecc3b1040..831c87e97 100644 --- a/gthash.c +++ b/gthash.c @@ -158,6 +158,8 @@ _gi_typelib_hash_builder_pack (GITypelibHashBuilder *builder, guint8* mem, guint g_assert (len >= builder->packed_size); g_assert ((((unsigned long)mem) & 0x3) == 0); + memset (mem, 0, len); + *((guint32*) mem) = builder->dirmap_offset; packed_mem = (guint8*)(mem + sizeof(guint32)); cmph_pack (builder->c, packed_mem); From 90a99b4fcc054978505f81fb4def02cc766039b1 Mon Sep 17 00:00:00 2001 From: Rico Tzschichholz Date: Thu, 23 Jan 2014 17:19:41 +0100 Subject: [PATCH 528/692] giobjectinfo: Add missing transfer annotation to find_signal () --- giobjectinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/giobjectinfo.c b/giobjectinfo.c index b0aff37cd..3e3b312c2 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -536,7 +536,7 @@ g_object_info_get_signal (GIObjectInfo *info, * * TODO * - * Returns: Info for the signal with name @name in @info, or %NULL on failure. + * Returns: (transfer full): Info for the signal with name @name in @info, or %NULL on failure. */ GISignalInfo * g_object_info_find_signal (GIObjectInfo *info, From cf4fb6a0fe19c8f071e2c72758d3fcc980e3d98f Mon Sep 17 00:00:00 2001 From: Simon Feltman Date: Thu, 27 Feb 2014 02:05:54 -0800 Subject: [PATCH 529/692] g-ir-compiler: Add support for callback fields on GObjects Use ParseState enum instead of a boolean for the ParseContexts embedded_type flag. This allows specific tracking of the embedded type currently being parsed which can now either be STATE_STRUCT_FIELD or STATE_CLASS_FIELD (or allow for future expansion). Add ParseState::STATE_NONE as the default for this field. Fix GObject FieldBlob validation to take into account the sizeof CallbackBlobs (copied from the struct validator). Add static g_object_info_get_field_offset which parallels g_struct_info_get_field_offset which is needed since callback fields may vary in size. https://bugzilla.gnome.org/show_bug.cgi?id=725198 --- giobjectinfo.c | 71 +++++++++++++++++++++++++++++--------------------- girparser.c | 41 +++++++++++++++-------------- gitypelib.c | 9 ++++++- 3 files changed, 71 insertions(+), 50 deletions(-) diff --git a/giobjectinfo.c b/giobjectinfo.c index 3e3b312c2..d92a86151 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -47,6 +47,40 @@ * */ +/** + * g_object_info_get_field_offset: + * @info: a #GIObjectInfo + * @n: index of queried field + * + * Obtain the offset of the specified field. + * + * Returns: field offset in bytes + */ +static gint32 +g_object_info_get_field_offset (GIObjectInfo *info, + gint n) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + Header *header = (Header *)rinfo->typelib->data; + ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; + guint32 offset; + gint i; + FieldBlob *field_blob; + + offset = rinfo->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2; + + for (i = 0; i < n; i++) + { + field_blob = (FieldBlob *)&rinfo->typelib->data[offset]; + offset += header->field_blob_size; + if (field_blob->has_embedded_type) + offset += header->callback_blob_size; + } + + return offset; +} + /** * g_object_info_get_parent: * @info: a #GIObjectInfo @@ -251,18 +285,11 @@ g_object_info_get_field (GIObjectInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header; - ObjectBlob *blob; g_return_val_if_fail (info != NULL, NULL); g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL); - header = (Header *)rinfo->typelib->data; - blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - - offset = rinfo->offset + header->object_blob_size - + (blob->n_interfaces + blob->n_interfaces % 2) * 2 - + n * header->field_blob_size; + offset = g_object_info_get_field_offset(info, n); return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, offset); } @@ -313,9 +340,7 @@ g_object_info_get_property (GIObjectInfo *info, header = (Header *)rinfo->typelib->data; blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = rinfo->offset + header->object_blob_size - + (blob->n_interfaces + blob->n_interfaces % 2) * 2 - + blob->n_fields * header->field_blob_size + offset = g_object_info_get_field_offset(info, blob->n_fields) + n * header->property_blob_size; return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info, @@ -370,9 +395,7 @@ g_object_info_get_method (GIObjectInfo *info, blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = rinfo->offset + header->object_blob_size - + (blob->n_interfaces + blob->n_interfaces % 2) * 2 - + blob->n_fields * header->field_blob_size + offset = g_object_info_get_field_offset(info, blob->n_fields) + blob->n_properties * header->property_blob_size + n * header->function_blob_size; @@ -406,9 +429,7 @@ g_object_info_find_method (GIObjectInfo *info, header = (Header *)rinfo->typelib->data; blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = rinfo->offset + header->object_blob_size - + (blob->n_interfaces + blob->n_interfaces % 2) * 2 - + blob->n_fields * header->field_blob_size + + offset = g_object_info_get_field_offset(info, blob->n_fields) + blob->n_properties * header->property_blob_size; return _g_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_methods, name); @@ -518,9 +539,7 @@ g_object_info_get_signal (GIObjectInfo *info, header = (Header *)rinfo->typelib->data; blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = rinfo->offset + header->object_blob_size - + (blob->n_interfaces + blob->n_interfaces % 2) * 2 - + blob->n_fields * header->field_blob_size + offset = g_object_info_get_field_offset(info, blob->n_fields) + blob->n_properties * header->property_blob_size + blob->n_methods * header->function_blob_size + n * header->signal_blob_size; @@ -609,9 +628,7 @@ g_object_info_get_vfunc (GIObjectInfo *info, header = (Header *)rinfo->typelib->data; blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = rinfo->offset + header->object_blob_size - + (blob->n_interfaces + blob->n_interfaces % 2) * 2 - + blob->n_fields * header->field_blob_size + offset = g_object_info_get_field_offset(info, blob->n_fields) + blob->n_properties * header->property_blob_size + blob->n_methods * header->function_blob_size + blob->n_signals * header->signal_blob_size @@ -652,9 +669,7 @@ g_object_info_find_vfunc (GIObjectInfo *info, header = (Header *)rinfo->typelib->data; blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = rinfo->offset + header->object_blob_size - + (blob->n_interfaces + blob->n_interfaces % 2) * 2 - + blob->n_fields * header->field_blob_size + offset = g_object_info_get_field_offset(info, blob->n_fields) + blob->n_properties * header->property_blob_size + blob->n_methods * header->function_blob_size + blob->n_signals * header->signal_blob_size; @@ -769,9 +784,7 @@ g_object_info_get_constant (GIObjectInfo *info, header = (Header *)rinfo->typelib->data; blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = rinfo->offset + header->object_blob_size - + (blob->n_interfaces + blob->n_interfaces % 2) * 2 - + blob->n_fields * header->field_blob_size + offset = g_object_info_get_field_offset(info, blob->n_fields) + blob->n_properties * header->property_blob_size + blob->n_methods * header->function_blob_size + blob->n_signals * header->signal_blob_size diff --git a/girparser.c b/girparser.c index 82005fc0f..c7feb6ad3 100644 --- a/girparser.c +++ b/girparser.c @@ -62,37 +62,38 @@ struct _GIrParser typedef enum { + STATE_NONE = 0, STATE_START, STATE_END, STATE_REPOSITORY, STATE_INCLUDE, - STATE_C_INCLUDE, - STATE_PACKAGE, /* 5 */ + STATE_C_INCLUDE, /* 5 */ + STATE_PACKAGE, STATE_NAMESPACE, STATE_ENUM, STATE_BITFIELD, - STATE_FUNCTION, - STATE_FUNCTION_RETURN, /* 10 */ + STATE_FUNCTION, /* 10 */ + STATE_FUNCTION_RETURN, STATE_FUNCTION_PARAMETERS, STATE_FUNCTION_PARAMETER, STATE_CLASS, - STATE_CLASS_FIELD, - STATE_CLASS_PROPERTY, /* 15 */ + STATE_CLASS_FIELD, /* 15 */ + STATE_CLASS_PROPERTY, STATE_INTERFACE, STATE_INTERFACE_PROPERTY, STATE_INTERFACE_FIELD, - STATE_IMPLEMENTS, - STATE_PREREQUISITE, /* 20 */ + STATE_IMPLEMENTS, /* 20 */ + STATE_PREREQUISITE, STATE_BOXED, STATE_BOXED_FIELD, STATE_STRUCT, - STATE_STRUCT_FIELD, - STATE_UNION, /* 25 */ + STATE_STRUCT_FIELD, /* 25 */ + STATE_UNION, STATE_UNION_FIELD, STATE_NAMESPACE_CONSTANT, STATE_CLASS_CONSTANT, - STATE_INTERFACE_CONSTANT, - STATE_ALIAS, /* 30 */ + STATE_INTERFACE_CONSTANT, /* 30 */ + STATE_ALIAS, STATE_TYPE, STATE_ATTRIBUTE, STATE_PASSTHROUGH @@ -123,7 +124,7 @@ struct _ParseContext GList *type_stack; GList *type_parameters; int type_depth; - gboolean in_embedded_type; + ParseState in_embedded_state; }; #define CURRENT_NODE(ctx) ((GIrNode *)((ctx)->node_stack->data)) @@ -807,7 +808,7 @@ start_function (GMarkupParseContext *context, const gchar *throws; GIrNodeFunction *function; gboolean found = FALSE; - gboolean in_embedded_type; + ParseState in_embedded_state = STATE_NONE; switch (ctx->state) { @@ -830,8 +831,10 @@ start_function (GMarkupParseContext *context, case STATE_ENUM: found = strcmp (element_name, "function") == 0; break; + case STATE_CLASS_FIELD: case STATE_STRUCT_FIELD: found = (found || strcmp (element_name, "callback") == 0); + in_embedded_state = ctx->state; break; default: break; @@ -840,12 +843,10 @@ start_function (GMarkupParseContext *context, if (!found) return FALSE; - in_embedded_type = ctx->state == STATE_STRUCT_FIELD; - if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION)) return TRUE; - ctx->in_embedded_type = in_embedded_type; + ctx->in_embedded_state = in_embedded_state; name = find_attribute ("name", attribute_names, attribute_values); shadows = find_attribute ("shadows", attribute_names, attribute_values); @@ -3210,10 +3211,10 @@ end_element_handler (GMarkupParseContext *context, else { g_debug("case STATE_FUNCTION %d", CURRENT_NODE (ctx)->type); - if (ctx->in_embedded_type) + if (ctx->in_embedded_state != STATE_NONE) { - ctx->in_embedded_type = FALSE; - state_switch (ctx, STATE_STRUCT_FIELD); + state_switch (ctx, ctx->in_embedded_state); + ctx->in_embedded_state = STATE_NONE; } else if (CURRENT_NODE (ctx)->type == G_IR_NODE_INTERFACE) state_switch (ctx, STATE_INTERFACE); diff --git a/gitypelib.c b/gitypelib.c index 8883496e3..41b54fd8e 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -1773,10 +1773,17 @@ validate_object_blob (ValidateContext *ctx, push_context (ctx, get_string_nofail (typelib, blob->name)); - for (i = 0; i < blob->n_fields; i++, offset2 += sizeof (FieldBlob)) + for (i = 0; i < blob->n_fields; i++) { + FieldBlob *blob = (FieldBlob*) &typelib->data[offset2]; + if (!validate_field_blob (ctx, offset2, error)) return FALSE; + + offset2 += sizeof (FieldBlob); + /* Special case fields which are callbacks. */ + if (blob->has_embedded_type) + offset2 += sizeof (CallbackBlob); } for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob)) From 6d1df44ff750476ae2515f7c642941f3dda9e62c Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Wed, 16 Apr 2014 11:33:36 -0400 Subject: [PATCH 530/692] girepository: ArgBlob: rename allow_none parameter Rename the "allow_none" parameter on internal/private structure ArgBlob to "nullable". This is a straight rename with no other changes. https://bugzilla.gnome.org/show_bug.cgi?id=660879 --- giarginfo.c | 2 +- girnode.c | 10 +++++----- girnode.h | 2 +- girparser.c | 4 ++-- gitypelib-internal.h | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/giarginfo.c b/giarginfo.c index 572839c3f..c96976a86 100644 --- a/giarginfo.c +++ b/giarginfo.c @@ -162,7 +162,7 @@ g_arg_info_may_be_null (GIArgInfo *info) blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset]; - return blob->allow_none; + return blob->nullable; } /** diff --git a/girnode.c b/girnode.c index 093a37836..53385c26a 100644 --- a/girnode.c +++ b/girnode.c @@ -1660,7 +1660,7 @@ _g_ir_node_build_typelib (GIrNode *node, _g_ir_node_build_typelib ((GIrNode *)function->result->type, node, build, &signature, offset2); - blob2->may_return_null = function->result->allow_none; + blob2->may_return_null = function->result->nullable; blob2->caller_owns_return_value = function->result->transfer; blob2->caller_owns_return_container = function->result->shallow_transfer; blob2->skip_return = function->result->skip; @@ -1702,7 +1702,7 @@ _g_ir_node_build_typelib (GIrNode *node, _g_ir_node_build_typelib ((GIrNode *)function->result->type, node, build, &signature, offset2); - blob2->may_return_null = function->result->allow_none; + blob2->may_return_null = function->result->nullable; blob2->caller_owns_return_value = function->result->transfer; blob2->caller_owns_return_container = function->result->shallow_transfer; blob2->reserved = 0; @@ -1759,7 +1759,7 @@ _g_ir_node_build_typelib (GIrNode *node, _g_ir_node_build_typelib ((GIrNode *)signal->result->type, node, build, &signature, offset2); - blob2->may_return_null = signal->result->allow_none; + blob2->may_return_null = signal->result->nullable; blob2->caller_owns_return_value = signal->result->transfer; blob2->caller_owns_return_container = signal->result->shallow_transfer; blob2->reserved = 0; @@ -1817,7 +1817,7 @@ _g_ir_node_build_typelib (GIrNode *node, _g_ir_node_build_typelib ((GIrNode *)vfunc->result->type, node, build, &signature, offset2); - blob2->may_return_null = vfunc->result->allow_none; + blob2->may_return_null = vfunc->result->nullable; blob2->caller_owns_return_value = vfunc->result->transfer; blob2->caller_owns_return_container = vfunc->result->shallow_transfer; blob2->reserved = 0; @@ -1848,7 +1848,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob->in = param->in; blob->out = param->out; blob->caller_allocates = param->caller_allocates; - blob->allow_none = param->allow_none; + blob->nullable = param->nullable; blob->skip = param->skip; blob->optional = param->optional; blob->transfer_ownership = param->transfer; diff --git a/girnode.h b/girnode.h index 07b084c49..4beef7f83 100644 --- a/girnode.h +++ b/girnode.h @@ -146,7 +146,7 @@ struct _GIrNodeParam gboolean caller_allocates; gboolean optional; gboolean retval; - gboolean allow_none; + gboolean nullable; gboolean skip; gboolean transfer; gboolean shallow_transfer; diff --git a/girparser.c b/girparser.c index c7feb6ad3..ac21f6a99 100644 --- a/girparser.c +++ b/girparser.c @@ -1127,9 +1127,9 @@ start_parameter (GMarkupParseContext *context, param->optional = FALSE; if (allow_none && strcmp (allow_none, "1") == 0) - param->allow_none = TRUE; + param->nullable = TRUE; else - param->allow_none = FALSE; + param->nullable = FALSE; if (skip && strcmp (skip, "1") == 0) param->skip = TRUE; diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 23f4d625e..93d621b2c 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -396,7 +396,7 @@ typedef union _SimpleTypeBlob SimpleTypeBlob; * parameter, the function actually takes an uint32*. * @caller_allocates: The parameter is a pointer to a struct or object that * will receive an output of the function. - * @allow_none: Only meaningful for types which are passed as pointers. For an + * @nullable: Only meaningful for types which are passed as pointers. For an * in parameter, indicates if it is ok to pass NULL in. Gor an out * parameter, indicates whether it may return NULL. Note that NULL is a * valid GList and GSList value, thus allow_none will normally be set @@ -437,7 +437,7 @@ typedef struct { guint in : 1; guint out : 1; guint caller_allocates : 1; - guint allow_none : 1; + guint nullable : 1; guint optional : 1; guint transfer_ownership : 1; guint transfer_container_ownership : 1; From 45e28fa69846b45deb8726d606915ff1538db701 Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Wed, 16 Apr 2014 11:39:09 -0400 Subject: [PATCH 531/692] compiler: girparser: parse 'nullable' attribute Parse the 'nullable' attribute on parameters and function return types. Additionally, tweak the meaning of the 'allow-none' attribute. We now only treat it as equivalent to 'nullable' for non-out parameters. For out parameters, we treat it to mean the same as the already-recognised 'optional' parameter (which we only recently started actually using). https://bugzilla.gnome.org/show_bug.cgi?id=660879 --- girparser.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index ac21f6a99..6c7686695 100644 --- a/girparser.c +++ b/girparser.c @@ -1065,6 +1065,7 @@ start_parameter (GMarkupParseContext *context, const gchar *closure; const gchar *destroy; const gchar *skip; + const gchar *nullable; GIrNodeParam *param; if (!(strcmp (element_name, "parameter") == 0 && @@ -1082,6 +1083,7 @@ start_parameter (GMarkupParseContext *context, closure = find_attribute ("closure", attribute_names, attribute_values); destroy = find_attribute ("destroy", attribute_names, attribute_values); skip = find_attribute ("skip", attribute_names, attribute_values); + nullable = find_attribute ("nullable", attribute_names, attribute_values); if (name == NULL) name = "unknown"; @@ -1126,11 +1128,19 @@ start_parameter (GMarkupParseContext *context, else param->optional = FALSE; - if (allow_none && strcmp (allow_none, "1") == 0) + if (nullable && strcmp (nullable, "1") == 0) param->nullable = TRUE; else param->nullable = FALSE; + if (allow_none && strcmp (allow_none, "1") == 0) + { + if (param->out) + param->optional = TRUE; + else + param->nullable = TRUE; + } + if (skip && strcmp (skip, "1") == 0) param->skip = TRUE; else @@ -2172,6 +2182,7 @@ start_return_value (GMarkupParseContext *context, GIrNodeParam *param; const gchar *transfer; const gchar *skip; + const gchar *nullable; if (!(strcmp (element_name, "return-value") == 0 && ctx->state == STATE_FUNCTION)) @@ -2197,6 +2208,10 @@ start_return_value (GMarkupParseContext *context, if (!parse_param_transfer (param, transfer, NULL, error)) return FALSE; + nullable = find_attribute ("nullable", attribute_names, attribute_values); + if (nullable && g_str_equal (nullable, "1")) + param->nullable = TRUE; + switch (CURRENT_NODE (ctx)->type) { case G_IR_NODE_FUNCTION: From c0dab09f95ed5486be8a852badf53438de45d7bc Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Wed, 14 May 2014 14:56:58 -0400 Subject: [PATCH 532/692] girepository: change giarginfo docs Clarify the meaning of 'may be null' in the docs: it refers to the value of the argument itself, not the reference to the argument. https://bugzilla.gnome.org/show_bug.cgi?id=660879 --- giarginfo.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/giarginfo.c b/giarginfo.c index c96976a86..083ca44da 100644 --- a/giarginfo.c +++ b/giarginfo.c @@ -125,7 +125,8 @@ g_arg_info_is_caller_allocates (GIArgInfo *info) * g_arg_info_is_optional: * @info: a #GIArgInfo * - * Obtain if the argument is optional. + * Obtain if the argument is optional. For 'out' arguments this means + * that you can pass %NULL in order to ignore the result. * * Returns: %TRUE if it is an optional argument */ @@ -147,9 +148,13 @@ g_arg_info_is_optional (GIArgInfo *info) * g_arg_info_may_be_null: * @info: a #GIArgInfo * - * Obtain if the argument accepts %NULL. + * Obtain if the type of the argument includes the possibility of %NULL. + * For 'in' values this means that %NULL is a valid value. For 'out' + * values, this means that %NULL may be returned. * - * Returns: %TRUE if it accepts %NULL + * See also g_arg_info_is_optional(). + * + * Returns: %TRUE if the value may be %NULL */ gboolean g_arg_info_may_be_null (GIArgInfo *info) From d2514073b963fb8ea7b14eac3a51fff566a3b764 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 23 Jun 2014 09:35:02 +0100 Subject: [PATCH 533/692] gibaseinfo: Expand g_base_info_iterate_attributes() documentation Clarify what an attribute is, in response to a question on gir-devel-list. https://bugzilla.gnome.org/show_bug.cgi?id=732078 --- gibaseinfo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gibaseinfo.c b/gibaseinfo.c index 4bbe850a0..25c98b0e0 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -562,7 +562,10 @@ _attribute_blob_find_first (GIBaseInfo *info, * * Iterate over all attributes associated with this node. The iterator * structure is typically stack allocated, and must have its first - * member initialized to %NULL. + * member initialized to %NULL. Attributes are arbitrary namespaced key–value + * pairs which can be attached to almost any item. They are intended for use + * by software higher in the toolchain than bindings, and are distinct from + * normal GIR annotations. * * Both the @name and @value should be treated as constants * and must not be freed. From 9921571eb0e8660d329d1b2e506e9e97638b7eb0 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Tue, 6 May 2014 18:53:21 +0200 Subject: [PATCH 534/692] Parse and expose ownership transfer for instance parameters Knowing the ownership transfer for instance parameters is necessary for correct memory management of functions which "eat" their instance argument, such as g_dbus_method_invocation_return_*. Parse this information from the gir file and store in the typelib, and then provide new API on GICallableInfo to retrieve this. https://bugzilla.gnome.org/show_bug.cgi?id=729662 --- gicallableinfo.c | 26 ++++++++++++++++ gicallableinfo.h | 2 ++ girepository.symbols | 1 + girnode.c | 3 ++ girnode.h | 3 ++ girparser.c | 74 +++++++++++++++++++++++++++++++++++++++++--- gitypelib-internal.h | 5 ++- 7 files changed, 108 insertions(+), 6 deletions(-) diff --git a/gicallableinfo.c b/gicallableinfo.c index e69e3e9d2..702e16cd4 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -275,6 +275,32 @@ g_callable_info_get_caller_owns (GICallableInfo *info) return GI_TRANSFER_NOTHING; } +/** + * g_callable_info_get_instance_ownership_transfer: + * @info: a #GICallableInfo + * + * Obtains the ownership transfer for the instance argument. + * #GITransfer contains a list of possible transfer values. + * + * Returns: the transfer + */ +GITransfer +g_callable_info_get_instance_ownership_transfer (GICallableInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo*) info; + SignatureBlob *blob; + + g_return_val_if_fail (info != NULL, -1); + g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), -1); + + blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)]; + + if (blob->instance_transfer_ownership) + return GI_TRANSFER_EVERYTHING; + else + return GI_TRANSFER_NOTHING; +} + /** * g_callable_info_get_n_args: * @info: a #GICallableInfo diff --git a/gicallableinfo.h b/gicallableinfo.h index 71f9d0c62..f273d2905 100644 --- a/gicallableinfo.h +++ b/gicallableinfo.h @@ -73,6 +73,8 @@ gboolean g_callable_info_invoke (GICallableInfo *info, gboolean is_method, gboolean throws, GError **error); +GITransfer g_callable_info_get_instance_ownership_transfer (GICallableInfo *info); + G_END_DECLS diff --git a/girepository.symbols b/girepository.symbols index 5f01adffd..48fb0d904 100644 --- a/girepository.symbols +++ b/girepository.symbols @@ -26,6 +26,7 @@ g_info_new g_callable_info_can_throw_gerror g_callable_info_get_arg g_callable_info_get_caller_owns +g_callable_info_get_instance_ownership_transfer g_callable_info_get_n_args g_callable_info_get_return_attribute g_callable_info_get_return_type diff --git a/girnode.c b/girnode.c index 53385c26a..a7a77e315 100644 --- a/girnode.c +++ b/girnode.c @@ -1664,6 +1664,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob2->caller_owns_return_value = function->result->transfer; blob2->caller_owns_return_container = function->result->shallow_transfer; blob2->skip_return = function->result->skip; + blob2->instance_transfer_ownership = function->instance_transfer_full; blob2->reserved = 0; blob2->n_arguments = n; @@ -1762,6 +1763,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob2->may_return_null = signal->result->nullable; blob2->caller_owns_return_value = signal->result->transfer; blob2->caller_owns_return_container = signal->result->shallow_transfer; + blob2->instance_transfer_ownership = signal->instance_transfer_full; blob2->reserved = 0; blob2->n_arguments = n; @@ -1820,6 +1822,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob2->may_return_null = vfunc->result->nullable; blob2->caller_owns_return_value = vfunc->result->transfer; blob2->caller_owns_return_container = vfunc->result->shallow_transfer; + blob2->instance_transfer_ownership = vfunc->instance_transfer_full; blob2->reserved = 0; blob2->n_arguments = n; diff --git a/girnode.h b/girnode.h index 4beef7f83..02196e7f4 100644 --- a/girnode.h +++ b/girnode.h @@ -100,6 +100,7 @@ struct _GIrNodeFunction gboolean is_constructor; gboolean wraps_vfunc; gboolean throws; + gboolean instance_transfer_full; gchar *symbol; @@ -188,6 +189,7 @@ struct _GIrNodeSignal gboolean detailed; gboolean action; gboolean no_hooks; + gboolean instance_transfer_full; gboolean has_class_closure; gboolean true_stops_emit; @@ -208,6 +210,7 @@ struct _GIrNodeVFunc gboolean must_not_be_implemented; gboolean is_class_closure; gboolean throws; + gboolean instance_transfer_full; char *invoker; diff --git a/girparser.c b/girparser.c index 6c7686695..f928c2e29 100644 --- a/girparser.c +++ b/girparser.c @@ -1046,6 +1046,71 @@ parse_param_transfer (GIrNodeParam *param, const gchar *transfer, const gchar *n return TRUE; } +static gboolean +start_instance_parameter (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + ParseContext *ctx, + GError **error) +{ + const gchar *transfer; + gboolean transfer_full; + + if (!(strcmp (element_name, "instance-parameter") == 0 && + ctx->state == STATE_FUNCTION_PARAMETERS)) + return FALSE; + + transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); + + state_switch (ctx, STATE_PASSTHROUGH); + + if (strcmp (transfer, "full") == 0) + transfer_full = TRUE; + else if (strcmp (transfer, "none") == 0) + transfer_full = FALSE; + else + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + "invalid value for 'transfer-ownership' for instance parameter: %s", transfer); + return FALSE; + } + + switch (CURRENT_NODE (ctx)->type) + { + case G_IR_NODE_FUNCTION: + case G_IR_NODE_CALLBACK: + { + GIrNodeFunction *func; + + func = (GIrNodeFunction *)CURRENT_NODE (ctx); + func->instance_transfer_full = transfer_full; + } + break; + case G_IR_NODE_SIGNAL: + { + GIrNodeSignal *signal; + + signal = (GIrNodeSignal *)CURRENT_NODE (ctx); + signal->instance_transfer_full = transfer_full; + } + break; + case G_IR_NODE_VFUNC: + { + GIrNodeVFunc *vfunc; + + vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx); + vfunc->instance_transfer_full = transfer_full; + } + break; + default: + g_assert_not_reached (); + } + + return TRUE; +} + static gboolean start_parameter (GMarkupParseContext *context, const gchar *element_name, @@ -2848,11 +2913,10 @@ start_element_handler (GMarkupParseContext *context, attribute_names, attribute_values, ctx, error)) goto out; - else if (strcmp (element_name, "instance-parameter") == 0) - { - state_switch (ctx, STATE_PASSTHROUGH); - goto out; - } + else if (start_instance_parameter (context, element_name, + attribute_names, attribute_values, + ctx, error)) + goto out; else if (strcmp (element_name, "c:include") == 0) { state_switch (ctx, STATE_C_INCLUDE); diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 93d621b2c..5ccb61734 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -465,6 +465,8 @@ typedef struct { * freeing the container, but not its contents. * @skip_return: Indicates that the return value is only useful in C and should * be skipped. + * @instance_transfer_ownership: When calling, the function assumes ownership of + * the instance parameter. * @reserved: Reserved for future use. * @n_arguments: The number of arguments that this function expects, also the * length of the array of ArgBlobs. @@ -479,7 +481,8 @@ typedef struct { guint16 caller_owns_return_value : 1; guint16 caller_owns_return_container : 1; guint16 skip_return : 1; - guint16 reserved :12; + guint16 instance_transfer_ownership : 1; + guint16 reserved :11; guint16 n_arguments; From adc6f08ff71c92c6060a6eed67c901eed5813214 Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Fri, 4 Jul 2014 18:27:41 +0800 Subject: [PATCH 535/692] girepository: Include config.h First in All Sources This includes config.h in all the C-sources of girepository so that we can get the correct export directive from config.h during compile time and therefore export the symbols as necessary, like what GLib and GTK+ is currently doing. https://bugzilla.gnome.org/show_bug.cgi?id=732669 --- giarginfo.c | 2 ++ gibaseinfo.c | 2 ++ gicallableinfo.c | 2 ++ giconstantinfo.c | 2 ++ gienuminfo.c | 2 ++ gifieldinfo.c | 2 ++ gifunctioninfo.c | 2 ++ giinterfaceinfo.c | 2 ++ ginvoke.c | 3 ++- giobjectinfo.c | 2 ++ gipropertyinfo.c | 2 ++ giregisteredtypeinfo.c | 2 ++ girepository.c | 5 ++--- girparser.c | 3 ++- gisignalinfo.c | 2 ++ gistructinfo.c | 2 ++ gitypeinfo.c | 2 ++ gitypelib.c | 3 ++- giunioninfo.c | 2 ++ givfuncinfo.c | 2 ++ 20 files changed, 40 insertions(+), 6 deletions(-) diff --git a/giarginfo.c b/giarginfo.c index 083ca44da..6bc53c484 100644 --- a/giarginfo.c +++ b/giarginfo.c @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include "gitypelib-internal.h" diff --git a/gibaseinfo.c b/gibaseinfo.c index 25c98b0e0..5d9e5f37b 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include diff --git a/gicallableinfo.c b/gicallableinfo.c index 702e16cd4..7e0ec7762 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include diff --git a/giconstantinfo.c b/giconstantinfo.c index 7b2f716c9..60715a4b6 100644 --- a/giconstantinfo.c +++ b/giconstantinfo.c @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include // memcpy diff --git a/gienuminfo.c b/gienuminfo.c index 253ec6848..42930b2f5 100644 --- a/gienuminfo.c +++ b/gienuminfo.c @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include diff --git a/gifieldinfo.c b/gifieldinfo.c index 2bbc0214f..ea64dabbd 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include diff --git a/gifunctioninfo.c b/gifunctioninfo.c index ecd612755..ece948184 100644 --- a/gifunctioninfo.c +++ b/gifunctioninfo.c @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include diff --git a/giinterfaceinfo.c b/giinterfaceinfo.c index 481fc54e5..d60729c37 100644 --- a/giinterfaceinfo.c +++ b/giinterfaceinfo.c @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include diff --git a/ginvoke.c b/ginvoke.c index 6eba9fcc7..bd5aa2cd9 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -19,6 +19,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include @@ -26,7 +28,6 @@ #include #include "girffi.h" -#include "config.h" /** * value_to_ffi_type: diff --git a/giobjectinfo.c b/giobjectinfo.c index d92a86151..381f4651d 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include diff --git a/gipropertyinfo.c b/gipropertyinfo.c index 77a11cb86..338f360bf 100644 --- a/gipropertyinfo.c +++ b/gipropertyinfo.c @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include diff --git a/giregisteredtypeinfo.c b/giregisteredtypeinfo.c index e45e06038..1555c459b 100644 --- a/giregisteredtypeinfo.c +++ b/giregisteredtypeinfo.c @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include diff --git a/girepository.c b/girepository.c index 6fc7c77e9..931385ff0 100644 --- a/girepository.c +++ b/girepository.c @@ -21,6 +21,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include #include @@ -32,9 +34,6 @@ #include "gitypelib-internal.h" #include "girepository-private.h" -#include "config.h" - - /** * SECTION:girepository * @short_description: GObject Introspection repository manager diff --git a/girparser.c b/girparser.c index f928c2e29..eb61e34a5 100644 --- a/girparser.c +++ b/girparser.c @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include #include @@ -29,7 +31,6 @@ #include "girmodule.h" #include "girnode.h" #include "gitypelib-internal.h" -#include "config.h" /* This is a "major" version in the sense that it's only bumped * for incompatible changes. diff --git a/gisignalinfo.c b/gisignalinfo.c index be75276e9..e72890d78 100644 --- a/gisignalinfo.c +++ b/gisignalinfo.c @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include diff --git a/gistructinfo.c b/gistructinfo.c index f205e7cf5..0fbaec842 100644 --- a/gistructinfo.c +++ b/gistructinfo.c @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include diff --git a/gitypeinfo.c b/gitypeinfo.c index 3c17f5647..1bc189cb8 100644 --- a/gitypeinfo.c +++ b/gitypeinfo.c @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include diff --git a/gitypelib.c b/gitypelib.c index 41b54fd8e..09e74f13d 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -20,12 +20,13 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include #include -#include "config.h" #include "gitypelib-internal.h" typedef struct { diff --git a/giunioninfo.c b/giunioninfo.c index 8ae1e915b..a819595f1 100644 --- a/giunioninfo.c +++ b/giunioninfo.c @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include diff --git a/givfuncinfo.c b/givfuncinfo.c index 8a5b71a17..c16fb01dd 100644 --- a/givfuncinfo.c +++ b/givfuncinfo.c @@ -20,6 +20,8 @@ * Boston, MA 02111-1307, USA. */ +#include "config.h" + #include #include From 265ea792c17a55987600dd701166e1e91d94e923 Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Fri, 4 Jul 2014 18:18:32 +0800 Subject: [PATCH 536/692] girepository: Add Header for Version Macros This adds a header to the girepository library, which is then included either directly or indirectly by the other headers so that all the public symbols (and the 2 symbols in gitypelib-internal.h used by the tools) are decorated by a macro, that can later be used to export the symbols and also to be used to display compile-time warnings for usage of deprecated APIs, which is like what is now being done in GLib (and GTK+, Clutter, and so on). This marks the first step that we begin to stop depending on the .symbols/ .def files to export the symbols. https://bugzilla.gnome.org/show_bug.cgi?id=732669 --- giarginfo.h | 24 ++++++++ gibaseinfo.h | 26 +++++++++ gicallableinfo.h | 28 +++++++++ giconstantinfo.h | 6 ++ gienuminfo.h | 14 +++++ gifieldinfo.h | 12 ++++ gifunctioninfo.h | 12 ++++ giinterfaceinfo.h | 32 +++++++++++ giobjectinfo.h | 66 +++++++++++++++++++++ gipropertyinfo.h | 6 ++ giregisteredtypeinfo.h | 5 ++ girepository.h | 45 +++++++++++++++ girffi.h | 8 +++ gisignalinfo.h | 6 ++ gistructinfo.h | 18 ++++++ gitypeinfo.h | 19 ++++++ gitypelib-internal.h | 4 ++ gitypelib.h | 12 ++++ gitypes.h | 2 + giunioninfo.h | 21 +++++++ giversionmacros.h | 128 +++++++++++++++++++++++++++++++++++++++++ givfuncinfo.h | 11 ++++ 22 files changed, 505 insertions(+) create mode 100644 giversionmacros.h diff --git a/giarginfo.h b/giarginfo.h index 4045ab9c3..0cd1f79a7 100644 --- a/giarginfo.h +++ b/giarginfo.h @@ -40,17 +40,41 @@ G_BEGIN_DECLS #define GI_IS_ARG_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_ARG) + +GI_AVAILABLE_IN_ALL GIDirection g_arg_info_get_direction (GIArgInfo *info); + +GI_AVAILABLE_IN_ALL gboolean g_arg_info_is_return_value (GIArgInfo *info); + +GI_AVAILABLE_IN_ALL gboolean g_arg_info_is_optional (GIArgInfo *info); + +GI_AVAILABLE_IN_ALL gboolean g_arg_info_is_caller_allocates (GIArgInfo *info); + +GI_AVAILABLE_IN_ALL gboolean g_arg_info_may_be_null (GIArgInfo *info); + +GI_AVAILABLE_IN_ALL gboolean g_arg_info_is_skip (GIArgInfo *info); + +GI_AVAILABLE_IN_ALL GITransfer g_arg_info_get_ownership_transfer (GIArgInfo *info); + +GI_AVAILABLE_IN_ALL GIScopeType g_arg_info_get_scope (GIArgInfo *info); + +GI_AVAILABLE_IN_ALL gint g_arg_info_get_closure (GIArgInfo *info); + +GI_AVAILABLE_IN_ALL gint g_arg_info_get_destroy (GIArgInfo *info); + +GI_AVAILABLE_IN_ALL GITypeInfo * g_arg_info_get_type (GIArgInfo *info); + +GI_AVAILABLE_IN_ALL void g_arg_info_load_type (GIArgInfo *info, GITypeInfo *type); G_END_DECLS diff --git a/gibaseinfo.h b/gibaseinfo.h index a49dd506f..52471df33 100644 --- a/gibaseinfo.h +++ b/gibaseinfo.h @@ -66,23 +66,49 @@ typedef struct { #define GI_TYPE_BASE_INFO (g_base_info_gtype_get_type ()) + +GI_AVAILABLE_IN_ALL GType g_base_info_gtype_get_type (void) G_GNUC_CONST; + +GI_AVAILABLE_IN_ALL GIBaseInfo * g_base_info_ref (GIBaseInfo *info); + +GI_AVAILABLE_IN_ALL void g_base_info_unref (GIBaseInfo *info); + +GI_AVAILABLE_IN_ALL GIInfoType g_base_info_get_type (GIBaseInfo *info); + +GI_AVAILABLE_IN_ALL const gchar * g_base_info_get_name (GIBaseInfo *info); + +GI_AVAILABLE_IN_ALL const gchar * g_base_info_get_namespace (GIBaseInfo *info); + +GI_AVAILABLE_IN_ALL gboolean g_base_info_is_deprecated (GIBaseInfo *info); + +GI_AVAILABLE_IN_ALL const gchar * g_base_info_get_attribute (GIBaseInfo *info, const gchar *name); + +GI_AVAILABLE_IN_ALL gboolean g_base_info_iterate_attributes (GIBaseInfo *info, GIAttributeIter *iterator, char **name, char **value); + +GI_AVAILABLE_IN_ALL GIBaseInfo * g_base_info_get_container (GIBaseInfo *info); + +GI_AVAILABLE_IN_ALL GITypelib * g_base_info_get_typelib (GIBaseInfo *info); + +GI_AVAILABLE_IN_ALL gboolean g_base_info_equal (GIBaseInfo *info1, GIBaseInfo *info2); + +GI_AVAILABLE_IN_ALL GIBaseInfo * g_info_new (GIInfoType type, GIBaseInfo *container, GITypelib *typelib, diff --git a/gicallableinfo.h b/gicallableinfo.h index f273d2905..065ff91d6 100644 --- a/gicallableinfo.h +++ b/gicallableinfo.h @@ -43,26 +43,52 @@ G_BEGIN_DECLS (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_SIGNAL) || \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_VFUNC)) + +GI_AVAILABLE_IN_1_34 gboolean g_callable_info_is_method (GICallableInfo *info); + +GI_AVAILABLE_IN_1_34 gboolean g_callable_info_can_throw_gerror (GICallableInfo *info); + +GI_AVAILABLE_IN_ALL GITypeInfo * g_callable_info_get_return_type (GICallableInfo *info); + +GI_AVAILABLE_IN_ALL void g_callable_info_load_return_type (GICallableInfo *info, GITypeInfo *type); + +GI_AVAILABLE_IN_ALL const gchar * g_callable_info_get_return_attribute (GICallableInfo *info, const gchar *name); + +GI_AVAILABLE_IN_ALL gboolean g_callable_info_iterate_return_attributes (GICallableInfo *info, GIAttributeIter *iterator, char **name, char **value); + +GI_AVAILABLE_IN_ALL GITransfer g_callable_info_get_caller_owns (GICallableInfo *info); + +GI_AVAILABLE_IN_ALL gboolean g_callable_info_may_return_null (GICallableInfo *info); + +GI_AVAILABLE_IN_ALL gboolean g_callable_info_skip_return (GICallableInfo *info); + +GI_AVAILABLE_IN_ALL gint g_callable_info_get_n_args (GICallableInfo *info); + +GI_AVAILABLE_IN_ALL GIArgInfo * g_callable_info_get_arg (GICallableInfo *info, gint n); + +GI_AVAILABLE_IN_ALL void g_callable_info_load_arg (GICallableInfo *info, gint n, GIArgInfo *arg); + +GI_AVAILABLE_IN_1_34 gboolean g_callable_info_invoke (GICallableInfo *info, gpointer function, const GIArgument *in_args, @@ -73,6 +99,8 @@ gboolean g_callable_info_invoke (GICallableInfo *info, gboolean is_method, gboolean throws, GError **error); + +GI_AVAILABLE_IN_1_42 GITransfer g_callable_info_get_instance_ownership_transfer (GICallableInfo *info); G_END_DECLS diff --git a/giconstantinfo.h b/giconstantinfo.h index 2ce1dcad6..c958c8fde 100644 --- a/giconstantinfo.h +++ b/giconstantinfo.h @@ -40,9 +40,15 @@ G_BEGIN_DECLS #define GI_IS_CONSTANT_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_CONSTANT) + +GI_AVAILABLE_IN_ALL GITypeInfo * g_constant_info_get_type (GIConstantInfo *info); + +GI_AVAILABLE_IN_ALL void g_constant_info_free_value(GIConstantInfo *info, GIArgument *value); + +GI_AVAILABLE_IN_ALL gint g_constant_info_get_value(GIConstantInfo *info, GIArgument *value); G_END_DECLS diff --git a/gienuminfo.h b/gienuminfo.h index 257e4c120..3f990e656 100644 --- a/gienuminfo.h +++ b/gienuminfo.h @@ -50,15 +50,29 @@ G_BEGIN_DECLS #define GI_IS_VALUE_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_VALUE) + +GI_AVAILABLE_IN_ALL gint g_enum_info_get_n_values (GIEnumInfo *info); + +GI_AVAILABLE_IN_ALL GIValueInfo * g_enum_info_get_value (GIEnumInfo *info, gint n); + +GI_AVAILABLE_IN_ALL gint g_enum_info_get_n_methods (GIEnumInfo *info); + +GI_AVAILABLE_IN_ALL GIFunctionInfo * g_enum_info_get_method (GIEnumInfo *info, gint n); + +GI_AVAILABLE_IN_ALL GITypeTag g_enum_info_get_storage_type (GIEnumInfo *info); + +GI_AVAILABLE_IN_ALL const gchar * g_enum_info_get_error_domain (GIEnumInfo *info); + +GI_AVAILABLE_IN_ALL gint64 g_value_info_get_value (GIValueInfo *info); G_END_DECLS diff --git a/gifieldinfo.h b/gifieldinfo.h index 56a2e22ea..1b95b719b 100644 --- a/gifieldinfo.h +++ b/gifieldinfo.h @@ -41,13 +41,25 @@ G_BEGIN_DECLS #define GI_IS_FIELD_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FIELD) + +GI_AVAILABLE_IN_ALL GIFieldInfoFlags g_field_info_get_flags (GIFieldInfo *info); + +GI_AVAILABLE_IN_ALL gint g_field_info_get_size (GIFieldInfo *info); + +GI_AVAILABLE_IN_ALL gint g_field_info_get_offset (GIFieldInfo *info); + +GI_AVAILABLE_IN_ALL GITypeInfo * g_field_info_get_type (GIFieldInfo *info); + +GI_AVAILABLE_IN_ALL gboolean g_field_info_get_field (GIFieldInfo *field_info, gpointer mem, GIArgument *value); + +GI_AVAILABLE_IN_ALL gboolean g_field_info_set_field (GIFieldInfo *field_info, gpointer mem, const GIArgument *value); diff --git a/gifunctioninfo.h b/gifunctioninfo.h index 7987c9260..e82eec69a 100644 --- a/gifunctioninfo.h +++ b/gifunctioninfo.h @@ -40,9 +40,17 @@ G_BEGIN_DECLS #define GI_IS_FUNCTION_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_FUNCTION) + +GI_AVAILABLE_IN_ALL const gchar * g_function_info_get_symbol (GIFunctionInfo *info); + +GI_AVAILABLE_IN_ALL GIFunctionInfoFlags g_function_info_get_flags (GIFunctionInfo *info); + +GI_AVAILABLE_IN_ALL GIPropertyInfo * g_function_info_get_property (GIFunctionInfo *info); + +GI_AVAILABLE_IN_ALL GIVFuncInfo * g_function_info_get_vfunc (GIFunctionInfo *info); /** @@ -51,6 +59,8 @@ GIVFuncInfo * g_function_info_get_vfunc (GIFunctionInfo *info); * TODO */ #define G_INVOKE_ERROR (g_invoke_error_quark ()) + +GI_AVAILABLE_IN_ALL GQuark g_invoke_error_quark (void); /** @@ -72,6 +82,8 @@ typedef enum G_INVOKE_ERROR_ARGUMENT_MISMATCH } GInvokeError; + +GI_AVAILABLE_IN_ALL gboolean g_function_info_invoke (GIFunctionInfo *info, const GIArgument *in_args, int n_in_args, diff --git a/giinterfaceinfo.h b/giinterfaceinfo.h index ec33a6300..c8cb815c7 100644 --- a/giinterfaceinfo.h +++ b/giinterfaceinfo.h @@ -40,31 +40,63 @@ G_BEGIN_DECLS #define GI_IS_INTERFACE_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_INTERFACE) + +GI_AVAILABLE_IN_ALL gint g_interface_info_get_n_prerequisites (GIInterfaceInfo *info); + +GI_AVAILABLE_IN_ALL GIBaseInfo * g_interface_info_get_prerequisite (GIInterfaceInfo *info, gint n); + +GI_AVAILABLE_IN_ALL gint g_interface_info_get_n_properties (GIInterfaceInfo *info); + +GI_AVAILABLE_IN_ALL GIPropertyInfo * g_interface_info_get_property (GIInterfaceInfo *info, gint n); + +GI_AVAILABLE_IN_ALL gint g_interface_info_get_n_methods (GIInterfaceInfo *info); + +GI_AVAILABLE_IN_ALL GIFunctionInfo * g_interface_info_get_method (GIInterfaceInfo *info, gint n); + +GI_AVAILABLE_IN_ALL GIFunctionInfo * g_interface_info_find_method (GIInterfaceInfo *info, const gchar *name); + +GI_AVAILABLE_IN_ALL gint g_interface_info_get_n_signals (GIInterfaceInfo *info); + +GI_AVAILABLE_IN_ALL GISignalInfo * g_interface_info_get_signal (GIInterfaceInfo *info, gint n); + +GI_AVAILABLE_IN_1_34 GISignalInfo * g_interface_info_find_signal (GIInterfaceInfo *info, const gchar *name); + +GI_AVAILABLE_IN_ALL gint g_interface_info_get_n_vfuncs (GIInterfaceInfo *info); + +GI_AVAILABLE_IN_ALL GIVFuncInfo * g_interface_info_get_vfunc (GIInterfaceInfo *info, gint n); + +GI_AVAILABLE_IN_ALL GIVFuncInfo * g_interface_info_find_vfunc (GIInterfaceInfo *info, const gchar *name); + +GI_AVAILABLE_IN_ALL gint g_interface_info_get_n_constants (GIInterfaceInfo *info); + +GI_AVAILABLE_IN_ALL GIConstantInfo * g_interface_info_get_constant (GIInterfaceInfo *info, gint n); + +GI_AVAILABLE_IN_ALL GIStructInfo * g_interface_info_get_iface_struct (GIInterfaceInfo *info); G_END_DECLS diff --git a/giobjectinfo.h b/giobjectinfo.h index 06206776d..dac95abff 100644 --- a/giobjectinfo.h +++ b/giobjectinfo.h @@ -77,60 +77,126 @@ typedef void * (*GIObjectInfoGetValueFunction) (const GValue *value); #define GI_IS_OBJECT_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_OBJECT) + +GI_AVAILABLE_IN_ALL const gchar * g_object_info_get_type_name (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL const gchar * g_object_info_get_type_init (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL gboolean g_object_info_get_abstract (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL gboolean g_object_info_get_fundamental (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL GIObjectInfo * g_object_info_get_parent (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL gint g_object_info_get_n_interfaces (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL GIInterfaceInfo * g_object_info_get_interface (GIObjectInfo *info, gint n); + +GI_AVAILABLE_IN_ALL gint g_object_info_get_n_fields (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL GIFieldInfo * g_object_info_get_field (GIObjectInfo *info, gint n); + +GI_AVAILABLE_IN_ALL gint g_object_info_get_n_properties (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL GIPropertyInfo * g_object_info_get_property (GIObjectInfo *info, gint n); + +GI_AVAILABLE_IN_ALL gint g_object_info_get_n_methods (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL GIFunctionInfo * g_object_info_get_method (GIObjectInfo *info, gint n); + +GI_AVAILABLE_IN_ALL GIFunctionInfo * g_object_info_find_method (GIObjectInfo *info, const gchar *name); + +GI_AVAILABLE_IN_ALL GIFunctionInfo * g_object_info_find_method_using_interfaces (GIObjectInfo *info, const gchar *name, GIObjectInfo **implementor); + +GI_AVAILABLE_IN_ALL gint g_object_info_get_n_signals (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL GISignalInfo * g_object_info_get_signal (GIObjectInfo *info, gint n); + +GI_AVAILABLE_IN_ALL GISignalInfo * g_object_info_find_signal (GIObjectInfo *info, const gchar *name); + +GI_AVAILABLE_IN_ALL gint g_object_info_get_n_vfuncs (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL GIVFuncInfo * g_object_info_get_vfunc (GIObjectInfo *info, gint n); + +GI_AVAILABLE_IN_ALL GIVFuncInfo * g_object_info_find_vfunc (GIObjectInfo *info, const gchar *name); + +GI_AVAILABLE_IN_1_32 GIVFuncInfo * g_object_info_find_vfunc_using_interfaces (GIObjectInfo *info, const gchar *name, GIObjectInfo **implementor); + +GI_AVAILABLE_IN_ALL gint g_object_info_get_n_constants (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL GIConstantInfo * g_object_info_get_constant (GIObjectInfo *info, gint n); + +GI_AVAILABLE_IN_ALL GIStructInfo * g_object_info_get_class_struct (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL const char * g_object_info_get_ref_function (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL GIObjectInfoRefFunction g_object_info_get_ref_function_pointer (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL const char * g_object_info_get_unref_function (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL GIObjectInfoUnrefFunction g_object_info_get_unref_function_pointer (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL const char * g_object_info_get_set_value_function (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL GIObjectInfoSetValueFunction g_object_info_get_set_value_function_pointer (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL const char * g_object_info_get_get_value_function (GIObjectInfo *info); + +GI_AVAILABLE_IN_ALL GIObjectInfoGetValueFunction g_object_info_get_get_value_function_pointer (GIObjectInfo *info); diff --git a/gipropertyinfo.h b/gipropertyinfo.h index 7644664bd..7f9c89a07 100644 --- a/gipropertyinfo.h +++ b/gipropertyinfo.h @@ -40,8 +40,14 @@ G_BEGIN_DECLS #define GI_IS_PROPERTY_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_PROPERTY) + +GI_AVAILABLE_IN_ALL GParamFlags g_property_info_get_flags (GIPropertyInfo *info); + +GI_AVAILABLE_IN_ALL GITypeInfo * g_property_info_get_type (GIPropertyInfo *info); + +GI_AVAILABLE_IN_ALL GITransfer g_property_info_get_ownership_transfer (GIPropertyInfo *info); G_END_DECLS diff --git a/giregisteredtypeinfo.h b/giregisteredtypeinfo.h index e5db25b4d..efc4a7739 100644 --- a/giregisteredtypeinfo.h +++ b/giregisteredtypeinfo.h @@ -48,8 +48,13 @@ G_BEGIN_DECLS (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_UNION) || \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_BOXED)) +GI_AVAILABLE_IN_ALL const gchar * g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info); + +GI_AVAILABLE_IN_ALL const gchar * g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info); + +GI_AVAILABLE_IN_ALL GType g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info); G_END_DECLS diff --git a/girepository.h b/girepository.h index dea250dfa..dcc34ce2c 100644 --- a/girepository.h +++ b/girepository.h @@ -45,6 +45,7 @@ #include #include #include +#include #include G_BEGIN_DECLS @@ -92,57 +93,99 @@ typedef enum /* Repository */ +GI_AVAILABLE_IN_ALL GType g_irepository_get_type (void) G_GNUC_CONST; + +GI_AVAILABLE_IN_ALL GIRepository *g_irepository_get_default (void); + +GI_AVAILABLE_IN_ALL void g_irepository_prepend_search_path (const char *directory); + +GI_AVAILABLE_IN_1_36 void g_irepository_prepend_library_path (const char *directory); + +GI_AVAILABLE_IN_ALL GSList * g_irepository_get_search_path (void); + +GI_AVAILABLE_IN_ALL const char * g_irepository_load_typelib (GIRepository *repository, GITypelib *typelib, GIRepositoryLoadFlags flags, GError **error); + +GI_AVAILABLE_IN_ALL gboolean g_irepository_is_registered (GIRepository *repository, const gchar *namespace_, const gchar *version); + +GI_AVAILABLE_IN_ALL GIBaseInfo * g_irepository_find_by_name (GIRepository *repository, const gchar *namespace_, const gchar *name); + +GI_AVAILABLE_IN_ALL GList * g_irepository_enumerate_versions (GIRepository *repository, const gchar *namespace_); + +GI_AVAILABLE_IN_ALL GITypelib * g_irepository_require (GIRepository *repository, const gchar *namespace_, const gchar *version, GIRepositoryLoadFlags flags, GError **error); + +GI_AVAILABLE_IN_ALL GITypelib * g_irepository_require_private (GIRepository *repository, const gchar *typelib_dir, const gchar *namespace_, const gchar *version, GIRepositoryLoadFlags flags, GError **error); + +GI_AVAILABLE_IN_ALL gchar ** g_irepository_get_dependencies (GIRepository *repository, const gchar *namespace_); + +GI_AVAILABLE_IN_ALL gchar ** g_irepository_get_loaded_namespaces (GIRepository *repository); + +GI_AVAILABLE_IN_ALL GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository, GType gtype); + +GI_AVAILABLE_IN_ALL gint g_irepository_get_n_infos (GIRepository *repository, const gchar *namespace_); + +GI_AVAILABLE_IN_ALL GIBaseInfo * g_irepository_get_info (GIRepository *repository, const gchar *namespace_, gint index); + +GI_AVAILABLE_IN_ALL GIEnumInfo * g_irepository_find_by_error_domain (GIRepository *repository, GQuark domain); + +GI_AVAILABLE_IN_ALL const gchar * g_irepository_get_typelib_path (GIRepository *repository, const gchar *namespace_); +GI_AVAILABLE_IN_ALL const gchar * g_irepository_get_shared_library (GIRepository *repository, const gchar *namespace_); +GI_AVAILABLE_IN_ALL const gchar * g_irepository_get_c_prefix (GIRepository *repository, const gchar *namespace_); +GI_AVAILABLE_IN_ALL const gchar * g_irepository_get_version (GIRepository *repository, const gchar *namespace_); + +GI_AVAILABLE_IN_ALL GOptionGroup * g_irepository_get_option_group (void); + +GI_AVAILABLE_IN_ALL gboolean g_irepository_dump (const char *arg, GError **error); /** @@ -175,11 +218,13 @@ typedef enum */ #define G_IREPOSITORY_ERROR (g_irepository_error_quark ()) +GI_AVAILABLE_IN_ALL GQuark g_irepository_error_quark (void); /* Global utility functions */ +GI_AVAILABLE_IN_ALL void gi_cclosure_marshal_generic (GClosure *closure, GValue *return_gvalue, guint n_param_values, diff --git a/girffi.h b/girffi.h index 50cabb170..d8a573698 100644 --- a/girffi.h +++ b/girffi.h @@ -64,30 +64,38 @@ struct _GIFunctionInvoker { */ typedef GIArgument GIFFIReturnValue; +GI_AVAILABLE_IN_ALL ffi_type * gi_type_tag_get_ffi_type (GITypeTag type_tag, gboolean is_pointer); +GI_AVAILABLE_IN_ALL ffi_type * g_type_info_get_ffi_type (GITypeInfo *info); +GI_AVAILABLE_IN_1_32 void gi_type_info_extract_ffi_return_value (GITypeInfo *return_info, GIFFIReturnValue *ffi_value, GIArgument *arg); +GI_AVAILABLE_IN_ALL gboolean g_function_info_prep_invoker (GIFunctionInfo *info, GIFunctionInvoker *invoker, GError **error); +GI_AVAILABLE_IN_1_32 gboolean g_function_invoker_new_for_address (gpointer addr, GICallableInfo *info, GIFunctionInvoker *invoker, GError **error); +GI_AVAILABLE_IN_ALL void g_function_invoker_destroy (GIFunctionInvoker *invoker); +GI_AVAILABLE_IN_ALL ffi_closure * g_callable_info_prepare_closure (GICallableInfo *callable_info, ffi_cif *cif, GIFFIClosureCallback callback, gpointer user_data); +GI_AVAILABLE_IN_ALL void g_callable_info_free_closure (GICallableInfo *callable_info, ffi_closure *closure); diff --git a/gisignalinfo.h b/gisignalinfo.h index 8502610c4..047aeb6e6 100644 --- a/gisignalinfo.h +++ b/gisignalinfo.h @@ -41,8 +41,14 @@ G_BEGIN_DECLS #define GI_IS_SIGNAL_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_SIGNAL) + +GI_AVAILABLE_IN_ALL GSignalFlags g_signal_info_get_flags (GISignalInfo *info); + +GI_AVAILABLE_IN_ALL GIVFuncInfo * g_signal_info_get_class_closure (GISignalInfo *info); + +GI_AVAILABLE_IN_ALL gboolean g_signal_info_true_stops_emit (GISignalInfo *info); G_END_DECLS diff --git a/gistructinfo.h b/gistructinfo.h index 4300534d6..2651311d3 100644 --- a/gistructinfo.h +++ b/gistructinfo.h @@ -40,17 +40,35 @@ G_BEGIN_DECLS #define GI_IS_STRUCT_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_STRUCT) + +GI_AVAILABLE_IN_ALL gint g_struct_info_get_n_fields (GIStructInfo *info); + +GI_AVAILABLE_IN_ALL GIFieldInfo * g_struct_info_get_field (GIStructInfo *info, gint n); + +GI_AVAILABLE_IN_ALL gint g_struct_info_get_n_methods (GIStructInfo *info); + +GI_AVAILABLE_IN_ALL GIFunctionInfo * g_struct_info_get_method (GIStructInfo *info, gint n); + +GI_AVAILABLE_IN_ALL GIFunctionInfo * g_struct_info_find_method (GIStructInfo *info, const gchar *name); + +GI_AVAILABLE_IN_ALL gsize g_struct_info_get_size (GIStructInfo *info); + +GI_AVAILABLE_IN_ALL gsize g_struct_info_get_alignment (GIStructInfo *info); + +GI_AVAILABLE_IN_ALL gboolean g_struct_info_is_gtype_struct (GIStructInfo *info); + +GI_AVAILABLE_IN_ALL gboolean g_struct_info_is_foreign (GIStructInfo *info); G_END_DECLS diff --git a/gitypeinfo.h b/gitypeinfo.h index 7591799a4..4d5679c93 100644 --- a/gitypeinfo.h +++ b/gitypeinfo.h @@ -48,17 +48,36 @@ G_BEGIN_DECLS */ #define G_TYPE_TAG_IS_BASIC(tag) (tag < GI_TYPE_TAG_ARRAY || tag == GI_TYPE_TAG_UNICHAR) +GI_AVAILABLE_IN_ALL const gchar* g_type_tag_to_string (GITypeTag type); + +GI_AVAILABLE_IN_ALL const gchar* g_info_type_to_string (GIInfoType type); + +GI_AVAILABLE_IN_ALL gboolean g_type_info_is_pointer (GITypeInfo *info); + +GI_AVAILABLE_IN_ALL GITypeTag g_type_info_get_tag (GITypeInfo *info); + +GI_AVAILABLE_IN_ALL GITypeInfo * g_type_info_get_param_type (GITypeInfo *info, gint n); + +GI_AVAILABLE_IN_ALL GIBaseInfo * g_type_info_get_interface (GITypeInfo *info); + +GI_AVAILABLE_IN_ALL gint g_type_info_get_array_length (GITypeInfo *info); + +GI_AVAILABLE_IN_ALL gint g_type_info_get_array_fixed_size(GITypeInfo *info); + +GI_AVAILABLE_IN_ALL gboolean g_type_info_is_zero_terminated (GITypeInfo *info); + +GI_AVAILABLE_IN_ALL GIArrayType g_type_info_get_array_type (GITypeInfo *info); G_END_DECLS diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 5ccb61734..e367cfa62 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -1217,6 +1217,8 @@ DirEntry *g_typelib_get_dir_entry_by_error_domain (GITypelib *typelib, gboolean g_typelib_matches_gtype_name_prefix (GITypelib *typelib, const gchar *gtype_name); + +GI_AVAILABLE_IN_ALL void g_typelib_check_sanity (void); /** @@ -1259,6 +1261,8 @@ typedef enum GQuark g_typelib_error_quark (void); + +GI_AVAILABLE_IN_ALL gboolean g_typelib_validate (GITypelib *typelib, GError **error); diff --git a/gitypelib.h b/gitypelib.h index 0726bf19b..7d0a66542 100644 --- a/gitypelib.h +++ b/gitypelib.h @@ -29,6 +29,8 @@ #include +#include + G_BEGIN_DECLS /** @@ -46,19 +48,29 @@ G_BEGIN_DECLS */ typedef struct _GITypelib GITypelib; +GI_AVAILABLE_IN_ALL GITypelib * g_typelib_new_from_memory (guint8 *memory, gsize len, GError **error); + +GI_AVAILABLE_IN_ALL GITypelib * g_typelib_new_from_const_memory (const guint8 *memory, gsize len, GError **error); + +GI_AVAILABLE_IN_ALL GITypelib * g_typelib_new_from_mapped_file (GMappedFile *mfile, GError **error); + +GI_AVAILABLE_IN_ALL void g_typelib_free (GITypelib *typelib); +GI_AVAILABLE_IN_ALL gboolean g_typelib_symbol (GITypelib *typelib, const gchar *symbol_name, gpointer *symbol); + +GI_AVAILABLE_IN_ALL const gchar * g_typelib_get_namespace (GITypelib *typelib); diff --git a/gitypes.h b/gitypes.h index cb8cb344a..b96ae0b37 100644 --- a/gitypes.h +++ b/gitypes.h @@ -27,6 +27,8 @@ #error "Only can be included directly." #endif +#include + G_BEGIN_DECLS #ifndef __GTK_DOC_IGNORE__ diff --git a/giunioninfo.h b/giunioninfo.h index 5359346af..62951b852 100644 --- a/giunioninfo.h +++ b/giunioninfo.h @@ -40,20 +40,41 @@ G_BEGIN_DECLS #define GI_IS_UNION_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_UNION) +GI_AVAILABLE_IN_ALL gint g_union_info_get_n_fields (GIUnionInfo *info); + +GI_AVAILABLE_IN_ALL GIFieldInfo * g_union_info_get_field (GIUnionInfo *info, gint n); + +GI_AVAILABLE_IN_ALL gint g_union_info_get_n_methods (GIUnionInfo *info); + +GI_AVAILABLE_IN_ALL GIFunctionInfo * g_union_info_get_method (GIUnionInfo *info, gint n); + +GI_AVAILABLE_IN_ALL gboolean g_union_info_is_discriminated (GIUnionInfo *info); + +GI_AVAILABLE_IN_ALL gint g_union_info_get_discriminator_offset (GIUnionInfo *info); + +GI_AVAILABLE_IN_ALL GITypeInfo * g_union_info_get_discriminator_type (GIUnionInfo *info); + +GI_AVAILABLE_IN_ALL GIConstantInfo * g_union_info_get_discriminator (GIUnionInfo *info, gint n); + +GI_AVAILABLE_IN_ALL GIFunctionInfo * g_union_info_find_method (GIUnionInfo *info, const gchar *name); + +GI_AVAILABLE_IN_ALL gsize g_union_info_get_size (GIUnionInfo *info); + +GI_AVAILABLE_IN_ALL gsize g_union_info_get_alignment (GIUnionInfo *info); G_END_DECLS diff --git a/giversionmacros.h b/giversionmacros.h new file mode 100644 index 000000000..15c88476e --- /dev/null +++ b/giversionmacros.h @@ -0,0 +1,128 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * GObject introspection: Versioning and export macros + * + * Copyright (C) 2014 Chun-wei Fan + * + * 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 + +#ifndef __GIVERSIONMACROS_H__ +#define __GIVERSIONMACROS_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef _GI_EXTERN +#define _GI_EXTERN extern +#endif + +#define GI_AVAILABLE_IN_ALL _GI_EXTERN + +/* XXX: Every new stable minor release should add a set of macros here + * + * We are using the GLib versions here as the G-I minor versions + * need to be in sync with the GLib minor versions. Api's added + * at or before 1.30 are marked as GI_AVAILABLE_IN_ALL + */ + +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_32 +# define GI_DEPRECATED_IN_1_32 GLIB_DEPRECATED +# define GI_DEPRECATED_IN_1_32_FOR(f) GLIB_DEPRECATED_FOR(f) +#else +# define GI_DEPRECATED_IN_1_32 _GI_EXTERN +# define GI_DEPRECATED_IN_1_32_FOR(f) _GI_EXTERN +#endif + +#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_32 +# define GI_AVAILABLE_IN_1_32 GLIB_UNAVAILABLE(2, 32) +#else +# define GI_AVAILABLE_IN_1_32 _GI_EXTERN +#endif + +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_34 +# define GI_DEPRECATED_IN_1_34 GLIB_DEPRECATED +# define GI_DEPRECATED_IN_1_34_FOR(f) GLIB_DEPRECATED_FOR(f) +#else +# define GI_DEPRECATED_IN_1_34 _GI_EXTERN +# define GI_DEPRECATED_IN_1_34_FOR(f) _GI_EXTERN +#endif + +#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_34 +# define GI_AVAILABLE_IN_1_34 GLIB_UNAVAILABLE(2, 34) +#else +# define GI_AVAILABLE_IN_1_34 _GI_EXTERN +#endif + +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_36 +# define GI_DEPRECATED_IN_1_36 GLIB_DEPRECATED +# define GI_DEPRECATED_IN_1_36_FOR(f) GLIB_DEPRECATED_FOR(f) +#else +# define GI_DEPRECATED_IN_1_36 _GI_EXTERN +# define GI_DEPRECATED_IN_1_36_FOR(f) _GI_EXTERN +#endif + +#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_36 +# define GI_AVAILABLE_IN_1_36 GLIB_UNAVAILABLE(2, 36) +#else +# define GI_AVAILABLE_IN_1_36 _GI_EXTERN +#endif + +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_38 +# define GI_DEPRECATED_IN_1_38 GLIB_DEPRECATED +# define GI_DEPRECATED_IN_1_38_FOR(f) GLIB_DEPRECATED_FOR(f) +#else +# define GI_DEPRECATED_IN_1_38 _GI_EXTERN +# define GI_DEPRECATED_IN_1_38_FOR(f) _GI_EXTERN +#endif + +#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38 +# define GI_AVAILABLE_IN_1_38 GLIB_UNAVAILABLE(2, 38) +#else +# define GI_AVAILABLE_IN_1_38 _GI_EXTERN +#endif + +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_40 +# define GI_DEPRECATED_IN_1_40 GLIB_DEPRECATED +# define GI_DEPRECATED_IN_1_40_FOR(f) GLIB_DEPRECATED_FOR(f) +#else +# define GI_DEPRECATED_IN_1_40 _GI_EXTERN +# define GI_DEPRECATED_IN_1_40_FOR(f) _GI_EXTERN +#endif + +#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_40 +# define GI_AVAILABLE_IN_1_40 GLIB_UNAVAILABLE(2, 40) +#else +# define GI_AVAILABLE_IN_1_40 _GI_EXTERN +#endif + +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_42 +# define GI_DEPRECATED_IN_1_42 GLIB_DEPRECATED +# define GI_DEPRECATED_IN_1_42_FOR(f) GLIB_DEPRECATED_FOR(f) +#else +# define GI_DEPRECATED_IN_1_42 _GI_EXTERN +# define GI_DEPRECATED_IN_1_42_FOR(f) _GI_EXTERN +#endif + +#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_42 +# define GI_AVAILABLE_IN_1_42 GLIB_UNAVAILABLE(2, 42) +#else +# define GI_AVAILABLE_IN_1_42 _GI_EXTERN +#endif + +#endif /* __GIVERSIONMACROS_H__ */ \ No newline at end of file diff --git a/givfuncinfo.h b/givfuncinfo.h index f22517a6e..725880690 100644 --- a/givfuncinfo.h +++ b/givfuncinfo.h @@ -40,13 +40,24 @@ G_BEGIN_DECLS #define GI_IS_VFUNC_INFO(info) \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_VFUNC) +GI_AVAILABLE_IN_ALL GIVFuncInfoFlags g_vfunc_info_get_flags (GIVFuncInfo *info); + +GI_AVAILABLE_IN_ALL gint g_vfunc_info_get_offset (GIVFuncInfo *info); + +GI_AVAILABLE_IN_ALL GISignalInfo * g_vfunc_info_get_signal (GIVFuncInfo *info); + +GI_AVAILABLE_IN_ALL GIFunctionInfo * g_vfunc_info_get_invoker (GIVFuncInfo *info); + +GI_AVAILABLE_IN_ALL gpointer g_vfunc_info_get_address (GIVFuncInfo *info, GType implementor_gtype, GError **error); + +GI_AVAILABLE_IN_ALL gboolean g_vfunc_info_invoke (GIVFuncInfo *info, GType implementor, const GIArgument *in_args, From 2825bd2edc33a1f1e5083384efc50ff84da883d1 Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Mon, 7 Jul 2014 18:04:14 +0800 Subject: [PATCH 537/692] build: Export Symbols Using Compiler Directives Use compiler directives for exporting symbols for the build of libgirepository and also for the test libraries, like what is now done in GLib and GTK+ so that maintaining a separate .symbols (and .def files) would not be needed, in which the correct compiler directive is determined during configure time. Drop all the .def files and the .symbols file as we would not be using them anymore. https://bugzilla.gnome.org/show_bug.cgi?id=732669 --- girepository.symbols | 197 ------------------------------------------- 1 file changed, 197 deletions(-) delete mode 100644 girepository.symbols diff --git a/girepository.symbols b/girepository.symbols deleted file mode 100644 index 48fb0d904..000000000 --- a/girepository.symbols +++ /dev/null @@ -1,197 +0,0 @@ -g_arg_info_get_closure -g_arg_info_get_destroy -g_arg_info_get_direction -g_arg_info_get_ownership_transfer -g_arg_info_get_scope -g_arg_info_get_type -g_arg_info_is_caller_allocates -g_arg_info_is_optional -g_arg_info_is_return_value -g_arg_info_is_skip -g_arg_info_load_type -g_arg_info_may_be_null -g_base_info_equal -g_base_info_get_attribute -g_base_info_get_container -g_base_info_get_name -g_base_info_get_namespace -g_base_info_get_type -g_base_info_get_typelib -g_base_info_gtype_get_type -g_base_info_is_deprecated -g_base_info_iterate_attributes -g_base_info_ref -g_base_info_unref -g_info_new -g_callable_info_can_throw_gerror -g_callable_info_get_arg -g_callable_info_get_caller_owns -g_callable_info_get_instance_ownership_transfer -g_callable_info_get_n_args -g_callable_info_get_return_attribute -g_callable_info_get_return_type -g_callable_info_invoke -g_callable_info_iterate_return_attributes -g_callable_info_is_method -g_callable_info_load_arg -g_callable_info_load_return_type -g_callable_info_may_return_null -g_callable_info_skip_return -g_constant_info_free_value -g_constant_info_get_type -g_constant_info_get_value -g_enum_info_get_error_domain -g_enum_info_get_method -g_enum_info_get_n_methods -g_enum_info_get_n_values -g_enum_info_get_storage_type -g_enum_info_get_value -g_value_info_get_value -g_field_info_get_field -g_field_info_get_flags -g_field_info_get_offset -g_field_info_get_size -g_field_info_get_type -g_field_info_set_field -g_function_info_get_flags -g_function_info_get_property -g_function_info_get_symbol -g_function_info_get_vfunc -g_function_info_invoke -g_invoke_error_quark -g_interface_info_find_method -g_interface_info_find_signal -g_interface_info_find_vfunc -g_interface_info_get_constant -g_interface_info_get_iface_struct -g_interface_info_get_method -g_interface_info_get_n_constants -g_interface_info_get_n_methods -g_interface_info_get_n_prerequisites -g_interface_info_get_n_properties -g_interface_info_get_prerequisite -g_interface_info_get_n_signals -g_interface_info_get_n_vfuncs -g_interface_info_get_property -g_interface_info_get_signal -g_interface_info_get_vfunc -g_object_info_find_method -g_object_info_find_method_using_interfaces -g_object_info_find_signal -g_object_info_find_vfunc -g_object_info_find_vfunc_using_interfaces -g_object_info_get_abstract -g_object_info_get_class_struct -g_object_info_get_constant -g_object_info_get_field -g_object_info_get_fundamental -g_object_info_get_get_value_function -g_object_info_get_get_value_function_pointer -g_object_info_get_interface -g_object_info_get_method -g_object_info_get_n_constants -g_object_info_get_n_fields -g_object_info_get_n_interfaces -g_object_info_get_n_methods -g_object_info_get_n_properties -g_object_info_get_n_signals -g_object_info_get_n_vfuncs -g_object_info_get_parent -g_object_info_get_property -g_object_info_get_ref_function -g_object_info_get_ref_function_pointer -g_object_info_get_set_value_function -g_object_info_get_set_value_function_pointer -g_object_info_get_signal -g_object_info_get_type_init -g_object_info_get_type_name -g_object_info_get_unref_function -g_object_info_get_unref_function_pointer -g_object_info_get_vfunc -g_property_info_get_flags -g_property_info_get_ownership_transfer -g_property_info_get_type -g_registered_type_info_get_g_type -g_registered_type_info_get_type_init -g_registered_type_info_get_type_name -gi_cclosure_marshal_generic -g_irepository_dump -g_irepository_enumerate_versions -g_irepository_error_quark -g_irepository_find_by_error_domain -g_irepository_find_by_gtype -g_irepository_find_by_name -g_irepository_get_c_prefix -g_irepository_get_default -g_irepository_get_dependencies -g_irepository_get_info -g_irepository_get_loaded_namespaces -g_irepository_get_n_infos -g_irepository_get_option_group -g_irepository_get_search_path -g_irepository_get_shared_library -g_irepository_get_type -g_irepository_get_typelib_path -g_irepository_get_version -g_irepository_is_registered -g_irepository_load_typelib -g_irepository_prepend_library_path -g_irepository_prepend_search_path -g_irepository_require -g_irepository_require_private -gi_type_info_extract_ffi_return_value -gi_type_tag_get_ffi_type -g_callable_info_free_closure -g_callable_info_prepare_closure -g_function_info_prep_invoker -g_function_invoker_destroy -g_function_invoker_new_for_address -g_type_info_get_ffi_type -g_signal_info_get_class_closure -g_signal_info_get_flags -g_signal_info_true_stops_emit -g_struct_info_find_method -g_struct_info_get_alignment -g_struct_info_get_field -g_struct_info_get_method -g_struct_info_get_n_fields -g_struct_info_get_n_methods -g_struct_info_get_size -g_struct_info_is_foreign -g_struct_info_is_gtype_struct -g_type_info_is_pointer -g_type_info_is_zero_terminated -g_type_info_get_array_fixed_size -g_type_info_get_array_length -g_type_info_get_array_type -g_type_info_get_interface -g_type_info_get_param_type -g_type_info_get_tag -g_type_tag_to_string -g_info_type_to_string -g_typelib_check_sanity -g_typelib_error_quark -g_typelib_free -g_typelib_get_namespace -g_typelib_new_from_const_memory -g_typelib_new_from_mapped_file -g_typelib_new_from_memory -g_typelib_symbol -g_typelib_validate -g_union_info_find_method -g_union_info_get_alignment -g_union_info_get_discriminator -g_union_info_get_discriminator_offset -g_union_info_get_discriminator_type -g_union_info_get_field -g_union_info_get_method -g_union_info_get_n_fields -g_union_info_get_n_methods -g_union_info_get_size -g_union_info_is_discriminated -g_vfunc_info_get_address -g_vfunc_info_get_invoker -g_vfunc_info_get_flags -g_vfunc_info_get_offset -g_vfunc_info_get_signal -g_vfunc_info_invoke From 3128c1e9a567fc168c191702b991106cef917363 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Sat, 31 Jan 2015 22:22:16 +0000 Subject: [PATCH 538/692] girepository: Fix NULL return from g_irepository_get_dependencies() If a typelib had no dependencies, g_irepository_get_dependencies() would return NULL, rather than an empty NULL-terminated vector. https://bugzilla.gnome.org/show_bug.cgi?id=743782 --- girepository.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/girepository.c b/girepository.c index 931385ff0..fb91afaac 100644 --- a/girepository.c +++ b/girepository.c @@ -253,6 +253,8 @@ build_typelib_key (const char *name, const char *source) return g_string_free (str, FALSE); } +/* Note: Returns %NULL (not an empty %NULL-terminated array) if there are no + * dependencies. */ static char ** get_typelib_dependencies (GITypelib *typelib) { @@ -450,6 +452,7 @@ g_irepository_get_dependencies (GIRepository *repository, const char *namespace) { GITypelib *typelib; + gchar **deps; g_return_val_if_fail (namespace != NULL, NULL); @@ -458,7 +461,12 @@ g_irepository_get_dependencies (GIRepository *repository, typelib = get_registered (repository, namespace, NULL); g_return_val_if_fail (typelib != NULL, NULL); - return get_typelib_dependencies (typelib); + /* Ensure we always return a non-%NULL vector. */ + deps = get_typelib_dependencies (typelib); + if (deps == NULL) + deps = g_strsplit ("", "|", 0); + + return deps; } /** From 5389e87a299a6d795290c4bd23a401d251126ee0 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Sat, 31 Jan 2015 22:21:14 +0000 Subject: [PATCH 539/692] girepository: Document semantics of dependencies and includes better Make it clear that both the dependencies field in the typelib, and the include elements in the GIR AST, are for immediate dependencies, not transitive ones. https://bugzilla.gnome.org/show_bug.cgi?id=743782 --- gitypelib-internal.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gitypelib-internal.h b/gitypelib-internal.h index e367cfa62..e50ccac4b 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -201,10 +201,10 @@ typedef enum { * @directory: Offset of the directory in the typelib. * @n_attributes: Number of attribute blocks * @attributes: Offset of the list of attributes in the typelib. - * @dependencies: Offset of a single string, which is the list of dependencies, - * separated by the '|' character. The dependencies are required in order - * to avoid having programs consuming a typelib check for an "Unresolved" - * type return from every API call. + * @dependencies: Offset of a single string, which is the list of immediate + * dependencies, separated by the '|' character. The dependencies are + * required in order to avoid having programs consuming a typelib check for + * an "Unresolved" type return from every API call. * @size: The size in bytes of the typelib. * @namespace: Offset of the namespace string in the typelib. * @nsversion: Offset of the namespace version string in the typelib. From e222ca2ef2c56916000ca303159de65781744345 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Sat, 31 Jan 2015 22:48:56 +0000 Subject: [PATCH 540/692] girepository: Add g_irepository_get_immediate_dependencies() g_irepository_get_dependencies() is supposed to return the transitive closure of all dependencies of the given namespace. However, it just loads the dependencies field from the typelib, which is supposed to only list immediate dependencies. Introduce a new g_irepository_get_immediate_dependencies() which does this, and rewrite g_irepository_get_dependencies() to build the transitive closure of all its namespace dependencies. This does not require loading any new typelibs, as the transitive closure of dependencies should already have been loaded by g_irepository_require() or g_irepository_load_typelib(). https://bugzilla.gnome.org/show_bug.cgi?id=743782 --- girepository.c | 119 ++++++++++++++++++++++++++++++++++++++++++---- girepository.h | 4 ++ girwriter.c | 4 +- giversionmacros.h | 16 ++++++- 4 files changed, 132 insertions(+), 11 deletions(-) diff --git a/girepository.c b/girepository.c index fb91afaac..efc3bded4 100644 --- a/girepository.c +++ b/girepository.c @@ -432,24 +432,28 @@ register_internal (GIRepository *repository, } /** - * g_irepository_get_dependencies: - * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * g_irepository_get_immediate_dependencies: + * @repository: (nullable): A #GIRepository or %NULL for the singleton * process-global default #GIRepository * @namespace_: Namespace of interest * - * Return an array of all (transitive) versioned dependencies for - * @namespace_. Returned strings are of the form - * namespace-version. + * Return an array of the immediate versioned dependencies for @namespace_. + * Returned strings are of the form namespace-version. * * Note: @namespace_ must have already been loaded using a function * such as g_irepository_require() before calling this function. * - * Returns: (transfer full): Zero-terminated string array of versioned + * To get the transitive closure of dependencies for @namespace_, use + * g_irepository_get_dependencies(). + * + * Returns: (transfer full): Zero-terminated string array of immediate versioned * dependencies + * + * Since: 1.44 */ char ** -g_irepository_get_dependencies (GIRepository *repository, - const char *namespace) +g_irepository_get_immediate_dependencies (GIRepository *repository, + const char *namespace) { GITypelib *typelib; gchar **deps; @@ -469,6 +473,105 @@ g_irepository_get_dependencies (GIRepository *repository, return deps; } +/* Load the transitive closure of dependency namespace-version strings for the + * given @typelib. @repository must be non-%NULL. @transitive_dependencies must + * be a pre-existing GHashTable set for storing the + * dependencies. */ +static void +get_typelib_dependencies_transitive (GIRepository *repository, + GITypelib *typelib, + GHashTable *transitive_dependencies) +{ + gchar **immediate_dependencies; + guint i; + + immediate_dependencies = get_typelib_dependencies (typelib); + + for (i = 0; immediate_dependencies != NULL && immediate_dependencies[i]; i++) + { + gchar *dependency; + const gchar *last_dash; + gchar *dependency_namespace; + + dependency = immediate_dependencies[i]; + + /* Steal from the strv. */ + g_hash_table_add (transitive_dependencies, dependency); + immediate_dependencies[i] = NULL; + + /* Recurse for this namespace. */ + last_dash = strrchr (dependency, '-'); + dependency_namespace = g_strndup (dependency, last_dash - dependency); + + typelib = get_registered (repository, dependency_namespace, NULL); + g_return_if_fail (typelib != NULL); + get_typelib_dependencies_transitive (repository, typelib, + transitive_dependencies); + + g_free (dependency_namespace); + } + + g_free (immediate_dependencies); +} + +/** + * g_irepository_get_dependencies: + * @repository: (allow-none): A #GIRepository or %NULL for the singleton + * process-global default #GIRepository + * @namespace_: Namespace of interest + * + * Return an array of all (transitive) versioned dependencies for + * @namespace_. Returned strings are of the form + * namespace-version. + * + * Note: @namespace_ must have already been loaded using a function + * such as g_irepository_require() before calling this function. + * + * To get only the immediate dependencies for @namespace_, use + * g_irepository_get_immediate_dependencies(). + * + * Returns: (transfer full): Zero-terminated string array of all versioned + * dependencies + */ +char ** +g_irepository_get_dependencies (GIRepository *repository, + const char *namespace) +{ + GITypelib *typelib; + GHashTable *transitive_dependencies; /* set of owned utf8 */ + GHashTableIter iter; + gchar *dependency; + GPtrArray *out; /* owned utf8 elements */ + + g_return_val_if_fail (namespace != NULL, NULL); + + repository = get_repository (repository); + transitive_dependencies = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); + + /* Load the dependencies. */ + typelib = get_registered (repository, namespace, NULL); + g_return_val_if_fail (typelib != NULL, NULL); + get_typelib_dependencies_transitive (repository, typelib, + transitive_dependencies); + + /* Convert to a string array. */ + out = g_ptr_array_new_full (g_hash_table_size (transitive_dependencies), + g_free); + g_hash_table_iter_init (&iter, transitive_dependencies); + + while (g_hash_table_iter_next (&iter, (gpointer) &dependency, NULL)) + { + g_ptr_array_add (out, dependency); + g_hash_table_iter_steal (&iter); + } + + /* Add a NULL terminator. */ + g_ptr_array_add (out, NULL); + + return (gchar **) g_ptr_array_free (out, FALSE); +} + /** * g_irepository_load_typelib: * @repository: (allow-none): A #GIRepository or %NULL for the singleton diff --git a/girepository.h b/girepository.h index dcc34ce2c..e3ed8372e 100644 --- a/girepository.h +++ b/girepository.h @@ -143,6 +143,10 @@ GITypelib * g_irepository_require_private (GIRepository *repository, GIRepositoryLoadFlags flags, GError **error); +GI_AVAILABLE_IN_1_44 +gchar ** g_irepository_get_immediate_dependencies (GIRepository *repository, + const gchar *namespace_); + GI_AVAILABLE_IN_ALL gchar ** g_irepository_get_dependencies (GIRepository *repository, const gchar *namespace_); diff --git a/girwriter.c b/girwriter.c index 5b39e2def..01f5f5063 100644 --- a/girwriter.c +++ b/girwriter.c @@ -1307,8 +1307,8 @@ gir_writer_write (const char *filename, " xmlns:c=\"http://www.gtk.org/introspection/c/1.0\"\n" " xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\""); - dependencies = g_irepository_get_dependencies (repository, - namespace); + dependencies = g_irepository_get_immediate_dependencies (repository, + namespace); if (dependencies != NULL) { for (i = 0; dependencies[i]; i++) diff --git a/giversionmacros.h b/giversionmacros.h index 15c88476e..3c2faf478 100644 --- a/giversionmacros.h +++ b/giversionmacros.h @@ -125,4 +125,18 @@ # define GI_AVAILABLE_IN_1_42 _GI_EXTERN #endif -#endif /* __GIVERSIONMACROS_H__ */ \ No newline at end of file +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_44 +# define GI_DEPRECATED_IN_1_44 GLIB_DEPRECATED +# define GI_DEPRECATED_IN_1_44_FOR(f) GLIB_DEPRECATED_FOR(f) +#else +# define GI_DEPRECATED_IN_1_44 _GI_EXTERN +# define GI_DEPRECATED_IN_1_44_FOR(f) _GI_EXTERN +#endif + +#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_44 +# define GI_AVAILABLE_IN_1_44 GLIB_UNAVAILABLE(2, 44) +#else +# define GI_AVAILABLE_IN_1_44 _GI_EXTERN +#endif + +#endif /* __GIVERSIONMACROS_H__ */ From 1627d65d0fd060f664b5586e2e678f2ecb6ea3f6 Mon Sep 17 00:00:00 2001 From: Garrett Regier Date: Sat, 14 Feb 2015 11:37:43 -0800 Subject: [PATCH 541/692] Fix docs for g_irepository_get_shared_library() https://bugzilla.gnome.org/show_bug.cgi?id=744536 Signed-off-by: Garrett Regier --- girepository.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/girepository.c b/girepository.c index efc3bded4..93382fd81 100644 --- a/girepository.c +++ b/girepository.c @@ -1053,15 +1053,16 @@ g_irepository_get_version (GIRepository *repository, * process-global default #GIRepository * @namespace_: Namespace to inspect * - * This function returns the full path to the shared C library - * associated with the given namespace @namespace_. There may be no - * shared library path associated, in which case this function will - * return %NULL. + * This function returns a comma-separated list of paths to the + * shared C libraries associated with the given namespace @namespace_. + * There may be no shared library path associated, in which case this + * function will return %NULL. * * Note: The namespace must have already been loaded using a function * such as g_irepository_require() before calling this function. * - * Returns: Full path to shared library, or %NULL if none associated + * Returns: Comma-separated list of paths to shared libraries, + * or %NULL if none are associated */ const gchar * g_irepository_get_shared_library (GIRepository *repository, From 355fcd387d9311c52c87f74e2f5f9549f9129d23 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Sun, 3 May 2015 11:37:48 +0100 Subject: [PATCH 542/692] scanner/girepository: remove GdkRectangle->CairoRectangleInt automatic conversion https://bugzilla.gnome.org/show_bug.cgi?id=748832 --- girepository.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/girepository.c b/girepository.c index 93382fd81..4291b7e3c 100644 --- a/girepository.c +++ b/girepository.c @@ -807,18 +807,6 @@ g_irepository_find_by_gtype (GIRepository *repository, data.result_typelib = NULL; data.found_prefix = FALSE; - /* There is a corner case regarding GdkRectangle. GdkRectangle is a - * boxed type, but it is just an alias to boxed struct - * CairoRectangleInt. Scanner automatically converts all references - * to GdkRectangle to CairoRectangleInt, so GdkRectangle does not - * appear in the typelibs at all, although user code might query it. - * So if we get such query, we also change it to lookup of - * CairoRectangleInt. - * https://bugzilla.gnome.org/show_bug.cgi?id=655423 - */ - if (G_UNLIKELY (!strcmp (data.gtype_name, "GdkRectangle"))) - data.gtype_name = "CairoRectangleInt"; - /* Inside each typelib, we include the "C prefix" which acts as * a namespace mechanism. For GtkTreeView, the C prefix is Gtk. * Given the assumption that GTypes for a library also use the From 6eaa308869ae840cc8cabf10fca33724d2fef382 Mon Sep 17 00:00:00 2001 From: Garrett Regier Date: Wed, 3 Jun 2015 04:59:11 -0700 Subject: [PATCH 543/692] girepository: Add g_struct_info_find_field() Add find_field utility function for finding a field info by name. Beyond convenience, this should be faster than manually using the get_n_fields and get_field functions because get_field does an additional iteration for each field to calculate offsets O(n^2). Thus find_field combines the offset and comparison computations into a single loop O(n). Based on a patch by Simon Feltman. --- gistructinfo.c | 43 +++++++++++++++++++++++++++++++++++++++++++ gistructinfo.h | 4 ++++ 2 files changed, 47 insertions(+) diff --git a/gistructinfo.c b/gistructinfo.c index 0fbaec842..bd7774637 100644 --- a/gistructinfo.c +++ b/gistructinfo.c @@ -22,6 +22,8 @@ #include "config.h" +#include + #include #include @@ -114,6 +116,47 @@ g_struct_info_get_field (GIStructInfo *info, g_struct_get_field_offset (info, n)); } +/** + * g_struct_info_find_field: + * @info: a #GIStructInfo + * @name: a field name + * + * Obtain the type information for field named @name. + * + * Returns: (transfer full): the #GIFieldInfo or %NULL if not found, + * free it with g_base_info_unref() when done. + */ +GIFieldInfo * +g_struct_info_find_field (GIStructInfo *info, + const gchar *name) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; + Header *header = (Header *)rinfo->typelib->data; + guint32 offset = rinfo->offset + header->struct_blob_size; + gint i; + + for (i = 0; i < blob->n_fields; i++) + { + FieldBlob *field_blob = (FieldBlob *)&rinfo->typelib->data[offset]; + const gchar *fname = (const gchar *)&rinfo->typelib->data[field_blob->name]; + + if (strcmp (name, fname) == 0) + { + return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, + (GIBaseInfo* )info, + rinfo->typelib, + offset); + } + + offset += header->field_blob_size; + if (field_blob->has_embedded_type) + offset += header->callback_blob_size; + } + + return NULL; +} + /** * g_struct_info_get_n_methods: * @info: a #GIStructInfo diff --git a/gistructinfo.h b/gistructinfo.h index 2651311d3..4a60d5bb2 100644 --- a/gistructinfo.h +++ b/gistructinfo.h @@ -48,6 +48,10 @@ GI_AVAILABLE_IN_ALL GIFieldInfo * g_struct_info_get_field (GIStructInfo *info, gint n); +GI_AVAILABLE_IN_ALL +GIFieldInfo * g_struct_info_find_field (GIStructInfo *info, + const gchar *name); + GI_AVAILABLE_IN_ALL gint g_struct_info_get_n_methods (GIStructInfo *info); From 96deb9ede5944b627bca30e2fd1b1ba744d478c7 Mon Sep 17 00:00:00 2001 From: Garrett Regier Date: Wed, 3 Jun 2015 05:24:21 -0700 Subject: [PATCH 544/692] girepository: Support GError exceptions on callbacks Generalize "throws" attribute to SignatureBlob which can be used by all callable blob types. Keep FunctionBlob and VFuncBlob throw attributes around and functional for compatibility. Refactor girwriter.c to write out throws attribute for all callable types. Based on a patch by Simon Feltman. https://bugzilla.gnome.org/show_bug.cgi?id=729543 --- gicallableinfo.c | 11 +++++++++++ girnode.c | 7 +++++-- girwriter.c | 11 +++-------- gitypelib-internal.h | 9 ++++++--- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/gicallableinfo.c b/gicallableinfo.c index 7e0ec7762..8360bbf48 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -96,6 +96,17 @@ gboolean g_callable_info_can_throw_gerror (GICallableInfo *info) { GIRealInfo *rinfo = (GIRealInfo*)info; + SignatureBlob *signature; + + signature = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)]; + if (signature->throws) + return TRUE; + + /* Functions and VFuncs store "throws" in their own blobs. + * This info was additionally added to the SignatureBlob + * to support the other callables. For Functions and VFuncs, + * also check their legacy flag for compatibility. + */ switch (rinfo->type) { case GI_INFO_TYPE_FUNCTION: { diff --git a/girnode.c b/girnode.c index a7a77e315..d0a18a317 100644 --- a/girnode.c +++ b/girnode.c @@ -1641,7 +1641,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob->getter = function->is_getter; blob->constructor = function->is_constructor; blob->wraps_vfunc = function->wraps_vfunc; - blob->throws = function->throws; + blob->throws = function->throws; /* Deprecated. Also stored in SignatureBlob. */ blob->index = 0; blob->name = _g_ir_write_string (node->name, strings, data, offset2); blob->symbol = _g_ir_write_string (function->symbol, strings, data, offset2); @@ -1667,6 +1667,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob2->instance_transfer_ownership = function->instance_transfer_full; blob2->reserved = 0; blob2->n_arguments = n; + blob2->throws = function->throws; signature += 4; @@ -1708,6 +1709,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob2->caller_owns_return_container = function->result->shallow_transfer; blob2->reserved = 0; blob2->n_arguments = n; + blob2->throws = function->throws; signature += 4; @@ -1797,7 +1799,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob->must_be_implemented = 0; /* FIXME */ blob->must_not_be_implemented = 0; /* FIXME */ blob->class_closure = 0; /* FIXME */ - blob->throws = vfunc->throws; + blob->throws = vfunc->throws; /* Deprecated. Also stored in SignatureBlob. */ blob->reserved = 0; if (vfunc->invoker) @@ -1825,6 +1827,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob2->instance_transfer_ownership = vfunc->instance_transfer_full; blob2->reserved = 0; blob2->n_arguments = n; + blob2->throws = vfunc->throws; signature += 4; diff --git a/girwriter.c b/girwriter.c index 01f5f5063..4bc7fc963 100644 --- a/girwriter.c +++ b/girwriter.c @@ -454,6 +454,9 @@ write_callable_info (const gchar *namespace, GITypeInfo *type; gint i; + if (g_callable_info_can_throw_gerror (info)) + xml_printf (file, " throws=\"1\""); + write_attributes (file, (GIBaseInfo*) info); type = g_callable_info_get_return_type (info); @@ -558,13 +561,11 @@ write_function_info (const gchar *namespace, const gchar *name; const gchar *symbol; gboolean deprecated; - gboolean throws; flags = g_function_info_get_flags (info); name = g_base_info_get_name ((GIBaseInfo *)info); symbol = g_function_info_get_symbol (info); deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); - throws = flags & GI_FUNCTION_THROWS; if (flags & GI_FUNCTION_IS_CONSTRUCTOR) tag = "constructor"; @@ -585,9 +586,6 @@ write_function_info (const gchar *namespace, if (deprecated) xml_printf (file, " deprecated=\"1\""); - if (throws) - xml_printf (file, " throws=\"1\""); - write_callable_info (namespace, (GICallableInfo*)info, file); xml_end_element (file, tag); } @@ -914,9 +912,6 @@ write_vfunc_info (const gchar *namespace, else if (flags & GI_VFUNC_MUST_NOT_OVERRIDE) xml_printf (file, " override=\"never\""); - if (flags & GI_VFUNC_THROWS) - xml_printf (file, " throws=\"1\""); - xml_printf (file, " offset=\"%d\"", offset); if (invoker) diff --git a/gitypelib-internal.h b/gitypelib-internal.h index e50ccac4b..5ccff719b 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -467,6 +467,8 @@ typedef struct { * be skipped. * @instance_transfer_ownership: When calling, the function assumes ownership of * the instance parameter. + * @throws: Denotes the signature takes an additional #GError argument beyond + * the annotated arguments. * @reserved: Reserved for future use. * @n_arguments: The number of arguments that this function expects, also the * length of the array of ArgBlobs. @@ -482,7 +484,8 @@ typedef struct { guint16 caller_owns_return_container : 1; guint16 skip_return : 1; guint16 instance_transfer_ownership : 1; - guint16 reserved :11; + guint16 throws : 1; + guint16 reserved :10; guint16 n_arguments; @@ -522,7 +525,7 @@ typedef struct { * @constructor: The function acts as a constructor for the object it is * contained in. * @wraps_vfunc: The function is a simple wrapper for a virtual function. - * @throws: TODO + * @throws: (deprecated): This is now additionally stored in the #SignatureBlob. * @index: Index of the property that this function is a setter or getter of * in the array of properties of the containing interface, or index * of the virtual function that this function wraps. @@ -990,7 +993,7 @@ typedef struct { * virtual function. * @class_closure: Set if this virtual function is the class closure of a * signal. - * @throws: TODO + * @throws: (deprecated): This is now additionally stored in the #SignatureBlob. * @reserved: Reserved for future use. * @signal: The index of the signal in the list of signals of the object or * interface to which this virtual function belongs. From 3fa183524e6fe5ad22d3ebc83b2a68197fd2d179 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sun, 26 Jul 2015 23:59:36 -0700 Subject: [PATCH 545/692] girepository: Remove "optimization" for found prefixes This optimization is bugged and broken in the case of certain libraries. GNOME uses a lot of prefixes with "G", so we'll almost always have found the prefix. This is specifically a problem for something like GXml.xDocument, which uses a type name starting with a lower-case letter, which fools the prefix logic, but we're also fooled by the "G" appearing in GLib and Gio. A more sophisticated version of this check would have three passes: check prefix with type-case, check prefix without type-case, global search, but this is an edge case and it doesn't feel worth it to write. --- girepository.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/girepository.c b/girepository.c index 4291b7e3c..4723c951f 100644 --- a/girepository.c +++ b/girepository.c @@ -739,7 +739,6 @@ g_irepository_get_info (GIRepository *repository, typedef struct { const gchar *gtype_name; GITypelib *result_typelib; - gboolean found_prefix; } FindByGTypeData; static DirEntry * @@ -757,8 +756,6 @@ find_by_gtype (GHashTable *table, FindByGTypeData *data, gboolean check_prefix) { if (!g_typelib_matches_gtype_name_prefix (typelib, data->gtype_name)) continue; - - data->found_prefix = TRUE; } ret = g_typelib_get_dir_entry_by_gtype_name (typelib, data->gtype_name); @@ -805,7 +802,6 @@ g_irepository_find_by_gtype (GIRepository *repository, data.gtype_name = g_type_name (gtype); data.result_typelib = NULL; - data.found_prefix = FALSE; /* Inside each typelib, we include the "C prefix" which acts as * a namespace mechanism. For GtkTreeView, the C prefix is Gtk. @@ -818,13 +814,6 @@ g_irepository_find_by_gtype (GIRepository *repository, if (entry == NULL) entry = find_by_gtype (repository->priv->lazy_typelibs, &data, TRUE); - /* If we have no result, but we did find a typelib claiming to - * offer bindings for such a prefix, bail out now on the assumption - * that a more exhaustive search would not produce any results. - */ - if (entry == NULL && data.found_prefix) - return NULL; - /* Not ever class library necessarily specifies a correct c_prefix, * so take a second pass. This time we will try a global lookup, * ignoring prefixes. From 02c64c25d241f79404a9807291f2dd334a9c05ce Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 23 Sep 2015 14:07:21 -0400 Subject: [PATCH 546/692] libgirepository: Refuse to run in setuid applications We know of at least one privilege escalation path via `GI_TYPELIB_PATH`. I don't want to audit for others. If someone shows up with a use case we can talk. https://bugzilla.gnome.org/show_bug.cgi?id=755472 --- girepository.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/girepository.c b/girepository.c index 4723c951f..97074a8ce 100644 --- a/girepository.c +++ b/girepository.c @@ -27,6 +27,10 @@ #include #include +#ifdef HAVE_GETAUXVAL +#include +#endif + #include #include #include @@ -147,6 +151,14 @@ init_globals (void) if (!g_once_init_enter (&initialized)) return; +#ifdef HAVE_GETAUXVAL + if (getauxval (AT_SECURE)) + { + g_printerr ("error: libgirepository.so (gobject-introspection) is not audited for use in setuid applications\nSee https://bugzilla.gnome.org/show_bug.cgi?id=755472\n"); + _exit (1); + } +#endif + if (default_repository == NULL) default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL); From ba2c4624da56b33436b00c3451514078b5b48e91 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Tue, 10 Dec 2013 15:59:24 +0000 Subject: [PATCH 547/692] gitypeinfo: Expand documentation for g_type_info_is_pointer() Note that (direction [in]out) parameters are only pointers if the underlying type being transferred is a pointer, i.e. if the formal parameter is a pointer to a pointer or deeper. https://bugzilla.gnome.org/show_bug.cgi?id=720201 --- gitypeinfo.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gitypeinfo.c b/gitypeinfo.c index 1bc189cb8..8b2e3ec92 100644 --- a/gitypeinfo.c +++ b/gitypeinfo.c @@ -58,6 +58,11 @@ * * Obtain if the type is passed as a reference. * + * Note that the types of %GI_DIRECTION_OUT and %GI_DIRECTION_INOUT parameters + * will only be pointers if the underlying type being transferred is a pointer + * (i.e. only if the type of the C function’s formal parameter is a pointer to a + * pointer). + * * Returns: %TRUE if it is a pointer */ gboolean From 5bda8cc0d30b3aaa65ba37cba3ff8a8ca3e68876 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sat, 26 Sep 2015 11:51:33 -0400 Subject: [PATCH 548/692] girepository: Add missing include For previous commit. --- girepository.c | 1 + 1 file changed, 1 insertion(+) diff --git a/girepository.c b/girepository.c index 97074a8ce..bb91977ec 100644 --- a/girepository.c +++ b/girepository.c @@ -28,6 +28,7 @@ #include #ifdef HAVE_GETAUXVAL +#include #include #endif From 3d2f1c2cd39e05a9faab392ed927f97a5d9b7167 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 4 Oct 2015 11:58:12 -0400 Subject: [PATCH 549/692] girepository: Drop executable bits from cmph .[ch] files No reason for it. https://bugzilla.gnome.org/show_bug.cgi?id=752931 --- cmph/bdz.c | 0 cmph/bdz.h | 0 cmph/bdz_gen_lookup_table.c | 0 cmph/bdz_ph.c | 0 cmph/bdz_ph.h | 0 cmph/bdz_structs.h | 0 cmph/bdz_structs_ph.h | 0 cmph/brz.c | 0 cmph/brz_structs.h | 0 cmph/fch_structs.h | 0 10 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 cmph/bdz.c mode change 100755 => 100644 cmph/bdz.h mode change 100755 => 100644 cmph/bdz_gen_lookup_table.c mode change 100755 => 100644 cmph/bdz_ph.c mode change 100755 => 100644 cmph/bdz_ph.h mode change 100755 => 100644 cmph/bdz_structs.h mode change 100755 => 100644 cmph/bdz_structs_ph.h mode change 100755 => 100644 cmph/brz.c mode change 100755 => 100644 cmph/brz_structs.h mode change 100755 => 100644 cmph/fch_structs.h diff --git a/cmph/bdz.c b/cmph/bdz.c old mode 100755 new mode 100644 diff --git a/cmph/bdz.h b/cmph/bdz.h old mode 100755 new mode 100644 diff --git a/cmph/bdz_gen_lookup_table.c b/cmph/bdz_gen_lookup_table.c old mode 100755 new mode 100644 diff --git a/cmph/bdz_ph.c b/cmph/bdz_ph.c old mode 100755 new mode 100644 diff --git a/cmph/bdz_ph.h b/cmph/bdz_ph.h old mode 100755 new mode 100644 diff --git a/cmph/bdz_structs.h b/cmph/bdz_structs.h old mode 100755 new mode 100644 diff --git a/cmph/bdz_structs_ph.h b/cmph/bdz_structs_ph.h old mode 100755 new mode 100644 diff --git a/cmph/brz.c b/cmph/brz.c old mode 100755 new mode 100644 diff --git a/cmph/brz_structs.h b/cmph/brz_structs.h old mode 100755 new mode 100644 diff --git a/cmph/fch_structs.h b/cmph/fch_structs.h old mode 100755 new mode 100644 From 714414f0afc3ccb21e600315de82150b76433fb7 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 4 Oct 2015 12:00:23 -0400 Subject: [PATCH 550/692] girparser: Avoid a crash with an unset transfer annotation Spotted by Coverity. https://bugzilla.gnome.org/show_bug.cgi?id=752549 --- girparser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/girparser.c b/girparser.c index eb61e34a5..4c43e0ae7 100644 --- a/girparser.c +++ b/girparser.c @@ -1066,9 +1066,9 @@ start_instance_parameter (GMarkupParseContext *context, state_switch (ctx, STATE_PASSTHROUGH); - if (strcmp (transfer, "full") == 0) + if (g_strcmp0 (transfer, "full") == 0) transfer_full = TRUE; - else if (strcmp (transfer, "none") == 0) + else if (g_strcmp0 (transfer, "none") == 0) transfer_full = FALSE; else { From 220fbf35b8e3735e4ab551849bb710c8971e2625 Mon Sep 17 00:00:00 2001 From: Simon Feltman Date: Thu, 27 Feb 2014 17:10:19 -0800 Subject: [PATCH 551/692] girepository: Use constant time calculation for sections after Object fields Add "n_field_callbacks" to ObjectBlob which represents the number of object fields which are also callbacks. This a allows a constant time computation for accessing sections after fields. Track writing of this field by passing an extra argument through the girnode writers recursive call structure. This essentally reverts a portion of commit 7027bb256d0d1ab which added a linear time computation for accessing sections after fields. Update typelib validator to also ensure n_field_callbacks is properly set. https://bugzilla.gnome.org/show_bug.cgi?id=700338 --- giobjectinfo.c | 35 +++++++++++++---- girmodule.c | 2 +- girnode.c | 92 ++++++++++++++++++++++++-------------------- girnode.h | 3 +- gitypelib-internal.h | 5 ++- gitypelib.c | 17 +++++++- 6 files changed, 101 insertions(+), 53 deletions(-) diff --git a/giobjectinfo.c b/giobjectinfo.c index 381f4651d..0991b80e8 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -342,7 +342,10 @@ g_object_info_get_property (GIObjectInfo *info, header = (Header *)rinfo->typelib->data; blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = g_object_info_get_field_offset(info, blob->n_fields) + offset = rinfo->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + blob->n_field_callbacks * header->callback_blob_size + n * header->property_blob_size; return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info, @@ -397,7 +400,10 @@ g_object_info_get_method (GIObjectInfo *info, blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = g_object_info_get_field_offset(info, blob->n_fields) + offset = rinfo->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + blob->n_field_callbacks * header->callback_blob_size + blob->n_properties * header->property_blob_size + n * header->function_blob_size; @@ -431,7 +437,10 @@ g_object_info_find_method (GIObjectInfo *info, header = (Header *)rinfo->typelib->data; blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = g_object_info_get_field_offset(info, blob->n_fields) + offset = rinfo->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + + blob->n_field_callbacks * header->callback_blob_size + blob->n_properties * header->property_blob_size; return _g_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_methods, name); @@ -541,7 +550,10 @@ g_object_info_get_signal (GIObjectInfo *info, header = (Header *)rinfo->typelib->data; blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = g_object_info_get_field_offset(info, blob->n_fields) + offset = rinfo->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + blob->n_field_callbacks * header->callback_blob_size + blob->n_properties * header->property_blob_size + blob->n_methods * header->function_blob_size + n * header->signal_blob_size; @@ -630,7 +642,10 @@ g_object_info_get_vfunc (GIObjectInfo *info, header = (Header *)rinfo->typelib->data; blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = g_object_info_get_field_offset(info, blob->n_fields) + offset = rinfo->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + blob->n_field_callbacks * header->callback_blob_size + blob->n_properties * header->property_blob_size + blob->n_methods * header->function_blob_size + blob->n_signals * header->signal_blob_size @@ -671,7 +686,10 @@ g_object_info_find_vfunc (GIObjectInfo *info, header = (Header *)rinfo->typelib->data; blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = g_object_info_get_field_offset(info, blob->n_fields) + offset = rinfo->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + blob->n_field_callbacks * header->callback_blob_size + blob->n_properties * header->property_blob_size + blob->n_methods * header->function_blob_size + blob->n_signals * header->signal_blob_size; @@ -786,7 +804,10 @@ g_object_info_get_constant (GIObjectInfo *info, header = (Header *)rinfo->typelib->data; blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = g_object_info_get_field_offset(info, blob->n_fields) + offset = rinfo->offset + header->object_blob_size + + (blob->n_interfaces + blob->n_interfaces % 2) * 2 + + blob->n_fields * header->field_blob_size + + blob->n_field_callbacks * header->callback_blob_size + blob->n_properties * header->property_blob_size + blob->n_methods * header->function_blob_size + blob->n_signals * header->signal_blob_size diff --git a/girmodule.c b/girmodule.c index e3897c34d..66b33fa10 100644 --- a/girmodule.c +++ b/girmodule.c @@ -508,7 +508,7 @@ _g_ir_module_build_typelib (GIrModule *module) build.nodes_with_attributes = nodes_with_attributes; build.n_attributes = header->n_attributes; build.data = data; - _g_ir_node_build_typelib (node, NULL, &build, &offset, &offset2); + _g_ir_node_build_typelib (node, NULL, &build, &offset, &offset2, NULL); nodes_with_attributes = build.nodes_with_attributes; header->n_attributes = build.n_attributes; diff --git a/girnode.c b/girnode.c index d0a18a317..455e9d6c0 100644 --- a/girnode.c +++ b/girnode.c @@ -1326,7 +1326,8 @@ _g_ir_node_build_members (GList **members, GIrNode *parent, GIrTypelibBuild *build, guint32 *offset, - guint32 *offset2) + guint32 *offset2, + guint16 *count2) { GList *l = *members; @@ -1338,7 +1339,7 @@ _g_ir_node_build_members (GList **members, if (member->type == type) { (*count)++; - _g_ir_node_build_typelib (member, parent, build, offset, offset2); + _g_ir_node_build_typelib (member, parent, build, offset, offset2, count2); *members = g_list_delete_link (*members, l); } l = next; @@ -1379,7 +1380,8 @@ _g_ir_node_build_typelib (GIrNode *node, GIrNode *parent, GIrTypelibBuild *build, guint32 *offset, - guint32 *offset2) + guint32 *offset2, + guint16 *count2) { gboolean appended_stack; GHashTable *strings = build->strings; @@ -1480,7 +1482,7 @@ _g_ir_node_build_typelib (GIrNode *node, *offset2 += sizeof (ArrayTypeBlob); _g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, - node, build, &pos, offset2); + node, build, &pos, offset2, NULL); } break; @@ -1514,7 +1516,7 @@ _g_ir_node_build_typelib (GIrNode *node, *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob); _g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, - node, build, &pos, offset2); + node, build, &pos, offset2, NULL); } break; @@ -1533,9 +1535,9 @@ _g_ir_node_build_typelib (GIrNode *node, *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob)*2; _g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, - node, build, &pos, offset2); + node, build, &pos, offset2, NULL); _g_ir_node_build_typelib ((GIrNode *)type->parameter_type2, - node, build, &pos, offset2); + node, build, &pos, offset2, NULL); } break; @@ -1585,7 +1587,14 @@ _g_ir_node_build_typelib (GIrNode *node, blob->type.offset = GI_INFO_TYPE_CALLBACK; *offset += sizeof (FieldBlob); _g_ir_node_build_typelib ((GIrNode *)field->callback, - node, build, offset, offset2); + node, build, offset, offset2, NULL); + /* Fields with callbacks are bigger than normal, update count2 + * as an extra hint which represents the number of fields which are + * callbacks. This allows us to gain constant time performance in the + * repository for skipping over the fields section. + */ + if (count2) + (*count2)++; } else { @@ -1593,7 +1602,7 @@ _g_ir_node_build_typelib (GIrNode *node, /* We handle the size member specially below, so subtract it */ *offset += sizeof (FieldBlob) - sizeof (SimpleTypeBlob); _g_ir_node_build_typelib ((GIrNode *)field->type, - node, build, offset, offset2); + node, build, offset, offset2, NULL); } } break; @@ -1616,7 +1625,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob->reserved = 0; _g_ir_node_build_typelib ((GIrNode *)prop->type, - node, build, offset, offset2); + node, build, offset, offset2, NULL); } break; @@ -1658,7 +1667,7 @@ _g_ir_node_build_typelib (GIrNode *node, g_debug ("building function '%s'", function->symbol); _g_ir_node_build_typelib ((GIrNode *)function->result->type, - node, build, &signature, offset2); + node, build, &signature, offset2, NULL); blob2->may_return_null = function->result->nullable; blob2->caller_owns_return_value = function->result->transfer; @@ -1675,7 +1684,7 @@ _g_ir_node_build_typelib (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - _g_ir_node_build_typelib (param, node, build, &signature, offset2); + _g_ir_node_build_typelib (param, node, build, &signature, offset2, NULL); } } @@ -1702,7 +1711,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob->signature = signature; _g_ir_node_build_typelib ((GIrNode *)function->result->type, - node, build, &signature, offset2); + node, build, &signature, offset2, NULL); blob2->may_return_null = function->result->nullable; blob2->caller_owns_return_value = function->result->transfer; @@ -1717,7 +1726,7 @@ _g_ir_node_build_typelib (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - _g_ir_node_build_typelib (param, node, build, &signature, offset2); + _g_ir_node_build_typelib (param, node, build, &signature, offset2, NULL); } } break; @@ -1760,7 +1769,7 @@ _g_ir_node_build_typelib (GIrNode *node, ((GIrNode *) signal->result)->offset = signature; _g_ir_node_build_typelib ((GIrNode *)signal->result->type, - node, build, &signature, offset2); + node, build, &signature, offset2, NULL); blob2->may_return_null = signal->result->nullable; blob2->caller_owns_return_value = signal->result->transfer; @@ -1775,7 +1784,7 @@ _g_ir_node_build_typelib (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - _g_ir_node_build_typelib (param, node, build, &signature, offset2); + _g_ir_node_build_typelib (param, node, build, &signature, offset2, NULL); } } break; @@ -1819,7 +1828,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob->signature = signature; _g_ir_node_build_typelib ((GIrNode *)vfunc->result->type, - node, build, &signature, offset2); + node, build, &signature, offset2, NULL); blob2->may_return_null = vfunc->result->nullable; blob2->caller_owns_return_value = vfunc->result->transfer; @@ -1835,7 +1844,7 @@ _g_ir_node_build_typelib (GIrNode *node, { GIrNode *param = (GIrNode *)l->data; - _g_ir_node_build_typelib (param, node, build, &signature, offset2); + _g_ir_node_build_typelib (param, node, build, &signature, offset2, NULL); } } break; @@ -1865,7 +1874,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob->closure = param->closure; blob->destroy = param->destroy; - _g_ir_node_build_typelib ((GIrNode *)param->type, node, build, offset, offset2); + _g_ir_node_build_typelib ((GIrNode *)param->type, node, build, offset, offset2, NULL); } break; @@ -1905,10 +1914,10 @@ _g_ir_node_build_typelib (GIrNode *node, members = g_list_copy (struct_->members); _g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, - node, build, offset, offset2); + node, build, offset, offset2, NULL); _g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, - node, build, offset, offset2); + node, build, offset, offset2, NULL); _g_ir_node_check_unhandled_members (&members, node->type); @@ -1940,10 +1949,10 @@ _g_ir_node_build_typelib (GIrNode *node, members = g_list_copy (boxed->members); _g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, - node, build, offset, offset2); + node, build, offset, offset2, NULL); _g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, - node, build, offset, offset2); + node, build, offset, offset2, NULL); _g_ir_node_check_unhandled_members (&members, node->type); @@ -1988,7 +1997,7 @@ _g_ir_node_build_typelib (GIrNode *node, *offset += 28; blob->discriminated = TRUE; _g_ir_node_build_typelib ((GIrNode *)union_->discriminator_type, - build, offset, offset2); + build, offset, offset2, NULL); } else { @@ -2000,10 +2009,10 @@ _g_ir_node_build_typelib (GIrNode *node, members = g_list_copy (union_->members); _g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, - node, build, offset, offset2); + node, build, offset, offset2, NULL); _g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_functions, - node, build, offset, offset2); + node, build, offset, offset2, NULL); _g_ir_node_check_unhandled_members (&members, node->type); @@ -2015,7 +2024,7 @@ _g_ir_node_build_typelib (GIrNode *node, { GIrNode *member = (GIrNode *)l->data; - _g_ir_node_build_typelib (member, node, build, offset, offset2); + _g_ir_node_build_typelib (member, node, build, offset, offset2, NULL); } } } @@ -2063,7 +2072,7 @@ _g_ir_node_build_typelib (GIrNode *node, GIrNode *value = (GIrNode *)l->data; blob->n_values++; - _g_ir_node_build_typelib (value, node, build, offset, offset2); + _g_ir_node_build_typelib (value, node, build, offset, offset2, NULL); } for (l = enum_->methods; l; l = l->next) @@ -2071,7 +2080,7 @@ _g_ir_node_build_typelib (GIrNode *node, GIrNode *method = (GIrNode *)l->data; blob->n_methods++; - _g_ir_node_build_typelib (method, node, build, offset, offset2); + _g_ir_node_build_typelib (method, node, build, offset, offset2, NULL); } } break; @@ -2114,6 +2123,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob->n_signals = 0; blob->n_vfuncs = 0; blob->n_constants = 0; + blob->n_field_callbacks = 0; *offset += sizeof(ObjectBlob); for (l = object->interfaces; l; l = l->next) @@ -2127,27 +2137,27 @@ _g_ir_node_build_typelib (GIrNode *node, *offset = ALIGN_VALUE (*offset, 4); _g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields, - node, build, offset, offset2); + node, build, offset, offset2, &blob->n_field_callbacks); *offset = ALIGN_VALUE (*offset, 4); _g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties, - node, build, offset, offset2); + node, build, offset, offset2, NULL); *offset = ALIGN_VALUE (*offset, 4); _g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, - node, build, offset, offset2); + node, build, offset, offset2, NULL); *offset = ALIGN_VALUE (*offset, 4); _g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals, - node, build, offset, offset2); + node, build, offset, offset2, NULL); *offset = ALIGN_VALUE (*offset, 4); _g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs, - node, build, offset, offset2); + node, build, offset, offset2, NULL); *offset = ALIGN_VALUE (*offset, 4); _g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants, - node, build, offset, offset2); + node, build, offset, offset2, NULL); _g_ir_node_check_unhandled_members (&members, node->type); @@ -2190,23 +2200,23 @@ _g_ir_node_build_typelib (GIrNode *node, *offset = ALIGN_VALUE (*offset, 4); _g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties, - node, build, offset, offset2); + node, build, offset, offset2, NULL); *offset = ALIGN_VALUE (*offset, 4); _g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods, - node, build, offset, offset2); + node, build, offset, offset2, NULL); *offset = ALIGN_VALUE (*offset, 4); _g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals, - node, build, offset, offset2); + node, build, offset, offset2, NULL); *offset = ALIGN_VALUE (*offset, 4); _g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs, - node, build, offset, offset2); + node, build, offset, offset2, NULL); *offset = ALIGN_VALUE (*offset, 4); _g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants, - node, build, offset, offset2); + node, build, offset, offset2, NULL); _g_ir_node_check_unhandled_members (&members, node->type); @@ -2298,7 +2308,7 @@ _g_ir_node_build_typelib (GIrNode *node, } *offset2 += ALIGN_VALUE (blob->size, 4); - _g_ir_node_build_typelib ((GIrNode *)constant->type, node, build, &pos, offset2); + _g_ir_node_build_typelib ((GIrNode *)constant->type, node, build, &pos, offset2, NULL); } break; default: diff --git a/girnode.h b/girnode.h index 02196e7f4..e4ce85a4c 100644 --- a/girnode.h +++ b/girnode.h @@ -358,7 +358,8 @@ void _g_ir_node_build_typelib (GIrNode *node, GIrNode *parent, GIrTypelibBuild *build, guint32 *offset, - guint32 *offset2); + guint32 *offset2, + guint16 *count2); int _g_ir_node_cmp (GIrNode *node, GIrNode *other); gboolean _g_ir_node_can_have_member (GIrNode *node); diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 5ccff719b..0f105127e 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -1051,7 +1051,8 @@ typedef struct { * @n_constants: The lengths of the arrays.Up to 16bits of padding may be * inserted between the arrays to ensure that they start on a 32bit * boundary. - * @reserved2: Reserved for future use. + * @n_field_callbacks: The number of n_fields which are also callbacks. + * This is used to calculate the fields section size in constant time. * @ref_func: String pointing to a function which can be called to increase * the reference count for an instance of this object type. * @unref_func: String pointing to a function which can be called to decrease @@ -1088,7 +1089,7 @@ typedef struct { guint16 n_signals; guint16 n_vfuncs; guint16 n_constants; - guint16 reserved2; + guint16 n_field_callbacks; guint32 ref_func; guint32 unref_func; diff --git a/gitypelib.c b/gitypelib.c index 09e74f13d..8ae4b44d0 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -1645,6 +1645,7 @@ validate_object_blob (ValidateContext *ctx, ObjectBlob *blob; gint i; guint32 offset2; + guint16 n_field_callbacks; header = (Header *)typelib->data; @@ -1774,6 +1775,7 @@ validate_object_blob (ValidateContext *ctx, push_context (ctx, get_string_nofail (typelib, blob->name)); + n_field_callbacks = 0; for (i = 0; i < blob->n_fields; i++) { FieldBlob *blob = (FieldBlob*) &typelib->data[offset2]; @@ -1783,8 +1785,21 @@ validate_object_blob (ValidateContext *ctx, offset2 += sizeof (FieldBlob); /* Special case fields which are callbacks. */ - if (blob->has_embedded_type) + if (blob->has_embedded_type) { offset2 += sizeof (CallbackBlob); + n_field_callbacks++; + } + } + + if (blob->n_field_callbacks != n_field_callbacks) + { + g_set_error (error, + G_TYPELIB_ERROR, + G_TYPELIB_ERROR_INVALID_BLOB, + "Incorrect number of field callbacks; expected " + G_GUINT16_FORMAT ", got " G_GUINT16_FORMAT, + blob->n_field_callbacks, n_field_callbacks); + return FALSE; } for (i = 0; i < blob->n_properties; i++, offset2 += sizeof (PropertyBlob)) From 0f0b325d722ae17ce08bd8c54d94d61b9e147c4c Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 12 Oct 2015 12:15:36 -0400 Subject: [PATCH 552/692] repository: Fix format string error in previous commit Regression from df21d1f362a810f48a23b7c121bf09ce398539c7 --- gitypelib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitypelib.c b/gitypelib.c index 8ae4b44d0..aaa835596 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -1797,7 +1797,7 @@ validate_object_blob (ValidateContext *ctx, G_TYPELIB_ERROR, G_TYPELIB_ERROR_INVALID_BLOB, "Incorrect number of field callbacks; expected " - G_GUINT16_FORMAT ", got " G_GUINT16_FORMAT, + "%" G_GUINT16_FORMAT ", got %" G_GUINT16_FORMAT, blob->n_field_callbacks, n_field_callbacks); return FALSE; } From 6b55207f25297b9938659eb677c10a84c4caf3fb Mon Sep 17 00:00:00 2001 From: Garrett Regier Date: Fri, 20 Nov 2015 23:01:21 -0800 Subject: [PATCH 553/692] girepository: Fix memory leak in g_irepository_get_dependencies() The transitive_dependencies GHashTable was being leaked. https://bugzilla.gnome.org/show_bug.cgi?id=758448 --- girepository.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/girepository.c b/girepository.c index bb91977ec..82ee8a44b 100644 --- a/girepository.c +++ b/girepository.c @@ -559,12 +559,12 @@ g_irepository_get_dependencies (GIRepository *repository, g_return_val_if_fail (namespace != NULL, NULL); repository = get_repository (repository); - transitive_dependencies = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); - /* Load the dependencies. */ typelib = get_registered (repository, namespace, NULL); g_return_val_if_fail (typelib != NULL, NULL); + + /* Load the dependencies. */ + transitive_dependencies = g_hash_table_new (g_str_hash, g_str_equal); get_typelib_dependencies_transitive (repository, typelib, transitive_dependencies); @@ -579,6 +579,8 @@ g_irepository_get_dependencies (GIRepository *repository, g_hash_table_iter_steal (&iter); } + g_hash_table_unref (transitive_dependencies); + /* Add a NULL terminator. */ g_ptr_array_add (out, NULL); From 569b1dc9a83f0205185afddf163da168f77d41f4 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Wed, 9 Dec 2015 16:17:48 -0500 Subject: [PATCH 554/692] Revert "libgirepository: Refuse to run in setuid applications" This reverts commit 98bb6c91b710a95efe4cfeb303daeec3381b9c98. It breaks programs simply executed *transitively* from a setuid binary like the dbus daemon launch helper. https://bugzilla.redhat.com/show_bug.cgi?id=1285991 Conflicts: girepository/girepository.c --- girepository.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/girepository.c b/girepository.c index 82ee8a44b..4537c03d7 100644 --- a/girepository.c +++ b/girepository.c @@ -27,11 +27,6 @@ #include #include -#ifdef HAVE_GETAUXVAL -#include -#include -#endif - #include #include #include @@ -152,14 +147,6 @@ init_globals (void) if (!g_once_init_enter (&initialized)) return; -#ifdef HAVE_GETAUXVAL - if (getauxval (AT_SECURE)) - { - g_printerr ("error: libgirepository.so (gobject-introspection) is not audited for use in setuid applications\nSee https://bugzilla.gnome.org/show_bug.cgi?id=755472\n"); - _exit (1); - } -#endif - if (default_repository == NULL) default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL); From ec81889c35bd4b1ff8e0175ea1a85a0191c09225 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Wed, 24 Feb 2016 23:53:08 +0000 Subject: [PATCH 555/692] girepository: Fix some memory leaks in gdump.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These were leaking memory when dumping introspection data from projects for building their GIR files. That’s generally not a problem, unless you’re trying to build the project with -fsanitize=address, which causes the GIR build phase to error out due to leaking memory. https://bugzilla.gnome.org/show_bug.cgi?id=762653 --- gdump.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gdump.c b/gdump.c index a72841fe4..b60a5dcee 100644 --- a/gdump.c +++ b/gdump.c @@ -204,6 +204,7 @@ dump_signals (GType type, GOutputStream *out) } goutput_write (out, " \n"); } + g_free (sig_ids); } static void @@ -249,6 +250,8 @@ dump_object_type (GType type, const char *symbol, GOutputStream *out) escaped_printf (out, " \n", g_type_name (itype)); } + g_free (interfaces); + dump_properties (type, out); dump_signals (type, out); goutput_write (out, " \n"); @@ -280,6 +283,8 @@ dump_interface_type (GType type, const char *symbol, GOutputStream *out) escaped_printf (out, " \n", g_type_name (itype)); } + g_free (interfaces); + dump_properties (type, out); dump_signals (type, out); goutput_write (out, " \n"); @@ -379,6 +384,7 @@ dump_fundamental_type (GType type, const char *symbol, GOutputStream *out) escaped_printf (out, " \n", g_type_name (itype)); } + g_free (interfaces); goutput_write (out, " \n"); } @@ -471,6 +477,8 @@ g_irepository_dump (const char *arg, GError **error) input_file = g_file_new_for_path (args[0]); output_file = g_file_new_for_path (args[1]); + g_strfreev (args); + input = g_file_read (input_file, NULL, error); if (input == NULL) return FALSE; From 4e43ed811279382a5ea75b8804f2115eacf933c5 Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Wed, 23 Jul 2014 15:36:41 +0800 Subject: [PATCH 556/692] cmph/bdz.c: Work Around MSVC 2012 x64 Compiler Bug Due to an MSVC 2012 x64 compiler issue, the compiler generates bad code for bdz.c, so the for loop in assign() continues running until the point i falls below zero, causing an access violation when we try to do curr_edge=queue[i]; (line 427 in bdz.c). Address this issue by breaking out of the loop at the end of it when i reaches 0 after doing the necessary processing. https://bugzilla.gnome.org/show_bug.cgi?id=733595 --- cmph/bdz.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmph/bdz.c b/cmph/bdz.c index 81cd7151c..a1c907f11 100644 --- a/cmph/bdz.c +++ b/cmph/bdz.c @@ -455,6 +455,12 @@ static void assigning(bdz_config_data_t *bdz, bdz_graph3_t* graph3, bdz_queue_t SETBIT(marked_vertices, v2); } DEBUGP("A:%u %u %u -- %u %u %u\n", v0, v1, v2, GETVALUE(bdz->g, v0), GETVALUE(bdz->g, v1), GETVALUE(bdz->g, v2)); +#if (_MSC_VER > 1699 && _MSC_VER < 1800) + /* This is bad, MSVC 2012 X64 getting confused with the value of i... */ + /* an obvious MSVC 2012 X64 compiler bug :| */ + if (i <= 0) + break; +#endif }; free(marked_vertices); } From b4df729c618367f506c66ac12e8fc979cec406ec Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Thu, 17 Mar 2016 17:39:43 +0800 Subject: [PATCH 557/692] Fix code style Make my last patch to this file conform to the code style in the rest of this file. --- cmph/bdz.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cmph/bdz.c b/cmph/bdz.c index a1c907f11..34898ad54 100644 --- a/cmph/bdz.c +++ b/cmph/bdz.c @@ -455,12 +455,14 @@ static void assigning(bdz_config_data_t *bdz, bdz_graph3_t* graph3, bdz_queue_t SETBIT(marked_vertices, v2); } DEBUGP("A:%u %u %u -- %u %u %u\n", v0, v1, v2, GETVALUE(bdz->g, v0), GETVALUE(bdz->g, v1), GETVALUE(bdz->g, v2)); + #if (_MSC_VER > 1699 && _MSC_VER < 1800) - /* This is bad, MSVC 2012 X64 getting confused with the value of i... */ - /* an obvious MSVC 2012 X64 compiler bug :| */ - if (i <= 0) - break; + /* This is bad, MSVC 2012 X64 getting confused with the value of i... */ + /* an obvious MSVC 2012 X64 compiler bug :| */ + if (i <= 0) + break; #endif + }; free(marked_vertices); } From 8a08674b33961ba531fa65d6a30bbf24fb96d427 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 28 Apr 2016 16:22:38 +0200 Subject: [PATCH 558/692] girepository: Merge overrides with the regular search path This reverts commit e81c4681cc88a00fcd841c5a68d860d3714b55d7 The GI_TYPELIB_PATH envvar will still allow overriding the default typelib dir (based on gobject-introspection libdir), but applications will have the last say about typelib lookup directories. The resulting lookup order is now: - Paths added through g_irepository_prepend_search_path() - Paths in GI_TYPELIB_PATH - The default gobject introspection lookup dir This makes g_irespository_prepend_search_path() work as announced despite environment variables. If any application was relying on GI_TYPELIB_PATH overriding the paths of this function call (for e.g. make check, or to be able to run code inside the project tree), it is encouraged to set up a similar envvar for their application specific lookup dir, or perform this override through other means. https://bugzilla.gnome.org/show_bug.cgi?id=765735 --- girepository.c | 32 +++----------------------------- 1 file changed, 3 insertions(+), 29 deletions(-) diff --git a/girepository.c b/girepository.c index 4537c03d7..d9f8f6c34 100644 --- a/girepository.c +++ b/girepository.c @@ -46,7 +46,6 @@ static GIRepository *default_repository = NULL; static GSList *search_path = NULL; -static GSList *override_search_path = NULL; struct _GIRepositoryPrivate { @@ -163,7 +162,6 @@ init_globals (void) type_lib_path_env = g_getenv ("GI_TYPELIB_PATH"); search_path = NULL; - override_search_path = NULL; if (type_lib_path_env) { gchar **custom_dirs; @@ -174,7 +172,7 @@ init_globals (void) d = custom_dirs; while (*d) { - override_search_path = g_slist_prepend (override_search_path, *d); + search_path = g_slist_prepend (search_path, *d); d++; } @@ -182,9 +180,6 @@ init_globals (void) g_free (custom_dirs); } - if (override_search_path != NULL) - override_search_path = g_slist_reverse (override_search_path); - libdir = GOBJECT_INTROSPECTION_LIBDIR; typelib_dir = g_build_filename (libdir, "girepository-1.0", NULL); @@ -227,23 +222,6 @@ g_irepository_get_search_path (void) return search_path; } -static GSList * -build_search_path_with_overrides (void) -{ - GSList *result; - - init_globals (); - - if (override_search_path != NULL) - { - result = g_slist_copy (override_search_path); - g_slist_last (result)->next = g_slist_copy (search_path); - } - else - result = g_slist_copy (search_path); - return result; -} - static char * build_typelib_key (const char *name, const char *source) { @@ -1394,13 +1372,11 @@ g_irepository_enumerate_versions (GIRepository *repository, const gchar *namespace_) { GList *ret = NULL; - GSList *search_path; GSList *candidates, *link; const gchar *loaded_version; - search_path = build_search_path_with_overrides (); + init_globals (); candidates = enumerate_namespace_versions (namespace_, search_path); - g_slist_free (search_path); for (link = candidates; link; link = link->next) { @@ -1563,13 +1539,11 @@ g_irepository_require (GIRepository *repository, GIRepositoryLoadFlags flags, GError **error) { - GSList *search_path; GITypelib *typelib; - search_path = build_search_path_with_overrides (); + init_globals (); typelib = require_internal (repository, namespace, version, flags, search_path, error); - g_slist_free (search_path); return typelib; } From 50c7ae999c48ba4bf0279c132028c20f12cde39c Mon Sep 17 00:00:00 2001 From: Paolo Borelli Date: Fri, 22 Apr 2016 13:23:51 +0200 Subject: [PATCH 559/692] gdump: do not leak gfile objects --- gdump.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gdump.c b/gdump.c index b60a5dcee..6aa8bfd1c 100644 --- a/gdump.c +++ b/gdump.c @@ -480,10 +480,17 @@ g_irepository_dump (const char *arg, GError **error) g_strfreev (args); input = g_file_read (input_file, NULL, error); + g_object_unref (input_file); + if (input == NULL) - return FALSE; + { + g_object_unref (output_file); + return FALSE; + } output = g_file_replace (output_file, NULL, FALSE, 0, NULL, error); + g_object_unref (output_file); + if (output == NULL) { g_input_stream_close (G_INPUT_STREAM (input), NULL, NULL); From f6ea1695308faa32cd61eeca3d6dd4f7ed983239 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 18 May 2016 23:10:46 +0100 Subject: [PATCH 560/692] docs: Fix return value description The return value of g_callable_info_get_caller_owns() is not a boolean any more. --- gicallableinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gicallableinfo.c b/gicallableinfo.c index 8360bbf48..46c5d5106 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -267,7 +267,7 @@ g_callable_info_skip_return (GICallableInfo *info) * See whether the caller owns the return value of this callable. * #GITransfer contains a list of possible transfer values. * - * Returns: %TRUE if the caller owns the return value, %FALSE otherwise. + * Returns: the transfer mode for the return value of the callable */ GITransfer g_callable_info_get_caller_owns (GICallableInfo *info) From 597d32df9cee047bf6e716ba8a8e540b12278a8c Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 18 May 2016 23:11:34 +0100 Subject: [PATCH 561/692] docs: Clarify return value documentation Be a bit more specific than just saying "the transfer". --- gicallableinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gicallableinfo.c b/gicallableinfo.c index 46c5d5106..27c7cb2f4 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -295,7 +295,7 @@ g_callable_info_get_caller_owns (GICallableInfo *info) * Obtains the ownership transfer for the instance argument. * #GITransfer contains a list of possible transfer values. * - * Returns: the transfer + * Returns: the transfer mode of the instance argument */ GITransfer g_callable_info_get_instance_ownership_transfer (GICallableInfo *info) From 79225a62c0457ebbd02bafb42b9daacb978f3cb9 Mon Sep 17 00:00:00 2001 From: Tobias Mueller Date: Fri, 9 Sep 2016 12:53:11 +0200 Subject: [PATCH 562/692] gthash: free cmph objects If not done, it would leak the memory as address sanitizer reports: ==1294==ERROR: LeakSanitizer: detected memory leaks Direct leak of 40 byte(s) in 1 object(s) allocated from: #0 0x7fa7a94b7602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602) #1 0x44c7a7 in __config_new girepository/cmph/cmph_structs.c:11 #2 0x44aaa7 in cmph_config_new girepository/cmph/cmph.c:291 #3 0x446fb5 in _gi_typelib_hash_builder_prepare girepository/gthash.c:114 #4 0x406cf7 in add_directory_index_section girepository/girmodule.c:270 #5 0x409ee6 in _g_ir_module_build_typelib girepository/girmodule.c:546 #6 0x404ada in main tools/compiler.c:217 #7 0x7fa7a70d482f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) ==4091==ERROR: LeakSanitizer: detected memory leaks Direct leak of 40 byte(s) in 1 object(s) allocated from: #0 0x7fc20c854602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602) #1 0x44a3f3 in cmph_io_vector_new girepository/cmph/cmph.c:228 #2 0x44a965 in cmph_io_vector_adapter girepository/cmph/cmph.c:276 #3 0x446f9f in _gi_typelib_hash_builder_prepare girepository/gthash.c:113 #4 0x406cf7 in add_directory_index_section girepository/girmodule.c:270 #5 0x409ee6 in _g_ir_module_build_typelib girepository/girmodule.c:546 #6 0x404ada in main tools/compiler.c:217 #7 0x7fc20a47182f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) --- gthash.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gthash.c b/gthash.c index 831c87e97..7440913ae 100644 --- a/gthash.c +++ b/gthash.c @@ -129,6 +129,8 @@ _gi_typelib_hash_builder_prepare (GITypelibHashBuilder *builder) builder->dirmap_offset = ALIGN_VALUE (offset, 4); builder->packed_size = builder->dirmap_offset + (num_elts * sizeof(guint16)); out: + cmph_config_destroy (config); + cmph_io_vector_adapter_destroy (io); return builder->buildable; } From f3154d62a2beab53017bfbd0eba5b3767620f95b Mon Sep 17 00:00:00 2001 From: Rico Tzschichholz Date: Thu, 15 Sep 2016 10:27:27 +0200 Subject: [PATCH 563/692] girepository: Annotate iterator arguments as (inout) --- gibaseinfo.c | 2 +- gicallableinfo.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gibaseinfo.c b/gibaseinfo.c index 5d9e5f37b..ced7674e2 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -558,7 +558,7 @@ _attribute_blob_find_first (GIBaseInfo *info, /** * g_base_info_iterate_attributes: * @info: a #GIBaseInfo - * @iterator: a #GIAttributeIter structure, must be initialized; see below + * @iterator: (inout): a #GIAttributeIter structure, must be initialized; see below * @name: (out) (transfer none): Returned name, must not be freed * @value: (out) (transfer none): Returned name, must not be freed * diff --git a/gicallableinfo.c b/gicallableinfo.c index 27c7cb2f4..4ffb46ded 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -424,7 +424,7 @@ g_callable_info_get_return_attribute (GICallableInfo *info, /** * g_callable_info_iterate_return_attributes: * @info: a #GICallableInfo - * @iterator: a #GIAttributeIter structure, must be initialized; see below + * @iterator: (inout): a #GIAttributeIter structure, must be initialized; see below * @name: (out) (transfer none): Returned name, must not be freed * @value: (out) (transfer none): Returned name, must not be freed * From 38068ab362607ce1ab22e8b8435cd758faf7db8d Mon Sep 17 00:00:00 2001 From: Rico Tzschichholz Date: Sat, 10 Dec 2016 21:42:28 +0100 Subject: [PATCH 564/692] girepository: Annotate array and array-length parameter --- gicallableinfo.c | 4 ++-- gifunctioninfo.c | 4 ++-- givfuncinfo.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gicallableinfo.c b/gicallableinfo.c index 4ffb46ded..bfbcc255a 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -552,9 +552,9 @@ gi_type_info_extract_ffi_return_value (GITypeInfo *return_info, * g_callable_info_invoke: * @info: TODO * @function: TODO - * @in_args: TODO + * @in_args: (array length=n_in_args): TODO * @n_in_args: TODO - * @out_args: TODO + * @out_args: (array length=n_out_args): TODO * @n_out_args: TODO * @return_value: TODO * @is_method: TODO diff --git a/gifunctioninfo.c b/gifunctioninfo.c index ece948184..b5720244e 100644 --- a/gifunctioninfo.c +++ b/gifunctioninfo.c @@ -226,11 +226,11 @@ g_invoke_error_quark (void) /** * g_function_info_invoke: (skip) * @info: a #GIFunctionInfo describing the function to invoke - * @in_args: an array of #GIArguments, one for each in + * @in_args: (array length=n_in_args): an array of #GIArguments, one for each in * parameter of @info. If there are no in parameter, @in_args * can be %NULL * @n_in_args: the length of the @in_args array - * @out_args: an array of #GIArguments, one for each out + * @out_args: (array length=n_out_args): an array of #GIArguments, one for each out * parameter of @info. If there are no out parameters, @out_args * may be %NULL * @n_out_args: the length of the @out_args array diff --git a/givfuncinfo.c b/givfuncinfo.c index c16fb01dd..f20bfb062 100644 --- a/givfuncinfo.c +++ b/givfuncinfo.c @@ -305,11 +305,11 @@ g_vfunc_info_get_address (GIVFuncInfo *vfunc_info, * g_vfunc_info_invoke: (skip) * @info: a #GIVFuncInfo describing the virtual function to invoke * @implementor: #GType of the type that implements this virtual function - * @in_args: an array of #GIArguments, one for each in + * @in_args: (array length=n_in_args): an array of #GIArguments, one for each in * parameter of @info. If there are no in parameter, @in_args * can be %NULL * @n_in_args: the length of the @in_args array - * @out_args: an array of #GIArguments, one for each out + * @out_args: (array length=n_out_args): an array of #GIArguments, one for each out * parameter of @info. If there are no out parameters, @out_args * may be %NULL * @n_out_args: the length of the @out_args array From 52727afbd26b2b66ea3e6f48f1c7a7b4f25536d3 Mon Sep 17 00:00:00 2001 From: Nicola Fontana Date: Thu, 24 Mar 2016 05:15:51 +0100 Subject: [PATCH 565/692] docs: manifest typelib format portability Apart the endianness of its scalar values the typelib binary format must be considered arch-independent: make it clear in the docs. https://bugzilla.gnome.org/show_bug.cgi?id=764116 --- gitypelib-internal.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 0f105127e..281192eb8 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -37,6 +37,9 @@ G_BEGIN_DECLS * * The "typelib" is a binary, readonly, memory-mappable database * containing reflective information about a GObject library. + * What the typelib describes and the types used are the same for every + * platform so, apart the endianness of its scalar values, the typelib + * database must be considered architecture-independent. * * The format of GObject typelib is strongly influenced by the Mozilla XPCOM * format. From a6b5da2a4fb8708f873af87e24ba2afdb283d488 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Sun, 24 Sep 2017 14:32:26 +0100 Subject: [PATCH 566/692] Use locale-independent functions to parse numbers https://bugzilla.gnome.org/show_bug.cgi?id=788087 --- girnode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/girnode.c b/girnode.c index 455e9d6c0..4d439a642 100644 --- a/girnode.c +++ b/girnode.c @@ -992,19 +992,19 @@ _g_ir_node_param_direction_string (GIrNodeParam * node) static gint64 parse_int_value (const gchar *str) { - return strtoll (str, NULL, 0); + return g_ascii_strtoll (str, NULL, 0); } static guint64 parse_uint_value (const gchar *str) { - return strtoull (str, NULL, 0); + return g_ascii_strtoull (str, NULL, 0); } static gdouble parse_float_value (const gchar *str) { - return strtod (str, NULL); + return g_ascii_strtod (str, NULL); } static gboolean From ac76bbb53b871f10c1fe23ab62750647bfc0c8fc Mon Sep 17 00:00:00 2001 From: Patrick Griffis Date: Wed, 23 Aug 2017 00:29:42 -0400 Subject: [PATCH 567/692] girepository: Don't skip g_irepository_get_option_group() This function works fine via introspection https://bugzilla.gnome.org/show_bug.cgi?id=786665 --- girepository.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girepository.c b/girepository.c index d9f8f6c34..df0f24797 100644 --- a/girepository.c +++ b/girepository.c @@ -1605,7 +1605,7 @@ static const GOptionEntry introspection_args[] = { }; /** - * g_irepository_get_option_group: (skip) + * g_irepository_get_option_group: * * Obtain the option group for girepository, it's used * by the dumper and for programs that wants to provide From 5ecbc70a05bb1bf9d48d08cfa4f672ea7698893a Mon Sep 17 00:00:00 2001 From: Leslie Giles Date: Fri, 3 Nov 2017 13:51:20 -0400 Subject: [PATCH 568/692] Increase MAX_NAME_LEN There is no real limit on the length of an identifier, and some toolchains easily hit the current limit of 200 characters. According to this answer on StackOverflow, 2048 seems to be the limit on MSVC and ICC: https://stackoverflow.com/questions/6007568/what-is-max-length-for-an-c-c-identifier-on-common-build-systems So let's use that. https://bugzilla.gnome.org/show_bug.cgi?id=764791 --- gitypelib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitypelib.c b/gitypelib.c index aaa835596..d9e924f63 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -467,7 +467,7 @@ is_aligned (guint32 offset) return offset == ALIGN_VALUE (offset, 4); } -#define MAX_NAME_LEN 200 +#define MAX_NAME_LEN 2048 static const char * get_string (GITypelib *typelib, guint32 offset, GError **error) From 8d25dd4159ff1eea72df6f1da70a3a12d2eb6961 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Tue, 30 Jan 2018 13:41:15 +0000 Subject: [PATCH 569/692] Remove unnecessary transfer annotation Integers do not need a transfer annotation. --- giunioninfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/giunioninfo.c b/giunioninfo.c index a819595f1..9a7f86135 100644 --- a/giunioninfo.c +++ b/giunioninfo.c @@ -154,7 +154,7 @@ g_union_info_is_discriminated (GIUnionInfo *info) * * Returns offset of the discriminator field in the structure. * - * Returns: (transfer full): offset in bytes of the discriminator + * Returns: offset in bytes of the discriminator */ gint g_union_info_get_discriminator_offset (GIUnionInfo *info) From 6b123c6cff7aea182fa611ad229a3cac038bb0ee Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Tue, 30 Jan 2018 13:43:28 +0000 Subject: [PATCH 570/692] Skip unused generic marshaller You typically want to use the version in GObject, not this one. --- ginvoke.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ginvoke.c b/ginvoke.c index bd5aa2cd9..f7e644938 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -233,7 +233,7 @@ g_value_from_ffi_value (GValue *gvalue, } /** - * gi_cclosure_marshal_generic: + * gi_cclosure_marshal_generic: (skip) * @closure: TODO * @return_gvalue: TODO * @n_param_values: TODO From caef88d09477871d77ffa6c3f89ffc0879d0654e Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Tue, 30 Jan 2018 14:01:06 +0000 Subject: [PATCH 571/692] docs: Mention GI_TYPELIB_PATH The rules for searching typelib files should be properly documented, as well as the way to modify the search paths. https://bugzilla.gnome.org/show_bug.cgi?id=699328 --- girepository.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/girepository.c b/girepository.c index df0f24797..10282c72d 100644 --- a/girepository.c +++ b/girepository.c @@ -41,6 +41,17 @@ * * #GIRepository is used to manage repositories of namespaces. Namespaces * are represented on disk by type libraries (.typelib files). + * + * ### Discovery of type libraries + * + * #GIRepository will typically look for a `girepository-1.0` directory + * under the library directory used when compiling gobject-introspection. + * + * It is possible to control the search paths programmatically, using + * g_irepository_prepend_search_path(). It is also possible to modify + * the search paths by using the `GI_TYPELIB_PATH` environment variable. + * The environment variable takes precedence over the default search path + * and the g_irepository_prepend_search_path() calls. */ @@ -198,7 +209,8 @@ init_globals (void) * search path * * Prepends @directory to the typelib search path. - * See g_irepository_get_search_path(). + * + * See also: g_irepository_get_search_path(). */ void g_irepository_prepend_search_path (const char *directory) @@ -1369,7 +1381,7 @@ find_namespace_latest (const gchar *namespace, */ GList * g_irepository_enumerate_versions (GIRepository *repository, - const gchar *namespace_) + const gchar *namespace_) { GList *ret = NULL; GSList *candidates, *link; From 4c8c1a53b84be14b22bec2fb62da7c4fe22b58d5 Mon Sep 17 00:00:00 2001 From: Patrick Griffis Date: Mon, 23 Oct 2017 04:53:04 -0400 Subject: [PATCH 572/692] Initial work on meson port --- cmph/meson.build | 50 +++++++++++++++ meson.build | 163 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 cmph/meson.build create mode 100644 meson.build diff --git a/cmph/meson.build b/cmph/meson.build new file mode 100644 index 000000000..0c0e0af55 --- /dev/null +++ b/cmph/meson.build @@ -0,0 +1,50 @@ +cmph_sources = [ + 'bdz.c', + 'bdz_ph.c', + 'bmz8.c', + 'bmz.c', + 'brz.c', + 'buffer_entry.c', + 'buffer_manager.c', + 'chd.c', + 'chd_ph.c', + 'chm.c', + 'cmph.c', + 'cmph_structs.c', + 'compressed_rank.c', + 'compressed_seq.c', + 'fch_buckets.c', + 'fch.c', + 'graph.c', + 'hash.c', + 'jenkins_hash.c', + 'miller_rabin.c', + 'select.c', + 'vqueue.c', + 'vstack.c', +] + +cmph_deps = [ + gobject_dep, + cc.find_library('m', required: false), +] + +cmph = static_library('cmph', + sources: cmph_sources, + c_args: gi_hidden_visibility_cflags, + dependencies: cmph_deps, +) + +cmph_dep = declare_dependency( + link_with: cmph, + include_directories: include_directories('.'), +) + +cmph_test = executable('cmph-bdz-test', '../cmph-bdz-test.c', + dependencies: [ + cmph_dep, + gobject_dep, + ] +) + +test('cmph-bdz-test', cmph_test) diff --git a/meson.build b/meson.build new file mode 100644 index 000000000..53486241f --- /dev/null +++ b/meson.build @@ -0,0 +1,163 @@ +subdir('cmph') + +girepo_gthash_lib = static_library('girepository-gthash', + sources: 'gthash.c', + c_args: gi_hidden_visibility_cflags, + dependencies: [ + cmph_dep, + gobject_dep, + ], +) + +girepo_gthash_dep = declare_dependency( + link_with: girepo_gthash_lib, + dependencies: gobject_dep, + include_directories: include_directories('.'), +) + +girepo_internals_lib = static_library('girepository-internals', + sources: [ + 'girmodule.c', + 'girnode.c', + 'giroffsets.c', + 'girparser.c', + 'girwriter.c', + ], + c_args: gi_hidden_visibility_cflags, + dependencies: [girepo_gthash_dep, libffi_dep], +) + +girepo_internals_dep = declare_dependency( + link_with: girepo_internals_lib, + dependencies: libffi_dep, + include_directories: include_directories('.'), +) + +girepo_headers = [ + 'giarginfo.h', + 'gibaseinfo.h', + 'gicallableinfo.h', + 'giconstantinfo.h', + 'gienuminfo.h', + 'gifieldinfo.h', + 'gifunctioninfo.h', + 'giinterfaceinfo.h', + 'giobjectinfo.h', + 'gipropertyinfo.h', + 'giregisteredtypeinfo.h', + 'girepository.h', + 'girffi.h', + 'gisignalinfo.h', + 'gistructinfo.h', + 'gitypeinfo.h', + 'gitypelib.h', + 'gitypes.h', + 'giunioninfo.h', + 'giversionmacros.h', + 'givfuncinfo.h', +] + +girepo_sources = [ + 'gdump.c', + 'giarginfo.c', + 'gibaseinfo.c', + 'gicallableinfo.c', + 'giconstantinfo.c', + 'gienuminfo.c', + 'gifieldinfo.c', + 'gifunctioninfo.c', + 'ginvoke.c', + 'giinterfaceinfo.c', + 'giobjectinfo.c', + 'gipropertyinfo.c', + 'giregisteredtypeinfo.c', + 'girepository.c', + 'girffi.c', + 'gisignalinfo.c', + 'gistructinfo.c', + 'gitypeinfo.c', + 'gitypelib.c', + 'giunioninfo.c', + 'givfuncinfo.c', +] + +# Used in gir/meson.build +girepo_gir_sources = files( + 'giarginfo.c', + 'gibaseinfo.c', + 'gicallableinfo.c', + 'giconstantinfo.c', + 'gienuminfo.c', + 'gifieldinfo.c', + 'gifunctioninfo.c', + 'giinterfaceinfo.c', + 'giobjectinfo.c', + 'gipropertyinfo.c', + 'giregisteredtypeinfo.c', + 'girepository.c', + 'gisignalinfo.c', + 'gistructinfo.c', + 'gitypeinfo.c', + 'giunioninfo.c', + 'givfuncinfo.c', + 'giarginfo.h', + 'gibaseinfo.h', + 'gicallableinfo.h', + 'giconstantinfo.h', + 'gienuminfo.h', + 'gifieldinfo.h', + 'gifunctioninfo.h', + 'giinterfaceinfo.h', + 'giobjectinfo.h', + 'gipropertyinfo.h', + 'giregisteredtypeinfo.h', + 'girepository.h', + 'gisignalinfo.h', + 'gistructinfo.h', + 'gitypeinfo.h', + 'gitypelib.h', + 'gitypes.h', + 'giunioninfo.h', + 'givfuncinfo.h', +) + +install_headers(girepo_headers, subdir: 'gobject-introspection-1.0') + +girepo_lib = shared_library('girepository-1.0', + sources: girepo_sources, + c_args: gi_hidden_visibility_cflags + ['-DG_IREPOSITORY_COMPILATION'], + dependencies: [ + gio_dep, + gmodule_dep, + girepo_internals_dep, + dependency('gio-2.0'), + ], + version: '1.0.0', + install: true, +) + +install_data('gdump.c', + install_dir: join_paths(get_option('datadir'), 'gobject-introspection-1.0') +) + +girepo_dep = declare_dependency( + link_with: girepo_lib, + dependencies: gio_dep, + include_directories: include_directories('.'), +) + +gthash_test = executable('gthash-test', 'gthash-test.c', + dependencies: girepo_gthash_dep, +) + +test('gthash-test', gthash_test) + +if giounix_dep.found() + executable('gi-dump-types', 'gi-dump-types.c', + dependencies: [ + girepo_dep, + gmodule_dep, + giounix_dep, + ] + ) +endif From 3a78885133a7eb6e371b430afad2a58c0e610dd1 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Thu, 23 Nov 2017 13:45:37 +0530 Subject: [PATCH 573/692] meson: Use glib_dep and configinc for girepository glib_dep is what is actually needed to #include , not gobject_dep. It works incidentally with system gobject/glib but not when built via subprojects. --- cmph/meson.build | 4 ++-- meson.build | 25 ++++++++++--------------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/cmph/meson.build b/cmph/meson.build index 0c0e0af55..368afc7b5 100644 --- a/cmph/meson.build +++ b/cmph/meson.build @@ -25,7 +25,7 @@ cmph_sources = [ ] cmph_deps = [ - gobject_dep, + glib_dep, cc.find_library('m', required: false), ] @@ -43,7 +43,7 @@ cmph_dep = declare_dependency( cmph_test = executable('cmph-bdz-test', '../cmph-bdz-test.c', dependencies: [ cmph_dep, - gobject_dep, + glib_dep, ] ) diff --git a/meson.build b/meson.build index 53486241f..b020caa44 100644 --- a/meson.build +++ b/meson.build @@ -2,16 +2,18 @@ subdir('cmph') girepo_gthash_lib = static_library('girepository-gthash', sources: 'gthash.c', + include_directories : configinc, c_args: gi_hidden_visibility_cflags, dependencies: [ cmph_dep, - gobject_dep, + glib_dep, + gmodule_dep, ], ) girepo_gthash_dep = declare_dependency( link_with: girepo_gthash_lib, - dependencies: gobject_dep, + dependencies: [glib_dep, gmodule_dep], include_directories: include_directories('.'), ) @@ -24,6 +26,7 @@ girepo_internals_lib = static_library('girepository-internals', 'girwriter.c', ], c_args: gi_hidden_visibility_cflags, + include_directories : configinc, dependencies: [girepo_gthash_dep, libffi_dep], ) @@ -125,13 +128,10 @@ install_headers(girepo_headers, subdir: 'gobject-introspection-1.0') girepo_lib = shared_library('girepository-1.0', sources: girepo_sources, + include_directories : configinc, c_args: gi_hidden_visibility_cflags + ['-DG_IREPOSITORY_COMPILATION'], - dependencies: [ - gio_dep, - gmodule_dep, - girepo_internals_dep, - dependency('gio-2.0'), - ], + dependencies: [glib_dep, gobject_dep, gmodule_dep, + gio_dep, girepo_internals_dep], version: '1.0.0', install: true, ) @@ -142,7 +142,7 @@ install_data('gdump.c', girepo_dep = declare_dependency( link_with: girepo_lib, - dependencies: gio_dep, + dependencies: [glib_dep, gobject_dep, gio_dep, gmodule_dep], include_directories: include_directories('.'), ) @@ -154,10 +154,5 @@ test('gthash-test', gthash_test) if giounix_dep.found() executable('gi-dump-types', 'gi-dump-types.c', - dependencies: [ - girepo_dep, - gmodule_dep, - giounix_dep, - ] - ) + dependencies: [girepo_dep, giounix_dep]) endif From c01bc6ef0e66568de53388b977fa8b172fad0d6d Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Fri, 24 Nov 2017 02:29:01 +0530 Subject: [PATCH 574/692] g-ir-scanner: Don't require SRCDIR and BUILDDIR env vars When building with Meson, we cannot set environment variables while running custom targets and our builddir layout is different from Autotools anyway. Now g-ir-scanner and friends can autodetect when they're being run uninstalled by Meson and will find _giscanner.so and the giscanner python files in the build directory. This is very similar to what gdbus-codegen uses in glib/gio. Same for girepository/gdump.c. --- meson.build | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index b020caa44..6a8c5b5d8 100644 --- a/meson.build +++ b/meson.build @@ -136,8 +136,12 @@ girepo_lib = shared_library('girepository-1.0', install: true, ) -install_data('gdump.c', - install_dir: join_paths(get_option('datadir'), 'gobject-introspection-1.0') +# Copy to builddir for use with giscanner/dumper.py when running uninstalled +configure_file(input : 'gdump.c', + output : 'gdump.c', + configuration : configuration_data(), + install_dir: join_paths(get_option('datadir'), 'gobject-introspection-1.0'), + install : true, ) girepo_dep = declare_dependency( From 4dafb4d5cfe3e104514e2fd1c951d9939bca4ed2 Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Tue, 3 Oct 2017 14:29:00 +0800 Subject: [PATCH 575/692] girepository: Properly acquire and check pointer values On Windows (Visual Studio at least), unsigned longs are always 4 bytes, on both 32-bit and x64 Windows, so we cannot use unsigned longs to deal with pointers on 64-bit builds, as pointers are 8 bytes on 64-bit Windows, which may well render the pointer (which we acquired from libffi) invalid. This will fix crashes in PyGObject which are manifested when launching the cairo-demo example sript (intermittent) and when clicking on "Interactive Dialog" button in the Dialog demo in the PyGObject GTK+ Code demos before entering anything in Entry 1 and Entry 2, when running on x64 Visual Studio builds of the GTK+/PyGObject stack. Also use size_t instead of unsigned long in gthash.c when we check that memory & 0x3 is 0, to silence compiler warnings from enabling /Wp64, which is used to detect portability problems on Visual Studio when doing x86->x64 code builds. https://bugzilla.gnome.org/show_bug.cgi?id=702788 --- gicallableinfo.c | 4 ++-- gthash.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gicallableinfo.c b/gicallableinfo.c index bfbcc255a..5f923d1a9 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -535,7 +535,7 @@ gi_type_info_extract_ffi_return_value (GITypeInfo *return_info, arg->v_int32 = (gint32) ffi_value->v_long; break; default: - arg->v_pointer = (gpointer) ffi_value->v_ulong; + arg->v_pointer = (gpointer) ffi_value->v_pointer; break; } @@ -543,7 +543,7 @@ gi_type_info_extract_ffi_return_value (GITypeInfo *return_info, } break; default: - arg->v_pointer = (gpointer) ffi_value->v_ulong; + arg->v_pointer = (gpointer) ffi_value->v_pointer; break; } } diff --git a/gthash.c b/gthash.c index 7440913ae..2fda90359 100644 --- a/gthash.c +++ b/gthash.c @@ -158,7 +158,7 @@ _gi_typelib_hash_builder_pack (GITypelibHashBuilder *builder, guint8* mem, guint g_return_if_fail (builder->buildable); g_assert (len >= builder->packed_size); - g_assert ((((unsigned long)mem) & 0x3) == 0); + g_assert ((((size_t)mem) & 0x3) == 0); memset (mem, 0, len); @@ -202,7 +202,7 @@ _gi_typelib_hash_search (guint8* memory, const char *str, guint n_entries) guint32 dirmap_offset; guint32 offset; - g_assert ((((unsigned long)memory) & 0x3) == 0); + g_assert ((((size_t)memory) & 0x3) == 0); mph = ((guint32*)memory)+1; offset = cmph_search_packed (mph, str, strlen (str)); From c704898e268d2a92512c27bebbc77e9d8dc9545c Mon Sep 17 00:00:00 2001 From: Rico Tzschichholz Date: Wed, 4 Jul 2018 16:54:31 +0200 Subject: [PATCH 576/692] gdump: Fix print-format error while GFlagsValue->value is an unsigned int --- gdump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gdump.c b/gdump.c index 6aa8bfd1c..0e8c60352 100644 --- a/gdump.c +++ b/gdump.c @@ -311,7 +311,7 @@ dump_flags_type (GType type, const char *symbol, GOutputStream *out) { GFlagsValue *value = &(klass->values[i]); - escaped_printf (out, " \n", + escaped_printf (out, " \n", value->value_name, value->value_nick, value->value); } goutput_write (out, " \n"); From 16f2c2ad0bb8608ff09b43224ee8889dcfbbef66 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sun, 29 Jul 2018 14:26:44 +0200 Subject: [PATCH 577/692] build: enable -Wdiscarded-qualifiers Except for the Python module because nothing in the CPython API is marked const and we'd have to cast everywhere. --- girwriter.c | 2 +- gitypelib.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/girwriter.c b/girwriter.c index 4bc7fc963..dacce86f3 100644 --- a/girwriter.c +++ b/girwriter.c @@ -237,7 +237,7 @@ write_type_info (const gchar *namespace, else if (tag == GI_TYPE_TAG_ARRAY) { gint length, size; - char *name = NULL; + const char *name = NULL; xml_start_element (file, "array"); diff --git a/gitypelib.c b/gitypelib.c index d9e924f63..8ad13604e 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -272,7 +272,7 @@ strsplit_iter_init (StrSplitIter *iter, static gboolean strsplit_iter_next (StrSplitIter *iter, - char **out_val) + const char **out_val) { const char *s = iter->s; const char *next; From 9018e7b13c5fca42daf16623b8d1a30ca7299f36 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sun, 29 Jul 2018 14:47:58 +0200 Subject: [PATCH 578/692] build: enable -Wincompatible-pointer-types --- gitypelib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitypelib.c b/gitypelib.c index 8ad13604e..f2b206078 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -324,7 +324,7 @@ g_typelib_matches_gtype_name_prefix (GITypelib *typelib, { Header *header = (Header *)typelib->data; const char *c_prefix; - gchar *prefix; + const gchar *prefix; gboolean ret = FALSE; StrSplitIter split_iter; gsize gtype_name_len; From 573fe4178839d74a12eb119bc04bd22c4ba0f895 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sun, 29 Jul 2018 14:54:34 +0200 Subject: [PATCH 579/692] build: enable -Wdouble-promotion --- girwriter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girwriter.c b/girwriter.c index dacce86f3..1b61de03e 100644 --- a/girwriter.c +++ b/girwriter.c @@ -748,7 +748,7 @@ write_constant_value (const gchar *namespace, xml_printf (file, "%" G_GUINT64_FORMAT, value->v_uint64); break; case GI_TYPE_TAG_FLOAT: - xml_printf (file, "%f", value->v_float); + xml_printf (file, "%f", (double)value->v_float); break; case GI_TYPE_TAG_DOUBLE: xml_printf (file, "%f", value->v_double); From ee2ec3343ef4b3aeb2cc598683435abfc561a483 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sun, 29 Jul 2018 15:02:41 +0200 Subject: [PATCH 580/692] build: enable -Wsuggest-attribute=format And use G_GNUC_PRINTF for the suggested function. --- girwriter.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/girwriter.c b/girwriter.c index 1b61de03e..bb82a46f6 100644 --- a/girwriter.c +++ b/girwriter.c @@ -61,6 +61,9 @@ xml_element_free (XmlElement *elem) g_slice_free (XmlElement, elem); } +static void +xml_printf (Xml *xml, const char *fmt, ...) G_GNUC_PRINTF (2, 3); + static void xml_printf (Xml *xml, const char *fmt, ...) { From 7cdf5d0d1d1ba75967f0b00e291b61ac67c2bbd0 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sun, 29 Jul 2018 15:24:59 +0200 Subject: [PATCH 581/692] build: enable -Wcast-function-type Where it's easy add dummy args to match the cast; where the target is a subset just prevent the warning with a cast to void*. Provide a real copy function for the boxed type code in regress_foo. This code is never executed afaics, but why not. --- girepository.c | 2 +- gitypelib.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/girepository.c b/girepository.c index 10282c72d..6ffb3aa87 100644 --- a/girepository.c +++ b/girepository.c @@ -1362,7 +1362,7 @@ find_namespace_latest (const gchar *namespace, *path_ret = elected->path; *version_ret = elected->version; g_slice_free (struct NamespaceVersionCandidadate, elected); /* just free the container */ - g_slist_foreach (candidates, (GFunc) free_candidate, NULL); + g_slist_foreach (candidates, (GFunc) (void *) free_candidate, NULL); g_slist_free (candidates); } return result; diff --git a/gitypelib.c b/gitypelib.c index f2b206078..1e33c6af9 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -2455,7 +2455,7 @@ g_typelib_free (GITypelib *typelib) g_free (typelib->data); if (typelib->modules) { - g_list_foreach (typelib->modules, (GFunc) g_module_close, NULL); + g_list_foreach (typelib->modules, (GFunc) (void *) g_module_close, NULL); g_list_free (typelib->modules); } g_slice_free (GITypelib, typelib); From 3a5b0c2ae2497d93e434d80d6918d33921ebf216 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sun, 29 Jul 2018 15:56:35 +0200 Subject: [PATCH 582/692] build: enable -Wshadow --- girepository.c | 20 ++++++++++---------- girnode.c | 18 +++++++++--------- girparser.c | 3 ++- gitypelib.c | 8 ++++---- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/girepository.c b/girepository.c index 6ffb3aa87..819f8e76a 100644 --- a/girepository.c +++ b/girepository.c @@ -56,7 +56,7 @@ static GIRepository *default_repository = NULL; -static GSList *search_path = NULL; +static GSList *typelib_search_path = NULL; struct _GIRepositoryPrivate { @@ -160,7 +160,7 @@ init_globals (void) if (default_repository == NULL) default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL); - if (search_path == NULL) + if (typelib_search_path == NULL) { const char *libdir; char *typelib_dir; @@ -172,7 +172,7 @@ init_globals (void) */ type_lib_path_env = g_getenv ("GI_TYPELIB_PATH"); - search_path = NULL; + typelib_search_path = NULL; if (type_lib_path_env) { gchar **custom_dirs; @@ -183,7 +183,7 @@ init_globals (void) d = custom_dirs; while (*d) { - search_path = g_slist_prepend (search_path, *d); + typelib_search_path = g_slist_prepend (typelib_search_path, *d); d++; } @@ -195,9 +195,9 @@ init_globals (void) typelib_dir = g_build_filename (libdir, "girepository-1.0", NULL); - search_path = g_slist_prepend (search_path, typelib_dir); + typelib_search_path = g_slist_prepend (typelib_search_path, typelib_dir); - search_path = g_slist_reverse (search_path); + typelib_search_path = g_slist_reverse (typelib_search_path); } g_once_init_leave (&initialized, 1); @@ -216,7 +216,7 @@ void g_irepository_prepend_search_path (const char *directory) { init_globals (); - search_path = g_slist_prepend (search_path, g_strdup (directory)); + typelib_search_path = g_slist_prepend (typelib_search_path, g_strdup (directory)); } /** @@ -231,7 +231,7 @@ g_irepository_prepend_search_path (const char *directory) GSList * g_irepository_get_search_path (void) { - return search_path; + return typelib_search_path; } static char * @@ -1388,7 +1388,7 @@ g_irepository_enumerate_versions (GIRepository *repository, const gchar *loaded_version; init_globals (); - candidates = enumerate_namespace_versions (namespace_, search_path); + candidates = enumerate_namespace_versions (namespace_, typelib_search_path); for (link = candidates; link; link = link->next) { @@ -1555,7 +1555,7 @@ g_irepository_require (GIRepository *repository, init_globals (); typelib = require_internal (repository, namespace, version, flags, - search_path, error); + typelib_search_path, error); return typelib; } diff --git a/girnode.c b/girnode.c index 4d439a642..fb21c2884 100644 --- a/girnode.c +++ b/girnode.c @@ -1182,14 +1182,14 @@ get_index_of_member_type (GIrNodeInterface *node, for (l = node->members; l; l = l->next) { - GIrNode *node = l->data; + GIrNode *member_node = l->data; - if (node->type != type) + if (member_node->type != type) continue; index++; - if (strcmp (node->name, name) == 0) + if (strcmp (member_node->name, name) == 0) break; } @@ -1543,13 +1543,13 @@ _g_ir_node_build_typelib (GIrNode *node, case GI_TYPE_TAG_ERROR: { - ErrorTypeBlob *blob = (ErrorTypeBlob *)&data[*offset2]; + ErrorTypeBlob *error_blob = (ErrorTypeBlob *)&data[*offset2]; - blob->pointer = 1; - blob->reserved = 0; - blob->tag = type->tag; - blob->reserved2 = 0; - blob->n_domains = 0; + error_blob->pointer = 1; + error_blob->reserved = 0; + error_blob->tag = type->tag; + error_blob->reserved2 = 0; + error_blob->n_domains = 0; *offset2 += sizeof (ErrorTypeBlob); } diff --git a/girparser.c b/girparser.c index 4c43e0ae7..dfc75c967 100644 --- a/girparser.c +++ b/girparser.c @@ -2761,7 +2761,6 @@ start_element_handler (GMarkupParseContext *context, GError **error) { ParseContext *ctx = user_data; - gint line_number, char_number; if (logged_levels & G_LOG_LEVEL_DEBUG) { @@ -3097,6 +3096,7 @@ start_element_handler (GMarkupParseContext *context, if (*error == NULL && ctx->state != STATE_PASSTHROUGH) { + gint line_number, char_number; g_markup_parse_context_get_position (context, &line_number, &char_number); if (!g_str_has_prefix (element_name, "c:")) g_printerr ("%s:%d:%d: warning: element %s from state %d is unknown, ignoring\n", @@ -3108,6 +3108,7 @@ start_element_handler (GMarkupParseContext *context, out: if (*error) { + gint line_number, char_number; g_markup_parse_context_get_position (context, &line_number, &char_number); g_printerr ("%s:%d:%d: error: %s\n", ctx->file_path, line_number, char_number, (*error)->message); diff --git a/gitypelib.c b/gitypelib.c index 1e33c6af9..dbc7261e7 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -1500,7 +1500,7 @@ validate_struct_blob (ValidateContext *ctx, field_offset = offset + sizeof (StructBlob); for (i = 0; i < blob->n_fields; i++) { - FieldBlob *blob = (FieldBlob*) &typelib->data[field_offset]; + FieldBlob *field_blob = (FieldBlob*) &typelib->data[field_offset]; if (!validate_field_blob (ctx, field_offset, @@ -1508,7 +1508,7 @@ validate_struct_blob (ValidateContext *ctx, return FALSE; field_offset += sizeof (FieldBlob); - if (blob->has_embedded_type) + if (field_blob->has_embedded_type) field_offset += sizeof (CallbackBlob); } @@ -1778,14 +1778,14 @@ validate_object_blob (ValidateContext *ctx, n_field_callbacks = 0; for (i = 0; i < blob->n_fields; i++) { - FieldBlob *blob = (FieldBlob*) &typelib->data[offset2]; + FieldBlob *field_blob = (FieldBlob*) &typelib->data[offset2]; if (!validate_field_blob (ctx, offset2, error)) return FALSE; offset2 += sizeof (FieldBlob); /* Special case fields which are callbacks. */ - if (blob->has_embedded_type) { + if (field_blob->has_embedded_type) { offset2 += sizeof (CallbackBlob); n_field_callbacks++; } From f02e90f2656556cd25f3d26d208330e063e62135 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sun, 29 Jul 2018 16:36:31 +0200 Subject: [PATCH 583/692] build: enable -Wimplicit-fallthrough and fix a missplaced break --- girparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index dfc75c967..893a9a4eb 100644 --- a/girparser.c +++ b/girparser.c @@ -3479,8 +3479,8 @@ end_element_handler (GMarkupParseContext *context, (strcmp ("varargs", element_name) == 0)) { end_type (ctx); - break; } + break; case STATE_ATTRIBUTE: if (strcmp ("attribute", element_name) == 0) { From 7be196f29539fb4e97277674f50e17634c6e2c35 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sun, 29 Jul 2018 16:40:27 +0200 Subject: [PATCH 584/692] build: enable -Wtype-limits hashv is unsigned, no need to check if >= 0 --- gthash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gthash.c b/gthash.c index 2fda90359..16bfb4b8a 100644 --- a/gthash.c +++ b/gthash.c @@ -177,7 +177,7 @@ _gi_typelib_hash_builder_pack (GITypelibHashBuilder *builder, guint8* mem, guint guint32 hashv; hashv = cmph_search_packed (packed_mem, str, strlen (str)); - g_assert (hashv >= 0 && hashv < num_elts); + g_assert (hashv < num_elts); table[hashv] = strval; } } From a718ebac867c1141580fe1e815071ca4e00d763c Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sun, 29 Jul 2018 17:13:16 +0200 Subject: [PATCH 585/692] build: enable -Wswitch-default In case the surrounding code handles missing cases break, otherwise add a g_assert_not_reached(). The generated parser code triggers this as well, so disable it there only. --- gicallableinfo.c | 2 ++ giconstantinfo.c | 2 ++ gifieldinfo.c | 8 ++++++++ girffi.c | 2 ++ girnode.c | 4 ++++ girparser.c | 2 ++ girwriter.c | 4 ++++ 7 files changed, 24 insertions(+) diff --git a/gicallableinfo.c b/gicallableinfo.c index 5f923d1a9..e9a426e15 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -77,6 +77,8 @@ signature_offset (GICallableInfo *info) case GI_INFO_TYPE_SIGNAL: sigoff = G_STRUCT_OFFSET (SignalBlob, signature); break; + default: + g_assert_not_reached (); } if (sigoff >= 0) return *(guint32 *)&rinfo->typelib->data[rinfo->offset + sigoff]; diff --git a/giconstantinfo.c b/giconstantinfo.c index 60715a4b6..d44646ee7 100644 --- a/giconstantinfo.c +++ b/giconstantinfo.c @@ -166,6 +166,8 @@ g_constant_info_get_value (GIConstantInfo *info, case GI_TYPE_TAG_DOUBLE: DO_ALIGNED_COPY(&value->v_double, &rinfo->typelib->data[blob->offset], gdouble); break; + default: + g_assert_not_reached (); } } } diff --git a/gifieldinfo.c b/gifieldinfo.c index ea64dabbd..4d07304e3 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -337,12 +337,16 @@ g_field_info_get_field (GIFieldInfo *field_info, g_base_info_get_name ((GIBaseInfo *)field_info), g_base_info_get_type (interface)); break; + default: + break; } g_base_info_unref ((GIBaseInfo *)interface); break; } break; + default: + break; } } @@ -513,12 +517,16 @@ g_field_info_set_field (GIFieldInfo *field_info, g_base_info_get_name ((GIBaseInfo *)field_info), g_base_info_get_type (interface)); break; + default: + break; } g_base_info_unref ((GIBaseInfo *)interface); break; } break; + default: + break; } } else { switch (g_type_info_get_tag (type_info)) diff --git a/girffi.c b/girffi.c index 30642fe18..86a13052e 100644 --- a/girffi.c +++ b/girffi.c @@ -102,6 +102,8 @@ gi_type_tag_get_ffi_type_internal (GITypeTag tag, return &ffi_type_pointer; else return &ffi_type_void; + default: + break; } g_assert_not_reached (); diff --git a/girnode.c b/girnode.c index fb21c2884..decd84201 100644 --- a/girnode.c +++ b/girnode.c @@ -923,6 +923,8 @@ _g_ir_node_can_have_member (GIrNode *node) case G_IR_NODE_FIELD: case G_IR_NODE_XREF: return FALSE; + default: + g_assert_not_reached (); }; return FALSE; } @@ -2305,6 +2307,8 @@ _g_ir_node_build_typelib (GIrNode *node, blob->size = strlen (constant->value) + 1; memcpy (&data[blob->offset], constant->value, blob->size); break; + default: + g_assert_not_reached (); } *offset2 += ALIGN_VALUE (blob->size, 4); diff --git a/girparser.c b/girparser.c index 893a9a4eb..97e62a533 100644 --- a/girparser.c +++ b/girparser.c @@ -3092,6 +3092,8 @@ start_element_handler (GMarkupParseContext *context, ctx, error)) goto out; break; + default: + break; } if (*error == NULL && ctx->state != STATE_PASSTHROUGH) diff --git a/girwriter.c b/girwriter.c index bb82a46f6..7b255423f 100644 --- a/girwriter.c +++ b/girwriter.c @@ -505,6 +505,8 @@ write_callable_info (const gchar *namespace, case GI_DIRECTION_INOUT: xml_printf (file, " direction=\"inout\""); break; + default: + g_assert_not_reached (); } if (g_arg_info_may_be_null (arg)) @@ -529,6 +531,8 @@ write_callable_info (const gchar *namespace, case GI_SCOPE_TYPE_NOTIFIED: xml_printf (file, " scope=\"notified\""); break; + default: + g_assert_not_reached (); } if (g_arg_info_get_closure (arg) >= 0) From cff8329f7082c4199825ded627dbd50583e6bc1f Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sun, 29 Jul 2018 17:33:22 +0200 Subject: [PATCH 586/692] build: enable -Wredundant-decls The ffi decls were added in cbdd9ee09e367e4dd to work around broken ffi headers. Let's assume this is fixed now. --- girepository-private.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/girepository-private.h b/girepository-private.h index bbd34e3ec..de0b04e6e 100644 --- a/girepository-private.h +++ b/girepository-private.h @@ -113,13 +113,4 @@ GIVFuncInfo * _g_base_info_find_vfunc (GIRealInfo *rinfo, gint n_vfuncs, const gchar *name); -extern ffi_status ffi_prep_closure_loc (ffi_closure *, - ffi_cif *, - void (*fun)(ffi_cif *, void *, void **, void *), - void *user_data, - void *codeloc); -extern void *ffi_closure_alloc (size_t size, void **code); -extern void ffi_closure_free (void *); - - #endif /* __GIREPOSITORY_PRIVATE_H__ */ From a060582afeb05464612ec25c1dc118923259758d Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Mon, 30 Jul 2018 07:53:01 +0200 Subject: [PATCH 587/692] girepository: port from g_type_class_add_private() to G_ADD_PRIVATE() This lets us enable -Wdeprecated-declarations --- girepository.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/girepository.c b/girepository.c index 819f8e76a..c1fa3d3a7 100644 --- a/girepository.c +++ b/girepository.c @@ -66,7 +66,7 @@ struct _GIRepositoryPrivate GHashTable *info_by_error_domain; /* GQuark -> GIBaseInfo */ }; -G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT); +G_DEFINE_TYPE_WITH_CODE (GIRepository, g_irepository, G_TYPE_OBJECT, G_ADD_PRIVATE (GIRepository)); #ifdef G_PLATFORM_WIN32 @@ -104,8 +104,7 @@ DllMain (HINSTANCE hinstDLL, static void g_irepository_init (GIRepository *repository) { - repository->priv = G_TYPE_INSTANCE_GET_PRIVATE (repository, G_TYPE_IREPOSITORY, - GIRepositoryPrivate); + repository->priv = g_irepository_get_instance_private (repository); repository->priv->typelibs = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) NULL, @@ -145,8 +144,6 @@ g_irepository_class_init (GIRepositoryClass *class) gobject_class = G_OBJECT_CLASS (class); gobject_class->finalize = g_irepository_finalize; - - g_type_class_add_private (class, sizeof (GIRepositoryPrivate)); } static void From 8c36d53cba9bc23f17d2d06d060100e134a46732 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Fri, 3 Aug 2018 08:06:08 +0200 Subject: [PATCH 588/692] girnode: remove wrongly added g_assert_not_reached(). Fixes #218 Added in 9535fc48. After the switch it calls _g_ir_node_build_typelib() again handling the other types. --- girnode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girnode.c b/girnode.c index decd84201..fadfe56f7 100644 --- a/girnode.c +++ b/girnode.c @@ -2308,7 +2308,7 @@ _g_ir_node_build_typelib (GIrNode *node, memcpy (&data[blob->offset], constant->value, blob->size); break; default: - g_assert_not_reached (); + break; } *offset2 += ALIGN_VALUE (blob->size, 4); From 4b32b6e11683f3944fbaa99bd91c362fe9853f81 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Mon, 19 Nov 2018 21:49:13 -0300 Subject: [PATCH 589/692] writer: Include documentation and symbol position in source files Some documentation tool (as hotdoc[0]) need to have information about symbol declaration and documentation positions in the source files to be able to do smart indexing (automatically build the documenation index). [0] https://hotdoc.github.io/ Fixes #175 --- girparser.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index 97e62a533..d545d3102 100644 --- a/girparser.c +++ b/girparser.c @@ -2828,7 +2828,7 @@ start_element_handler (GMarkupParseContext *context, if (start_discriminator (context, element_name, attribute_names, attribute_values, ctx, error)) - goto out; + goto out; if (strcmp ("doc", element_name) == 0 || strcmp ("doc-deprecated", element_name) == 0 || strcmp ("doc-stability", element_name) == 0 || strcmp ("doc-version", element_name) == 0) { @@ -3068,6 +3068,13 @@ start_element_handler (GMarkupParseContext *context, goto out; break; + case 's': + if (strcmp ("source-position", element_name) == 0) + { + state_switch (ctx, STATE_PASSTHROUGH); + goto out; + } + break; case 'u': if (start_union (context, element_name, attribute_names, attribute_values, From 722518e5bc2afa6f596f9287f52d972fac31f73f Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sun, 9 Dec 2018 18:04:49 +0100 Subject: [PATCH 590/692] docs: fix gtk-doc warnings and update version infos Move things around and rename things until gtk-doc is happy. This also moves the "Since" annotations to the next stable releases and adds version added info for g_callable_info_get_instance_ownership_transfer() and g_struct_info_find_field(). --- giarginfo.c | 4 ++-- gibaseinfo.h | 17 ----------------- gicallableinfo.c | 3 ++- giconstantinfo.c | 4 ++-- gienuminfo.c | 8 ++++---- gifieldinfo.c | 2 +- gifunctioninfo.c | 2 +- giinterfaceinfo.c | 2 +- giobjectinfo.c | 2 +- gipropertyinfo.c | 2 +- giregisteredtypeinfo.c | 2 +- girepository.c | 4 ++-- gisignalinfo.c | 2 +- gistructinfo.c | 3 ++- gistructinfo.h | 2 +- gitypeinfo.c | 2 +- gitypelib-internal.h | 4 ++-- gitypelib.c | 2 +- gitypes.h | 18 +++++++++++++----- giunioninfo.c | 2 +- giversionmacros.h | 14 ++++++++++++++ givfuncinfo.c | 2 +- 22 files changed, 55 insertions(+), 48 deletions(-) diff --git a/giarginfo.c b/giarginfo.c index 6bc53c484..381c38395 100644 --- a/giarginfo.c +++ b/giarginfo.c @@ -41,7 +41,7 @@ * * Struct hierarchy * - * GIBaseInfo + * GIBaseInfo * +----GIArgInfo * * @@ -179,7 +179,7 @@ g_arg_info_may_be_null (GIArgInfo *info) * Obtain if an argument is only useful in C. * * Returns: %TRUE if argument is only useful in C. - * Since: 1.29.0 + * Since: 1.30 */ gboolean g_arg_info_is_skip (GIArgInfo *info) diff --git a/gibaseinfo.h b/gibaseinfo.h index 52471df33..f8f7191b3 100644 --- a/gibaseinfo.h +++ b/gibaseinfo.h @@ -33,23 +33,6 @@ G_BEGIN_DECLS -/** - * GIBaseInfoStub: - * - * TODO - */ -struct _GIBaseInfoStub { - /* */ - gint32 dummy1; - gint32 dummy2; - gpointer dummy3; - gpointer dummy4; - gpointer dummy5; - guint32 dummy6; - guint32 dummy7; - gpointer padding[4]; -}; - /** * GIAttributeIter: * diff --git a/gicallableinfo.c b/gicallableinfo.c index e9a426e15..3048e1624 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -48,7 +48,7 @@ * * Struct hierarchy * - * GIBaseInfo + * GIBaseInfo * +----GICallableInfo * +----GIFunctionInfo * +----GISignalInfo @@ -297,6 +297,7 @@ g_callable_info_get_caller_owns (GICallableInfo *info) * Obtains the ownership transfer for the instance argument. * #GITransfer contains a list of possible transfer values. * + * Since: 1.42 * Returns: the transfer mode of the instance argument */ GITransfer diff --git a/giconstantinfo.c b/giconstantinfo.c index d44646ee7..c18a9d3fc 100644 --- a/giconstantinfo.c +++ b/giconstantinfo.c @@ -41,7 +41,7 @@ * * Struct hierarchy * - * GIBaseInfo + * GIBaseInfo * +----GIConstantInfo * * @@ -78,7 +78,7 @@ g_constant_info_get_type (GIConstantInfo *info) * * Free the value returned from g_constant_info_get_value(). * - * Since: 1.30.1 + * Since: 1.32 */ void g_constant_info_free_value (GIConstantInfo *info, diff --git a/gienuminfo.c b/gienuminfo.c index 42930b2f5..2dc4b167f 100644 --- a/gienuminfo.c +++ b/gienuminfo.c @@ -40,7 +40,7 @@ * * Struct hierarchy * - * GIBaseInfo + * GIBaseInfo * +----GIRegisteredTypeInfo * +----GIEnumInfo * @@ -78,7 +78,7 @@ g_enum_info_get_n_values (GIEnumInfo *info) * * Returns: (transfer none): the string form of the error domain associated * with this enum, or %NULL. - * Since: 1.29.17 + * Since: 1.30 */ const gchar * g_enum_info_get_error_domain (GIEnumInfo *info) @@ -132,7 +132,7 @@ g_enum_info_get_value (GIEnumInfo *info, * Obtain the number of methods that this enum type has. * * Returns: number of methods - * Since: 1.29.17 + * Since: 1.30 */ gint g_enum_info_get_n_methods (GIEnumInfo *info) @@ -157,7 +157,7 @@ g_enum_info_get_n_methods (GIEnumInfo *info) * * Returns: (transfer full): the #GIFunctionInfo. Free the struct by calling * g_base_info_unref() when done. - * Since: 1.29.17 + * Since: 1.30 */ GIFunctionInfo * g_enum_info_get_method (GIEnumInfo *info, diff --git a/gifieldinfo.c b/gifieldinfo.c index 4d07304e3..b5264ec74 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -44,7 +44,7 @@ * * Struct hierarchy * - * GIBaseInfo + * GIBaseInfo * +----GIFieldInfo * * diff --git a/gifunctioninfo.c b/gifunctioninfo.c index b5720244e..366850d5a 100644 --- a/gifunctioninfo.c +++ b/gifunctioninfo.c @@ -45,7 +45,7 @@ * * Struct hierarchy * - * GIBaseInfo + * GIBaseInfo * +----GICallableInfo * +----GIFunctionInfo * +----GISignalInfo diff --git a/giinterfaceinfo.c b/giinterfaceinfo.c index d60729c37..203113b6e 100644 --- a/giinterfaceinfo.c +++ b/giinterfaceinfo.c @@ -41,7 +41,7 @@ * * Struct hierarchy * - * GIBaseInfo + * GIBaseInfo * +----GIRegisteredTypeInfo * +----GIInterfaceInfo * diff --git a/giobjectinfo.c b/giobjectinfo.c index 0991b80e8..fb57bd62f 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -42,7 +42,7 @@ * * Struct hierarchy * - * GIBaseInfo + * GIBaseInfo * +----GIRegisteredTypeInfo * +----GIObjectInfo * diff --git a/gipropertyinfo.c b/gipropertyinfo.c index 338f360bf..e58d46006 100644 --- a/gipropertyinfo.c +++ b/gipropertyinfo.c @@ -39,7 +39,7 @@ * * Struct hierarchy * - * GIBaseInfo + * GIBaseInfo * +----GIPropertyInfo * * diff --git a/giregisteredtypeinfo.c b/giregisteredtypeinfo.c index 1555c459b..411b9b950 100644 --- a/giregisteredtypeinfo.c +++ b/giregisteredtypeinfo.c @@ -47,7 +47,7 @@ * * Struct hierarchy * - * GIBaseInfo + * GIBaseInfo * +----GIRegisteredTypeInfo * +----GIEnumInfo * +----GIInterfaceInfo diff --git a/girepository.c b/girepository.c index c1fa3d3a7..8bc49eb16 100644 --- a/girepository.c +++ b/girepository.c @@ -220,7 +220,7 @@ g_irepository_prepend_search_path (const char *directory) * g_irepository_get_search_path: * * Returns the current search path #GIRepository will use when loading - * typelib files. The list is internal to #GIRespository and should not + * typelib files. The list is internal to #GIRepository and should not * be freed, nor should its string elements. * * Returns: (element-type filename) (transfer none): #GSList of strings @@ -900,7 +900,7 @@ find_by_error_domain_foreach (gpointer key, * * Returns: (transfer full): #GIEnumInfo representing metadata about @domain's * enum type, or %NULL - * Since: 1.29.17 + * Since: 1.30 */ GIEnumInfo * g_irepository_find_by_error_domain (GIRepository *repository, diff --git a/gisignalinfo.c b/gisignalinfo.c index e72890d78..5f8fa880c 100644 --- a/gisignalinfo.c +++ b/gisignalinfo.c @@ -42,7 +42,7 @@ * * Struct hierarchy * - * GIBaseInfo + * GIBaseInfo * +----GICallableInfo * +----GIFunctionInfo * +----GISignalInfo diff --git a/gistructinfo.c b/gistructinfo.c index bd7774637..7db417fc4 100644 --- a/gistructinfo.c +++ b/gistructinfo.c @@ -42,7 +42,7 @@ * * Struct hierarchy * - * GIBaseInfo + * GIBaseInfo * +----GIRegisteredTypeInfo * +----GIStructInfo * @@ -123,6 +123,7 @@ g_struct_info_get_field (GIStructInfo *info, * * Obtain the type information for field named @name. * + * Since: 1.46 * Returns: (transfer full): the #GIFieldInfo or %NULL if not found, * free it with g_base_info_unref() when done. */ diff --git a/gistructinfo.h b/gistructinfo.h index 4a60d5bb2..6e70fea71 100644 --- a/gistructinfo.h +++ b/gistructinfo.h @@ -48,7 +48,7 @@ GI_AVAILABLE_IN_ALL GIFieldInfo * g_struct_info_get_field (GIStructInfo *info, gint n); -GI_AVAILABLE_IN_ALL +GI_AVAILABLE_IN_1_46 GIFieldInfo * g_struct_info_find_field (GIStructInfo *info, const gchar *name); diff --git a/gitypeinfo.c b/gitypeinfo.c index 8b2e3ec92..1434b2f32 100644 --- a/gitypeinfo.c +++ b/gitypeinfo.c @@ -46,7 +46,7 @@ * * Struct hierarchy * - * GIBaseInfo + * GIBaseInfo * +----GITypeInfo * * diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 281192eb8..b44ba041b 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -528,7 +528,7 @@ typedef struct { * @constructor: The function acts as a constructor for the object it is * contained in. * @wraps_vfunc: The function is a simple wrapper for a virtual function. - * @throws: (deprecated): This is now additionally stored in the #SignatureBlob. + * @throws: This is now additionally stored in the #SignatureBlob. (deprecated) * @index: Index of the property that this function is a setter or getter of * in the array of properties of the containing interface, or index * of the virtual function that this function wraps. @@ -996,7 +996,7 @@ typedef struct { * virtual function. * @class_closure: Set if this virtual function is the class closure of a * signal. - * @throws: (deprecated): This is now additionally stored in the #SignatureBlob. + * @throws: This is now additionally stored in the #SignatureBlob. (deprecated) * @reserved: Reserved for future use. * @signal: The index of the signal in the list of signals of the object or * interface to which this virtual function belongs. diff --git a/gitypelib.c b/gitypelib.c index dbc7261e7..de11748b5 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -2235,7 +2235,7 @@ static GSList *library_paths; * path (ie. LD_LIBRARY_PATH and DT_RPATH in ELF systems). * See the documentation of your dynamic linker for full details. * - * Since: 1.35.8 + * Since: 1.36 */ void g_irepository_prepend_library_path (const char *directory) diff --git a/gitypes.h b/gitypes.h index b96ae0b37..338975203 100644 --- a/gitypes.h +++ b/gitypes.h @@ -31,9 +31,17 @@ G_BEGIN_DECLS -#ifndef __GTK_DOC_IGNORE__ -typedef struct _GIBaseInfoStub GIBaseInfo; -#endif +typedef struct _GIBaseInfoStub { + /* */ + gint32 dummy1; + gint32 dummy2; + gpointer dummy3; + gpointer dummy4; + gpointer dummy5; + guint32 dummy6; + guint32 dummy7; + gpointer padding[4]; +} GIBaseInfo; /** * GICallableInfo: @@ -60,7 +68,7 @@ typedef GIBaseInfo GIFunctionInfo; * * Struct hierarchy * - * GIBaseInfo + * GIBaseInfo * +----GICallableInfo * +----GIFunctionInfo * +----GISignalInfo @@ -135,7 +143,7 @@ typedef GIBaseInfo GIConstantInfo; * * Struct hierarchy * - * GIBaseInfo + * GIBaseInfo * +----GIValueInfo * * diff --git a/giunioninfo.c b/giunioninfo.c index 9a7f86135..7bc81aa0f 100644 --- a/giunioninfo.c +++ b/giunioninfo.c @@ -42,7 +42,7 @@ * * Struct hierarchy * - * GIBaseInfo + * GIBaseInfo * +----GIRegisteredTypeInfo * +----GIUnionInfo * diff --git a/giversionmacros.h b/giversionmacros.h index 3c2faf478..bf8a08619 100644 --- a/giversionmacros.h +++ b/giversionmacros.h @@ -139,4 +139,18 @@ # define GI_AVAILABLE_IN_1_44 _GI_EXTERN #endif +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_46 +# define GI_DEPRECATED_IN_1_46 GLIB_DEPRECATED +# define GI_DEPRECATED_IN_1_46_FOR(f) GLIB_DEPRECATED_FOR(f) +#else +# define GI_DEPRECATED_IN_1_46 _GI_EXTERN +# define GI_DEPRECATED_IN_1_46_FOR(f) _GI_EXTERN +#endif + +#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_46 +# define GI_AVAILABLE_IN_1_46 GLIB_UNAVAILABLE(2, 46) +#else +# define GI_AVAILABLE_IN_1_46 _GI_EXTERN +#endif + #endif /* __GIVERSIONMACROS_H__ */ diff --git a/givfuncinfo.c b/givfuncinfo.c index f20bfb062..13ab654d3 100644 --- a/givfuncinfo.c +++ b/givfuncinfo.c @@ -41,7 +41,7 @@ * * Struct hierarchy * - * GIBaseInfo + * GIBaseInfo * +----GICallableInfo * +----GIFunctionInfo * +----GISignalInfo From 5e8e1a761e4424010097988022f32c0a3dd1d363 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Wed, 12 Dec 2018 09:32:44 +0100 Subject: [PATCH 591/692] docs: Remove everything not related to libgirepository and restructure. Fixes #244 The gtk-doc docs were including some bits of overal g-i docs but mostly unfinished and outdated. We now have the general docs in sphinx so remove the duplication and make the gtk-docs just about the libgirepository API and nothing more. This also renames some titles and fixes some missing links in the struct hierarchy while at it. --- docs.c | 2 +- gitypelib-internal.h | 2 +- gitypelib.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs.c b/docs.c index a4798c41f..b032b8231 100644 --- a/docs.c +++ b/docs.c @@ -26,7 +26,7 @@ /** * SECTION:gicommontypes - * @title: common types + * @title: Common Types * @short_description: TODO * * TODO diff --git a/gitypelib-internal.h b/gitypelib-internal.h index b44ba041b..28b177d67 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -31,7 +31,7 @@ G_BEGIN_DECLS /** * SECTION:gitypelib-internal - * @title: GITypelib + * @title: GITypelib Internals * @short_description: Layout and accessors for typelib * @stability: Stable * diff --git a/gitypelib.h b/gitypelib.h index 7d0a66542..e6f46bcff 100644 --- a/gitypelib.h +++ b/gitypelib.h @@ -35,7 +35,7 @@ G_BEGIN_DECLS /** * SECTION:gitypelib - * @title: gitypelib + * @title: GITypelib * @short_description: TODO * * TODO From 292afa1d5815e043dfe40c8067026d080f1ca442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Fri, 14 Dec 2018 00:00:00 +0000 Subject: [PATCH 592/692] docs: Field offsets are in the units of bytes --- gifieldinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gifieldinfo.c b/gifieldinfo.c index b5264ec74..0a20bdb26 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -109,7 +109,7 @@ g_field_info_get_size (GIFieldInfo *info) * g_field_info_get_offset: * @info: a #GIFieldInfo * - * Obtain the offset in bits of the field member, this is relative + * Obtain the offset in bytes of the field member, this is relative * to the beginning of the struct or union. * * Returns: the field offset From e01e11be42f1ccac5b139b1f06bd34e2afcc80b9 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 9 Apr 2012 19:09:10 -0300 Subject: [PATCH 593/692] giobjectinfo: Fix some documentation for find_vfunc_using_interfaces See #66 --- giobjectinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/giobjectinfo.c b/giobjectinfo.c index fb57bd62f..efb9ad76d 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -700,7 +700,7 @@ g_object_info_find_vfunc (GIObjectInfo *info, /** * g_object_info_find_vfunc_using_interfaces: * @info: a #GIObjectInfo - * @name: name of method to obtain + * @name: name of vfunc to obtain * @implementor: (out) (transfer full): The implementor of the interface * * Locate a virtual function slot with name @name, searching both the object @@ -713,7 +713,7 @@ g_object_info_find_vfunc (GIObjectInfo *info, * Note that this function does *not* search parent classes; you will have * to chain up if that's desired. * - * Returns: (transfer full): the #GIFunctionInfo. Free the struct by calling + * Returns: (transfer full): the #GIVFuncInfo. Free the struct by calling * g_base_info_unref() when done. */ GIVFuncInfo * From db90b3b3aed9b7faed95c8e79cc0c0b60713e33e Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sat, 15 Dec 2018 00:18:23 +0100 Subject: [PATCH 594/692] baseinfo: don't abort when calling g_base_info_get_name() on a GITypeInfo. Fixes #96 GITypeInfo is a GIBaseInfo so calling g_base_info_get_name() on it should do something sensible. g_base_info_get_name() has always been documented to return NULL in case no name is available so return that instead. --- gibaseinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gibaseinfo.c b/gibaseinfo.c index ced7674e2..e47d5390c 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -377,6 +377,7 @@ g_base_info_get_name (GIBaseInfo *info) } break; case GI_INFO_TYPE_TYPE: + return NULL; default: ; g_assert_not_reached (); /* unnamed */ From 487e670b1fd64bf1a84a4f99efaba44ddacce52a Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Fri, 14 Dec 2018 11:21:29 +0100 Subject: [PATCH 595/692] girepository: Add version macros and functions. Fixes #200 This adds the following macros and functions: GI_MAJOR_VERSION, GI_MICRO_VERSION, GI_MINOR_VERSION, GI_CHECK_VERSION, gi_get_major_version,gi_get_micro_version, gi_get_minor_version. Since we share a prefix with glib we have to namespace these by using the gi_ prefix. g_gi would also work but we already export symbols with gi_ like gi_cclosure_marshal_generic(), gi_type_tag_get_ffi_type() and gi_type_info_extract_ffi_return_value(), so let's not add another naming scheme. --- girepository.h | 1 + giversion.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++ giversion.h.in | 47 +++++++++++++++++++ giversionmacros.h | 6 +++ meson.build | 12 ++++- 5 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 giversion.c create mode 100644 giversion.h.in diff --git a/girepository.h b/girepository.h index e3ed8372e..3934ab31f 100644 --- a/girepository.h +++ b/girepository.h @@ -47,6 +47,7 @@ #include #include #include +#include G_BEGIN_DECLS diff --git a/giversion.c b/giversion.c new file mode 100644 index 000000000..927190fb4 --- /dev/null +++ b/giversion.c @@ -0,0 +1,114 @@ +/* Copyright (C) 2018 Christoph Reiter + * + * 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 "config.h" + +#include + +/** + * SECTION:giversion + * @Title: Version Information + * @Short_description: macros and functions to check the girepository version + */ + +/** + * GI_MAJOR_VERSION: + * + * The major version number of the girepository library. + * + * Since: 1.60 + */ + +/** + * GI_MINOR_VERSION: + * + * The minor version number of the girepository library. + * + * Since: 1.60 + */ + +/** + * GI_MICRO_VERSION: + * + * The micro version number of the girepository library. + * + * Since: 1.60 + */ + +/** + * GI_CHECK_VERSION: + * @major: the major version to check for + * @minor: the minor version to check for + * @micro: the micro version to check for + * + * Checks the version of the girepository library that is being compiled + * against. + * + * Returns: %TRUE if the version of the girepository header files + * is the same as or newer than the passed-in version. + * + * Since: 1.60 + */ + +/** + * gi_get_major_version: + * + * Returns the major version number of the girepository library. + * (e.g. in version 1.58.2 this is 1.) + * + * Returns: the major version number of the girepository library + * + * Since: 1.60 + */ +guint +gi_get_major_version (void) +{ + return GI_MAJOR_VERSION; +} + +/** + * gi_get_minor_version: + * + * Returns the minor version number of the girepository library. + * (e.g. in version 1.58.2 this is 58.) + * + * Returns: the minor version number of the girepository library + * + * Since: 1.60 + */ +guint +gi_get_minor_version (void) +{ + return GI_MINOR_VERSION; +} + +/** + * gi_get_micro_version: + * + * Returns the micro version number of the girepository library. + * (e.g. in version 1.58.2 this is 2.) + * + * Returns: the micro version number of the girepository library + * + * Since: 1.60 + */ +guint +gi_get_micro_version (void) +{ + return GI_MICRO_VERSION; +} diff --git a/giversion.h.in b/giversion.h.in new file mode 100644 index 000000000..177d33d19 --- /dev/null +++ b/giversion.h.in @@ -0,0 +1,47 @@ +/* Copyright (C) 2018 Christoph Reiter + * + * 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 __GIVERISON_H__ +#define __GIVERISON_H__ + +#if !defined (__GIREPOSITORY_H_INSIDE__) && !defined (GI_COMPILATION) +#error "Only can be included directly." +#endif + +G_BEGIN_DECLS + +#define GI_MAJOR_VERSION @GI_MAJOR_VERSION@ +#define GI_MINOR_VERSION @GI_MINOR_VERSION@ +#define GI_MICRO_VERSION @GI_MICRO_VERSION@ + +#define GI_CHECK_VERSION(major,minor,micro) \ + (GI_MAJOR_VERSION > (major) || \ + (GI_MAJOR_VERSION == (major) && GI_MINOR_VERSION > (minor)) || \ + (GI_MAJOR_VERSION == (major) && GI_MINOR_VERSION == (minor) && \ + GI_MICRO_VERSION >= (micro))) + +GI_AVAILABLE_IN_1_60 +guint gi_get_major_version (void) G_GNUC_CONST; +GI_AVAILABLE_IN_1_60 +guint gi_get_minor_version (void) G_GNUC_CONST; +GI_AVAILABLE_IN_1_60 +guint gi_get_micro_version (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __GIVERISON_H__ */ diff --git a/giversionmacros.h b/giversionmacros.h index bf8a08619..c32e5bb86 100644 --- a/giversionmacros.h +++ b/giversionmacros.h @@ -153,4 +153,10 @@ # define GI_AVAILABLE_IN_1_46 _GI_EXTERN #endif +#if defined(GLIB_VERSION_2_60) && GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_60 +# define GI_AVAILABLE_IN_1_60 GLIB_UNAVAILABLE(2, 60) +#else +# define GI_AVAILABLE_IN_1_60 _GI_EXTERN +#endif + #endif /* __GIVERSIONMACROS_H__ */ diff --git a/meson.build b/meson.build index 6a8c5b5d8..cc8d84204 100644 --- a/meson.build +++ b/meson.build @@ -36,6 +36,12 @@ girepo_internals_dep = declare_dependency( include_directories: include_directories('.'), ) +gi_version_h = configure_file( + configuration: config, + input: 'giversion.h.in', + output: 'giversion.h', +) + girepo_headers = [ 'giarginfo.h', 'gibaseinfo.h', @@ -58,6 +64,7 @@ girepo_headers = [ 'giunioninfo.h', 'giversionmacros.h', 'givfuncinfo.h', + gi_version_h, ] girepo_sources = [ @@ -81,6 +88,7 @@ girepo_sources = [ 'gitypeinfo.c', 'gitypelib.c', 'giunioninfo.c', + 'giversion.c', 'givfuncinfo.c', ] @@ -102,6 +110,7 @@ girepo_gir_sources = files( 'gistructinfo.c', 'gitypeinfo.c', 'giunioninfo.c', + 'giversion.c', 'givfuncinfo.c', 'giarginfo.h', 'gibaseinfo.h', @@ -122,7 +131,8 @@ girepo_gir_sources = files( 'gitypes.h', 'giunioninfo.h', 'givfuncinfo.h', -) +) + [gi_version_h] + install_headers(girepo_headers, subdir: 'gobject-introspection-1.0') From cb1d5994951e88596ad67e8ea809731cc7a1fe1f Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Tue, 18 Dec 2018 12:32:53 +0000 Subject: [PATCH 596/692] meson: Use `copy` instead of an empty configuration The configure_file target has grown a `copy` argument to avoid using an empty configuration_data object since Meson 0.47. --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index cc8d84204..64cd9ece2 100644 --- a/meson.build +++ b/meson.build @@ -149,7 +149,7 @@ girepo_lib = shared_library('girepository-1.0', # Copy to builddir for use with giscanner/dumper.py when running uninstalled configure_file(input : 'gdump.c', output : 'gdump.c', - configuration : configuration_data(), + copy: true, install_dir: join_paths(get_option('datadir'), 'gobject-introspection-1.0'), install : true, ) From 13ba457c226f8fde941d80483a51fd933c335aae Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Sat, 15 Dec 2018 12:18:04 +0100 Subject: [PATCH 597/692] meson: add default compiler warning flags and enable -Werror on CI This enables various compiler warnings project wide and disables the triggered ones for each library/executable. This should give us roughly the same behaviour as with autotools. Tested with gcc8 and clang7. --- cmph/meson.build | 21 +++++++++++++++++++-- meson.build | 24 +++++++++++++++++++++--- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/cmph/meson.build b/cmph/meson.build index 368afc7b5..77c6e696a 100644 --- a/cmph/meson.build +++ b/cmph/meson.build @@ -29,9 +29,20 @@ cmph_deps = [ cc.find_library('m', required: false), ] +custom_c_args = cc.get_supported_arguments([ + '-Wno-implicit-fallthrough', + '-Wno-old-style-definition', + '-Wno-strict-prototypes', + '-Wno-suggest-attribute=noreturn', + '-Wno-type-limits', + '-Wno-undef', + '-Wno-unused-parameter', + '-Wno-cast-align', + '-Wno-unused-function', +]) cmph = static_library('cmph', sources: cmph_sources, - c_args: gi_hidden_visibility_cflags, + c_args: gi_hidden_visibility_cflags + custom_c_args, dependencies: cmph_deps, ) @@ -40,11 +51,17 @@ cmph_dep = declare_dependency( include_directories: include_directories('.'), ) +custom_c_args = cc.get_supported_arguments([ + '-Wno-old-style-definition', + '-Wno-strict-prototypes', + '-Wno-type-limits', +]) cmph_test = executable('cmph-bdz-test', '../cmph-bdz-test.c', dependencies: [ cmph_dep, glib_dep, - ] + ], + c_args: custom_c_args, ) test('cmph-bdz-test', cmph_test) diff --git a/meson.build b/meson.build index 64cd9ece2..e0f224e71 100644 --- a/meson.build +++ b/meson.build @@ -1,9 +1,14 @@ subdir('cmph') +custom_c_args = cc.get_supported_arguments([ + '-Wno-strict-prototypes', + '-Wno-old-style-definition', + '-Wno-cast-align', +]) girepo_gthash_lib = static_library('girepository-gthash', sources: 'gthash.c', include_directories : configinc, - c_args: gi_hidden_visibility_cflags, + c_args: gi_hidden_visibility_cflags + custom_c_args, dependencies: [ cmph_dep, glib_dep, @@ -17,6 +22,11 @@ girepo_gthash_dep = declare_dependency( include_directories: include_directories('.'), ) +custom_c_args = cc.get_supported_arguments([ + '-Wno-unused-parameter', + '-Wno-duplicated-branches', + '-Wno-cast-align', +]) girepo_internals_lib = static_library('girepository-internals', sources: [ 'girmodule.c', @@ -25,7 +35,7 @@ girepo_internals_lib = static_library('girepository-internals', 'girparser.c', 'girwriter.c', ], - c_args: gi_hidden_visibility_cflags, + c_args: gi_hidden_visibility_cflags + custom_c_args, include_directories : configinc, dependencies: [girepo_gthash_dep, libffi_dep], ) @@ -136,10 +146,18 @@ girepo_gir_sources = files( install_headers(girepo_headers, subdir: 'gobject-introspection-1.0') +custom_c_args = cc.get_supported_arguments([ + '-Wno-unused-parameter', + '-Wno-duplicated-branches', + '-Wno-type-limits', + '-Wno-cast-align', + '-Wno-missing-field-initializers', +]) girepo_lib = shared_library('girepository-1.0', sources: girepo_sources, include_directories : configinc, - c_args: gi_hidden_visibility_cflags + ['-DG_IREPOSITORY_COMPILATION'], + c_args: gi_hidden_visibility_cflags + ['-DG_IREPOSITORY_COMPILATION'] + + custom_c_args, dependencies: [glib_dep, gobject_dep, gmodule_dep, gio_dep, girepo_internals_dep], version: '1.0.0', From b12b08df2f428babbc9aa252d26668fc40c213ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 20 Dec 2018 00:00:00 +0000 Subject: [PATCH 598/692] Cleanup strict-prototypes warnings --- cmph/cmph_time.h | 6 ++++-- cmph/meson.build | 2 -- meson.build | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/cmph/cmph_time.h b/cmph/cmph_time.h index c03558fb6..5d5d89330 100644 --- a/cmph/cmph_time.h +++ b/cmph/cmph_time.h @@ -24,8 +24,9 @@ } *elapsed_time = (double)e_time.tv_sec + ((double)e_time.tv_usec/1000000.0); } - static inline void dummy_elapsed_time_in_seconds() + static inline void dummy_elapsed_time_in_seconds(double * elapsed_time) { + (void) elapsed_time; } static inline void elapsed_time_in_useconds(cmph_uint64 * elapsed_time) { @@ -35,8 +36,9 @@ } *elapsed_time = (cmph_uint64)(e_time.tv_sec*1000000 + e_time.tv_usec); } - static inline void dummy_elapsed_time_in_useconds() + static inline void dummy_elapsed_time_in_useconds(cmph_uint64 * elapsed_time) { + (void) elapsed_time; } #endif #endif diff --git a/cmph/meson.build b/cmph/meson.build index 77c6e696a..6b515241f 100644 --- a/cmph/meson.build +++ b/cmph/meson.build @@ -32,7 +32,6 @@ cmph_deps = [ custom_c_args = cc.get_supported_arguments([ '-Wno-implicit-fallthrough', '-Wno-old-style-definition', - '-Wno-strict-prototypes', '-Wno-suggest-attribute=noreturn', '-Wno-type-limits', '-Wno-undef', @@ -53,7 +52,6 @@ cmph_dep = declare_dependency( custom_c_args = cc.get_supported_arguments([ '-Wno-old-style-definition', - '-Wno-strict-prototypes', '-Wno-type-limits', ]) cmph_test = executable('cmph-bdz-test', '../cmph-bdz-test.c', diff --git a/meson.build b/meson.build index e0f224e71..0261e1a55 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,6 @@ subdir('cmph') custom_c_args = cc.get_supported_arguments([ - '-Wno-strict-prototypes', '-Wno-old-style-definition', '-Wno-cast-align', ]) From 9b367e74ef2fd5c04fb66132f523ffc48ca5e15c Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Tue, 1 Jan 2019 18:06:47 +0100 Subject: [PATCH 599/692] ci: enable -Werror for msys2+meson --- cmph/meson.build | 1 + girepository.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/cmph/meson.build b/cmph/meson.build index 6b515241f..d7b1e4230 100644 --- a/cmph/meson.build +++ b/cmph/meson.build @@ -38,6 +38,7 @@ custom_c_args = cc.get_supported_arguments([ '-Wno-unused-parameter', '-Wno-cast-align', '-Wno-unused-function', + '-Wno-return-type', ]) cmph = static_library('cmph', sources: cmph_sources, diff --git a/girepository.c b/girepository.c index 8bc49eb16..e262d3e8d 100644 --- a/girepository.c +++ b/girepository.c @@ -76,6 +76,8 @@ static HMODULE girepository_dll = NULL; #ifdef DLL_EXPORT +BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); + BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, From 8de3abd6421279df9cabb9988c3f39e2cc564854 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 22 Oct 2010 18:08:15 -0400 Subject: [PATCH 600/692] repository: g_irepository_get_object_gtype_interfaces Bindings in some cases need to look up information from a GType dynamically. Support that better by supplying a cache for this information. (Rebased and versioning / gtk-doc stuff added by Philip Chimento.) Closes #38. See gjs#55. --- girepository.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++ girepository.h | 6 +++ 2 files changed, 105 insertions(+) diff --git a/girepository.c b/girepository.c index e262d3e8d..84e44f4a0 100644 --- a/girepository.c +++ b/girepository.c @@ -58,12 +58,29 @@ static GIRepository *default_repository = NULL; static GSList *typelib_search_path = NULL; +typedef struct { + guint n_interfaces; + GIBaseInfo *interfaces[]; +} GTypeInterfaceCache; + +static void +gtype_interface_cache_free (gpointer data) +{ + GTypeInterfaceCache *cache = data; + guint i; + + for (i = 0; i < cache->n_interfaces; i++) + g_base_info_unref ((GIBaseInfo*) cache->interfaces[i]); + g_free (cache); +} + struct _GIRepositoryPrivate { GHashTable *typelibs; /* (string) namespace -> GITypelib */ GHashTable *lazy_typelibs; /* (string) namespace-version -> GITypelib */ GHashTable *info_by_gtype; /* GType -> GIBaseInfo */ GHashTable *info_by_error_domain; /* GQuark -> GIBaseInfo */ + GHashTable *interfaces_for_gtype; /* GType -> GTypeInterfaceCache */ }; G_DEFINE_TYPE_WITH_CODE (GIRepository, g_irepository, G_TYPE_OBJECT, G_ADD_PRIVATE (GIRepository)); @@ -123,6 +140,10 @@ g_irepository_init (GIRepository *repository) = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) NULL, (GDestroyNotify) g_base_info_unref); + repository->priv->interfaces_for_gtype + = g_hash_table_new_full (g_direct_hash, g_direct_equal, + (GDestroyNotify) NULL, + (GDestroyNotify) gtype_interface_cache_free); } static void @@ -134,6 +155,7 @@ g_irepository_finalize (GObject *object) g_hash_table_destroy (repository->priv->lazy_typelibs); g_hash_table_destroy (repository->priv->info_by_gtype); g_hash_table_destroy (repository->priv->info_by_error_domain); + g_hash_table_destroy (repository->priv->interfaces_for_gtype); (* G_OBJECT_CLASS (g_irepository_parent_class)->finalize) (G_OBJECT (repository)); } @@ -942,6 +964,83 @@ g_irepository_find_by_error_domain (GIRepository *repository, return NULL; } +/** + * g_irepository_get_object_gtype_interfaces: + * @repository: (nullable): a #GIRepository, or %NULL for the default repository + * @gtype: a #GType whose fundamental type is G_TYPE_OBJECT + * @n_interfaces: (out): Number of interfaces + * @interfaces: (out) (transfer none) (array length=n_interfaces): Interfaces for @gtype + * + * Look up the implemented interfaces for @gtype. This function + * cannot fail per se; but for a totally "unknown" #GType, it may + * return 0 implemented interfaces. + * + * The semantics of this function are designed for a dynamic binding, + * where in certain cases (such as a function which returns an + * interface which may have "hidden" implementation classes), not all + * data may be statically known, and will have to be determined from + * the #GType of the object. An example is g_file_new_for_path() + * returning a concrete class of #GLocalFile, which is a #GType we + * see at runtime, but not statically. + * + * Since: 1.60 + */ +void +g_irepository_get_object_gtype_interfaces (GIRepository *repository, + GType gtype, + guint *n_interfaces_out, + GIInterfaceInfo **interfaces_out) +{ + GTypeInterfaceCache *cache; + + g_return_if_fail (g_type_fundamental (gtype) == G_TYPE_OBJECT); + + repository = get_repository (repository); + + cache = g_hash_table_lookup (repository->priv->interfaces_for_gtype, + (gpointer) gtype); + if (cache == NULL) + { + GType *interfaces; + guint n_interfaces; + guint i; + GList *interface_infos = NULL, *iter; + + interfaces = g_type_interfaces (gtype, &n_interfaces); + for (i = 0; i < n_interfaces; i++) + { + GIBaseInfo *base_info; + + base_info = g_irepository_find_by_gtype (repository, interfaces[i]); + if (base_info == NULL) + continue; + + if (g_base_info_get_type (base_info) != GI_INFO_TYPE_INTERFACE) + { + /* FIXME - could this really happen? */ + g_base_info_unref (base_info); + continue; + } + + if (!g_list_find (interface_infos, base_info)) + interface_infos = g_list_prepend (interface_infos, base_info); + } + + cache = g_malloc (sizeof (GTypeInterfaceCache) + + sizeof (GIBaseInfo*) * g_list_length (interface_infos)); + cache->n_interfaces = g_list_length (interface_infos); + for (iter = interface_infos, i = 0; iter; iter = iter->next, i++) + cache->interfaces[i] = iter->data; + g_list_free (interface_infos); + + g_hash_table_insert (repository->priv->interfaces_for_gtype, (gpointer) gtype, + cache); + } + + *n_interfaces_out = cache->n_interfaces; + *interfaces_out = *((GIInterfaceInfo**)&(cache->interfaces[0])); +} + static void collect_namespaces (gpointer key, gpointer value, diff --git a/girepository.h b/girepository.h index 3934ab31f..8dfcca2c9 100644 --- a/girepository.h +++ b/girepository.h @@ -159,6 +159,12 @@ GI_AVAILABLE_IN_ALL GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository, GType gtype); +GI_AVAILABLE_IN_1_60 +void g_irepository_get_object_gtype_interfaces (GIRepository *repository, + GType gtype, + guint *n_interfaces_out, + GIInterfaceInfo **interfaces_out); + GI_AVAILABLE_IN_ALL gint g_irepository_get_n_infos (GIRepository *repository, const gchar *namespace_); From 4c0a8388d55abb0c7d1979063200517c84e3cf09 Mon Sep 17 00:00:00 2001 From: Rico Tzschichholz Date: Wed, 16 Jan 2019 21:04:26 +0100 Subject: [PATCH 601/692] repository: Fix annotation for g_irepository_get_object_gtype_interfaces() Introduced by 9826d952358c8330d72ecba062f489fbdc31bbd1 --- girepository.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/girepository.c b/girepository.c index 84e44f4a0..77ba8ed51 100644 --- a/girepository.c +++ b/girepository.c @@ -968,8 +968,8 @@ g_irepository_find_by_error_domain (GIRepository *repository, * g_irepository_get_object_gtype_interfaces: * @repository: (nullable): a #GIRepository, or %NULL for the default repository * @gtype: a #GType whose fundamental type is G_TYPE_OBJECT - * @n_interfaces: (out): Number of interfaces - * @interfaces: (out) (transfer none) (array length=n_interfaces): Interfaces for @gtype + * @n_interfaces_out: (out): Number of interfaces + * @interfaces_out: (out) (transfer none) (array length=n_interfaces_out): Interfaces for @gtype * * Look up the implemented interfaces for @gtype. This function * cannot fail per se; but for a totally "unknown" #GType, it may From d17edde56885cf8912bb9229203cc990961a283a Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Thu, 31 Jan 2019 16:44:13 -0500 Subject: [PATCH 602/692] Fix possible leak of transitive dependency name. If a transitive dependency appears twice, the original pointer will be removed from the hash table. Since these names were created by g_strsplit, they need to be freed, or they will leak. --- girepository.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/girepository.c b/girepository.c index 77ba8ed51..bc9e4ed54 100644 --- a/girepository.c +++ b/girepository.c @@ -562,7 +562,8 @@ g_irepository_get_dependencies (GIRepository *repository, g_return_val_if_fail (typelib != NULL, NULL); /* Load the dependencies. */ - transitive_dependencies = g_hash_table_new (g_str_hash, g_str_equal); + transitive_dependencies = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); get_typelib_dependencies_transitive (repository, typelib, transitive_dependencies); From 6747ec55dd199ba037b636a7dde6ecdefe073e1b Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Thu, 31 Jan 2019 16:46:38 -0500 Subject: [PATCH 603/692] Fix a possible use-after-free. If g_mapped_file_new fails, then `version` will be freed, but it was already added to the hash table. This means there could be a use-after-free while doing a lookup on the hash table the next time. --- girepository.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girepository.c b/girepository.c index bc9e4ed54..ca5dc2b9b 100644 --- a/girepository.c +++ b/girepository.c @@ -1405,7 +1405,6 @@ enumerate_namespace_versions (const gchar *namespace, g_free (version); continue; } - g_hash_table_insert (found_versions, version, version); path = g_build_filename (dirname, entry, NULL); mfile = g_mapped_file_new (path, FALSE, &error); @@ -1422,6 +1421,7 @@ enumerate_namespace_versions (const gchar *namespace, candidate->path = path; candidate->version = version; candidates = g_slist_prepend (candidates, candidate); + g_hash_table_add (found_versions, version); } g_dir_close (dir); index++; From 1a19f05a0e3a7cb7af66257c119ff956c15dc569 Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Tue, 30 Apr 2019 16:07:39 +0800 Subject: [PATCH 604/692] build: Force-include msvc_recommended_pragmas.h on Visual Studio By doing so, we essentially cover the various compiler flags that we want to use for non-Visual Studio builds to check for warnings that might cause real concern. This also skips the checks for the various GCC-isque CFlag checks that are scattered in the various build files on Visual Studio builds, since they are essentially meaningless on Visual Studio builds. --- cmph/meson.build | 38 +++++++++++++++++++++++--------------- meson.build | 43 +++++++++++++++++++++++++++---------------- 2 files changed, 50 insertions(+), 31 deletions(-) diff --git a/cmph/meson.build b/cmph/meson.build index d7b1e4230..5bc41a33f 100644 --- a/cmph/meson.build +++ b/cmph/meson.build @@ -29,17 +29,22 @@ cmph_deps = [ cc.find_library('m', required: false), ] -custom_c_args = cc.get_supported_arguments([ - '-Wno-implicit-fallthrough', - '-Wno-old-style-definition', - '-Wno-suggest-attribute=noreturn', - '-Wno-type-limits', - '-Wno-undef', - '-Wno-unused-parameter', - '-Wno-cast-align', - '-Wno-unused-function', - '-Wno-return-type', -]) +custom_c_args = [] + +if cc.get_id() != 'msvc' + custom_c_args = cc.get_supported_arguments([ + '-Wno-implicit-fallthrough', + '-Wno-old-style-definition', + '-Wno-suggest-attribute=noreturn', + '-Wno-type-limits', + '-Wno-undef', + '-Wno-unused-parameter', + '-Wno-cast-align', + '-Wno-unused-function', + '-Wno-return-type', + ]) +endif + cmph = static_library('cmph', sources: cmph_sources, c_args: gi_hidden_visibility_cflags + custom_c_args, @@ -51,10 +56,13 @@ cmph_dep = declare_dependency( include_directories: include_directories('.'), ) -custom_c_args = cc.get_supported_arguments([ - '-Wno-old-style-definition', - '-Wno-type-limits', -]) +if cc.get_id() != 'msvc' + custom_c_args = cc.get_supported_arguments([ + '-Wno-old-style-definition', + '-Wno-type-limits', + ]) +endif + cmph_test = executable('cmph-bdz-test', '../cmph-bdz-test.c', dependencies: [ cmph_dep, diff --git a/meson.build b/meson.build index 0261e1a55..1d7aed6b8 100644 --- a/meson.build +++ b/meson.build @@ -1,9 +1,14 @@ subdir('cmph') -custom_c_args = cc.get_supported_arguments([ - '-Wno-old-style-definition', - '-Wno-cast-align', -]) +custom_c_args = [] + +if cc.get_id() != 'msvc' + custom_c_args = cc.get_supported_arguments([ + '-Wno-old-style-definition', + '-Wno-cast-align', + ]) +endif + girepo_gthash_lib = static_library('girepository-gthash', sources: 'gthash.c', include_directories : configinc, @@ -21,11 +26,14 @@ girepo_gthash_dep = declare_dependency( include_directories: include_directories('.'), ) -custom_c_args = cc.get_supported_arguments([ - '-Wno-unused-parameter', - '-Wno-duplicated-branches', - '-Wno-cast-align', -]) +if cc.get_id() != 'msvc' + custom_c_args = cc.get_supported_arguments([ + '-Wno-unused-parameter', + '-Wno-duplicated-branches', + '-Wno-cast-align', + ]) +endif + girepo_internals_lib = static_library('girepository-internals', sources: [ 'girmodule.c', @@ -145,13 +153,16 @@ girepo_gir_sources = files( install_headers(girepo_headers, subdir: 'gobject-introspection-1.0') -custom_c_args = cc.get_supported_arguments([ - '-Wno-unused-parameter', - '-Wno-duplicated-branches', - '-Wno-type-limits', - '-Wno-cast-align', - '-Wno-missing-field-initializers', -]) +if cc.get_id() != 'msvc' + custom_c_args = cc.get_supported_arguments([ + '-Wno-unused-parameter', + '-Wno-duplicated-branches', + '-Wno-type-limits', + '-Wno-cast-align', + '-Wno-missing-field-initializers', + ]) +endif + girepo_lib = shared_library('girepository-1.0', sources: girepo_sources, include_directories : configinc, From a458c66cbf1605abef73a2a22940da10b99a7bc5 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Thu, 20 Jun 2019 00:18:13 -0700 Subject: [PATCH 605/692] girepository: Return pointer array for interface cache In g_irepository_get_object_gtype_interfaces(), returning the address of the first GIBaseInfo* does not work reliably, because the GIBaseInfos are not necessarily stored contiguously. So the second and subsequent ones might be garbage. Instead, return the address of the array of GIBaseInfo pointers. Add a test that verifies the functionality, as well. This is unfortunately an API and ABI break. --- girepository.c | 6 +++--- girepository.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/girepository.c b/girepository.c index ca5dc2b9b..08149da84 100644 --- a/girepository.c +++ b/girepository.c @@ -984,13 +984,13 @@ g_irepository_find_by_error_domain (GIRepository *repository, * returning a concrete class of #GLocalFile, which is a #GType we * see at runtime, but not statically. * - * Since: 1.60 + * Since: 1.62 */ void g_irepository_get_object_gtype_interfaces (GIRepository *repository, GType gtype, guint *n_interfaces_out, - GIInterfaceInfo **interfaces_out) + GIInterfaceInfo ***interfaces_out) { GTypeInterfaceCache *cache; @@ -1039,7 +1039,7 @@ g_irepository_get_object_gtype_interfaces (GIRepository *repository, } *n_interfaces_out = cache->n_interfaces; - *interfaces_out = *((GIInterfaceInfo**)&(cache->interfaces[0])); + *interfaces_out = (GIInterfaceInfo**)&cache->interfaces[0]; } static void diff --git a/girepository.h b/girepository.h index 8dfcca2c9..073985b6e 100644 --- a/girepository.h +++ b/girepository.h @@ -163,7 +163,7 @@ GI_AVAILABLE_IN_1_60 void g_irepository_get_object_gtype_interfaces (GIRepository *repository, GType gtype, guint *n_interfaces_out, - GIInterfaceInfo **interfaces_out); + GIInterfaceInfo ***interfaces_out); GI_AVAILABLE_IN_ALL gint g_irepository_get_n_infos (GIRepository *repository, From 995d87db17526b246402a323e8f118c8e3d5020f Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Wed, 15 Jul 2015 13:11:45 +0200 Subject: [PATCH 606/692] scanner: parse and expose function macros This is useful for documentation tools, and other utilities that rely on full introspection of the C API of a given library. --- girparser.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index d545d3102..53450baf5 100644 --- a/girparser.c +++ b/girparser.c @@ -2845,7 +2845,12 @@ start_element_handler (GMarkupParseContext *context, break; case 'f': - if (start_function (context, element_name, + if (strcmp ("function-macro", element_name) == 0) + { + state_switch (ctx, STATE_PASSTHROUGH); + goto out; + } + else if (start_function (context, element_name, attribute_names, attribute_values, ctx, error)) goto out; From 8958f167bfe8b6e035b4ecd412f8584e85d1beed Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Fri, 26 Jul 2019 18:46:15 +0200 Subject: [PATCH 607/692] meson: don't pass "install" to configure_file() unless really needed In our case it was never needed because it defaults to true if install_dir is set, which it always is for all calls. This avoids a warning when running with newer meson where it complains that install is only available with 0.50+. Fixes #298 --- meson.build | 1 - 1 file changed, 1 deletion(-) diff --git a/meson.build b/meson.build index 1d7aed6b8..0183153e0 100644 --- a/meson.build +++ b/meson.build @@ -179,7 +179,6 @@ configure_file(input : 'gdump.c', output : 'gdump.c', copy: true, install_dir: join_paths(get_option('datadir'), 'gobject-introspection-1.0'), - install : true, ) girepo_dep = declare_dependency( From e0f9f94a7e77b30a3018ce089936ba929a262d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 14 Aug 2019 23:09:52 +0200 Subject: [PATCH 608/692] structinfo: Fix offset in find_method() The current offset only considers the fields themselves, but not the optional embedded type that may follow each field. Use the existing helper function instead of computing the offset to fix the issue. --- gistructinfo.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/gistructinfo.c b/gistructinfo.c index 7db417fc4..a1edfa9f9 100644 --- a/gistructinfo.c +++ b/gistructinfo.c @@ -215,12 +215,9 @@ g_struct_info_find_method (GIStructInfo *info, { gint offset; GIRealInfo *rinfo = (GIRealInfo *)info; - Header *header = (Header *)rinfo->typelib->data; StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; - offset = rinfo->offset + header->struct_blob_size - + blob->n_fields * header->field_blob_size; - + offset = g_struct_get_field_offset (info, blob->n_fields); return _g_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_methods, name); } From ddaa2a9ec33f4b48827dd2f1c84b42dff3307a4a Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Thu, 15 Aug 2019 09:41:30 -0400 Subject: [PATCH 609/692] Make meson.override_find_program working on more complex use cases Add some missing `meson.override_find_program` And make sure that the `.gir` we build are found when used uninstalled as a concequence of `meson.override_find_program`. --- girparser.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/girparser.c b/girparser.c index 53450baf5..fb47e75c2 100644 --- a/girparser.c +++ b/girparser.c @@ -309,6 +309,10 @@ locate_gir (GIrParser *parser, if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) return path; g_free (path); + path = g_build_filename (UNINSTALLED_GIR_DIR, girname, NULL); + if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) + return path; + g_free (path); return NULL; } From 590421cf14a821a0d50abeaa183803cad4c2ea9a Mon Sep 17 00:00:00 2001 From: Tom Schoonjans Date: Tue, 10 Sep 2019 12:49:04 +0100 Subject: [PATCH 610/692] build: use proper dylib versioning on macOS --- meson.build | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 0183153e0..204659fe9 100644 --- a/meson.build +++ b/meson.build @@ -163,6 +163,15 @@ if cc.get_id() != 'msvc' ]) endif +lib_version = '1.0.0' +lib_version_arr = lib_version.split('.') +lib_version_major = lib_version_arr[0].to_int() +lib_version_minor = lib_version_arr[1].to_int() +lib_version_micro = lib_version_arr[2].to_int() + +osx_current = lib_version_major + 1 +lib_osx_version = [osx_current, '@0@.@1@'.format(osx_current, lib_version_minor)] + girepo_lib = shared_library('girepository-1.0', sources: girepo_sources, include_directories : configinc, @@ -170,7 +179,8 @@ girepo_lib = shared_library('girepository-1.0', custom_c_args, dependencies: [glib_dep, gobject_dep, gmodule_dep, gio_dep, girepo_internals_dep], - version: '1.0.0', + version: lib_version, + darwin_versions: lib_osx_version, install: true, ) From fcc94454c1b151e8ae46b4777ac8eac7317fea7d Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Thu, 10 Oct 2019 13:34:23 -0700 Subject: [PATCH 611/692] girepository: Fix memory leak In g_irepository_get_object_gtype_interfaces() --- girepository.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/girepository.c b/girepository.c index 08149da84..fd668c5a5 100644 --- a/girepository.c +++ b/girepository.c @@ -1036,6 +1036,8 @@ g_irepository_get_object_gtype_interfaces (GIRepository *repository, g_hash_table_insert (repository->priv->interfaces_for_gtype, (gpointer) gtype, cache); + + g_free (interfaces); } *n_interfaces_out = cache->n_interfaces; From 67a0f3e914a38b5638d544a5e0f5d7b6cf175ba3 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 13 Nov 2019 19:37:00 +0100 Subject: [PATCH 612/692] girepository: Also store GType cache misses There are notably 4 classes of GTypes where a girepository lookup might fail: - GTypes from private interfaces in public objects (eg. MetaCullable in mutter) - GTypes for private base objects with public interfaces (eg. GLocalFile in GLib) - GTypes registered from the language, and presumably not coming from the GIR - GTypes of objects/interfaces that we didn't load a typelib for It is moot to look for those over and over again, and a full lookup can be taxing if looking up for a method/property on objects with those characteristics. It seems we can cache the misses too, so next lookups are just as quick as an introspected GType. The cache is invalidated after loading new typelibs, in case some of the previously missed GTypes is now properly introspected. --- girepository.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/girepository.c b/girepository.c index fd668c5a5..b7948d617 100644 --- a/girepository.c +++ b/girepository.c @@ -81,6 +81,7 @@ struct _GIRepositoryPrivate GHashTable *info_by_gtype; /* GType -> GIBaseInfo */ GHashTable *info_by_error_domain; /* GQuark -> GIBaseInfo */ GHashTable *interfaces_for_gtype; /* GType -> GTypeInterfaceCache */ + GHashTable *unknown_gtypes; /* hashset of GType */ }; G_DEFINE_TYPE_WITH_CODE (GIRepository, g_irepository, G_TYPE_OBJECT, G_ADD_PRIVATE (GIRepository)); @@ -144,6 +145,7 @@ g_irepository_init (GIRepository *repository) = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) NULL, (GDestroyNotify) gtype_interface_cache_free); + repository->priv->unknown_gtypes = g_hash_table_new (NULL, NULL); } static void @@ -156,6 +158,7 @@ g_irepository_finalize (GObject *object) g_hash_table_destroy (repository->priv->info_by_gtype); g_hash_table_destroy (repository->priv->info_by_error_domain); g_hash_table_destroy (repository->priv->interfaces_for_gtype); + g_hash_table_destroy (repository->priv->unknown_gtypes); (* G_OBJECT_CLASS (g_irepository_parent_class)->finalize) (G_OBJECT (repository)); } @@ -439,6 +442,9 @@ register_internal (GIRepository *repository, g_hash_table_insert (repository->priv->typelibs, key, (void *)typelib); } + /* These types might be resolved now, clear the cache */ + g_hash_table_remove_all (repository->priv->unknown_gtypes); + return namespace; } @@ -814,6 +820,9 @@ g_irepository_find_by_gtype (GIRepository *repository, if (cached != NULL) return g_base_info_ref (cached); + if (g_hash_table_contains (repository->priv->unknown_gtypes, (gpointer)gtype)) + return NULL; + data.gtype_name = g_type_name (gtype); data.result_typelib = NULL; @@ -849,7 +858,11 @@ g_irepository_find_by_gtype (GIRepository *repository, g_base_info_ref (cached)); return cached; } - return NULL; + else + { + g_hash_table_add (repository->priv->unknown_gtypes, (gpointer) gtype); + return NULL; + } } /** From f257d2f891d98e23d63fd56dedf02b57c4ef081b Mon Sep 17 00:00:00 2001 From: Joshua Watt Date: Wed, 20 Nov 2019 09:03:47 -0600 Subject: [PATCH 613/692] Fix build reproducibility ba744068 ("Make meson.override_find_program working on more complex use cases") made the build no longer reproducible by encoding a build system path into the output. This shouldn't be necessary anyway, since it should be possible to add new paths to search for gir files by setting the XDG_DATA_DIR environment variable. Closes #318 Signed-off-by: Joshua Watt --- girparser.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/girparser.c b/girparser.c index fb47e75c2..53450baf5 100644 --- a/girparser.c +++ b/girparser.c @@ -309,10 +309,6 @@ locate_gir (GIrParser *parser, if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) return path; g_free (path); - path = g_build_filename (UNINSTALLED_GIR_DIR, girname, NULL); - if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) - return path; - g_free (path); return NULL; } From 75a1bb1e13c035a13726e4feb4532bfbd386079f Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Wed, 22 Apr 2020 21:15:45 -0400 Subject: [PATCH 614/692] Meson: Fix build when glib is built as subproject --- cmph/meson.build | 2 ++ meson.build | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cmph/meson.build b/cmph/meson.build index 5bc41a33f..2a0cef7e4 100644 --- a/cmph/meson.build +++ b/cmph/meson.build @@ -26,6 +26,7 @@ cmph_sources = [ cmph_deps = [ glib_dep, + gobject_dep, cc.find_library('m', required: false), ] @@ -67,6 +68,7 @@ cmph_test = executable('cmph-bdz-test', '../cmph-bdz-test.c', dependencies: [ cmph_dep, glib_dep, + gobject_dep, ], c_args: custom_c_args, ) diff --git a/meson.build b/meson.build index 204659fe9..6cd8fd303 100644 --- a/meson.build +++ b/meson.build @@ -17,12 +17,13 @@ girepo_gthash_lib = static_library('girepository-gthash', cmph_dep, glib_dep, gmodule_dep, + gobject_dep, ], ) girepo_gthash_dep = declare_dependency( link_with: girepo_gthash_lib, - dependencies: [glib_dep, gmodule_dep], + dependencies: [glib_dep, gmodule_dep, gobject_dep], include_directories: include_directories('.'), ) From 3d39d61e3d1705624a1e1dd4cb20ebea1f2a2331 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 24 Apr 2020 11:52:45 +0100 Subject: [PATCH 615/692] Revert "Meson: Fix build when glib is built as subproject" This reverts commit ec00edd941953626ac027810f747847f68a71000. The nightly run time does not have Meson 0.54. --- cmph/meson.build | 2 -- meson.build | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/cmph/meson.build b/cmph/meson.build index 2a0cef7e4..5bc41a33f 100644 --- a/cmph/meson.build +++ b/cmph/meson.build @@ -26,7 +26,6 @@ cmph_sources = [ cmph_deps = [ glib_dep, - gobject_dep, cc.find_library('m', required: false), ] @@ -68,7 +67,6 @@ cmph_test = executable('cmph-bdz-test', '../cmph-bdz-test.c', dependencies: [ cmph_dep, glib_dep, - gobject_dep, ], c_args: custom_c_args, ) diff --git a/meson.build b/meson.build index 6cd8fd303..204659fe9 100644 --- a/meson.build +++ b/meson.build @@ -17,13 +17,12 @@ girepo_gthash_lib = static_library('girepository-gthash', cmph_dep, glib_dep, gmodule_dep, - gobject_dep, ], ) girepo_gthash_dep = declare_dependency( link_with: girepo_gthash_lib, - dependencies: [glib_dep, gmodule_dep, gobject_dep], + dependencies: [glib_dep, gmodule_dep], include_directories: include_directories('.'), ) From 74ff43c47f4306c33a49ead862fe85cd6c975ac6 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Fri, 24 Apr 2020 15:05:03 -0400 Subject: [PATCH 616/692] Revert "Revert "Meson: Fix build when glib is built as subproject"" This reverts commit 42b7d634a9a7500dcc71651f71844148fc200be3. --- cmph/meson.build | 2 ++ meson.build | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cmph/meson.build b/cmph/meson.build index 5bc41a33f..2a0cef7e4 100644 --- a/cmph/meson.build +++ b/cmph/meson.build @@ -26,6 +26,7 @@ cmph_sources = [ cmph_deps = [ glib_dep, + gobject_dep, cc.find_library('m', required: false), ] @@ -67,6 +68,7 @@ cmph_test = executable('cmph-bdz-test', '../cmph-bdz-test.c', dependencies: [ cmph_dep, glib_dep, + gobject_dep, ], c_args: custom_c_args, ) diff --git a/meson.build b/meson.build index 204659fe9..6cd8fd303 100644 --- a/meson.build +++ b/meson.build @@ -17,12 +17,13 @@ girepo_gthash_lib = static_library('girepository-gthash', cmph_dep, glib_dep, gmodule_dep, + gobject_dep, ], ) girepo_gthash_dep = declare_dependency( link_with: girepo_gthash_lib, - dependencies: [glib_dep, gmodule_dep], + dependencies: [glib_dep, gmodule_dep, gobject_dep], include_directories: include_directories('.'), ) From 8fcdeefb3af88c2e8681380fde71665be0444011 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Sat, 11 Apr 2020 14:19:06 -0700 Subject: [PATCH 617/692] girepository: Add 1.66 version macro Required for adding new API to the 1.66 series. --- giversionmacros.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/giversionmacros.h b/giversionmacros.h index c32e5bb86..a941ee2d6 100644 --- a/giversionmacros.h +++ b/giversionmacros.h @@ -159,4 +159,10 @@ # define GI_AVAILABLE_IN_1_60 _GI_EXTERN #endif +#if defined(GLIB_VERSION_2_66) && GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_66 +# define GI_AVAILABLE_IN_1_66 GLIB_UNAVAILABLE(2, 66) +#else +# define GI_AVAILABLE_IN_1_66 _GI_EXTERN +#endif + #endif /* __GIVERSIONMACROS_H__ */ From 7daee7b90acd2c908812613594d5963e05dc7431 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Sat, 11 Apr 2020 14:22:18 -0700 Subject: [PATCH 618/692] girepository: Add GITypeInfo utility functions for storing values in pointers This functionality is used in both PyGObject and GJS, and if not done correctly can lead to architecture-specific bugs. It seems best to add API in gobject-introspection for the correct way to do it. See also: GNOME/gjs#309 --- gitypeinfo.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++ gitypeinfo.h | 12 ++++ 2 files changed, 182 insertions(+) diff --git a/gitypeinfo.c b/gitypeinfo.c index 1434b2f32..e90f9463c 100644 --- a/gitypeinfo.c +++ b/gitypeinfo.c @@ -347,3 +347,173 @@ g_type_info_get_array_type (GITypeInfo *info) return -1; } + +/** + * g_type_info_get_storage_type: + * @info: a #GITypeInfo + * + * Obtain the type tag corresponding to the underlying storage type in C for + * the type. + * See #GITypeTag for a list of type tags. + * + * Returns: the type tag + * + * Since: 1.66 + */ +GITypeTag +g_type_info_get_storage_type (GITypeInfo *info) +{ + GITypeTag type_tag = g_type_info_get_tag (info); + + if (type_tag == GI_TYPE_TAG_INTERFACE) + { + GIBaseInfo *interface = g_type_info_get_interface (info); + GIInfoType info_type = g_base_info_get_type (interface); + if (info_type == GI_INFO_TYPE_ENUM || info_type == GI_INFO_TYPE_FLAGS) + type_tag = g_enum_info_get_storage_type (interface); + g_base_info_unref (interface); + } + + return type_tag; +} + +/** + * g_type_info_argument_from_hash_pointer: + * @info: a #GITypeInfo + * @hash_pointer: A pointer, such as a #GHashTable data pointer + * @arg: A #GIArgument to fill in + * + * GLib data structures, such as #GList, #GSList, and #GHashTable, all store + * data pointers. + * In the case where the list or hash table is storing single types rather than + * structs, these data pointers may have values stuffed into them via macros + * such as %GPOINTER_TO_INT. + * + * Use this function to ensure that all values are correctly extracted from + * stuffed pointers, regardless of the machine's architecture or endianness. + * + * This function fills in the appropriate field of @arg with the value extracted + * from @hash_pointer, depending on the storage type of @info. + * + * Since: 1.66 + */ +void +g_type_info_argument_from_hash_pointer (GITypeInfo *info, + gpointer hash_pointer, + GIArgument *arg) +{ + GITypeTag type_tag = g_type_info_get_storage_type (info); + + switch (type_tag) + { + case GI_TYPE_TAG_BOOLEAN: + arg->v_boolean = !!GPOINTER_TO_INT (hash_pointer); + break; + case GI_TYPE_TAG_INT8: + arg->v_int8 = (gint8)GPOINTER_TO_INT (hash_pointer); + break; + case GI_TYPE_TAG_UINT8: + arg->v_uint8 = (guint8)GPOINTER_TO_UINT (hash_pointer); + break; + case GI_TYPE_TAG_INT16: + arg->v_int16 = (gint16)GPOINTER_TO_INT (hash_pointer); + break; + case GI_TYPE_TAG_UINT16: + arg->v_uint16 = (guint16)GPOINTER_TO_UINT (hash_pointer); + break; + case GI_TYPE_TAG_INT32: + arg->v_int32 = (gint32)GPOINTER_TO_INT (hash_pointer); + break; + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_UNICHAR: + arg->v_uint32 = (guint32)GPOINTER_TO_UINT (hash_pointer); + break; + case GI_TYPE_TAG_GTYPE: + arg->v_size = GPOINTER_TO_SIZE (hash_pointer); + break; + case GI_TYPE_TAG_UTF8: + case GI_TYPE_TAG_FILENAME: + case GI_TYPE_TAG_INTERFACE: + case GI_TYPE_TAG_ARRAY: + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: + case GI_TYPE_TAG_GHASH: + case GI_TYPE_TAG_ERROR: + arg->v_pointer = hash_pointer; + break; + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + case GI_TYPE_TAG_FLOAT: + case GI_TYPE_TAG_DOUBLE: + default: + g_critical ("Unsupported type for pointer-stuffing: %s", + g_type_tag_to_string (type_tag)); + arg->v_pointer = hash_pointer; + } +} + +/** + * g_type_info_hash_pointer_from_argument: + * @info: a #GITypeInfo + * @arg: A #GIArgument with the value to stuff into a pointer + * + * GLib data structures, such as #GList, #GSList, and #GHashTable, all store + * data pointers. + * In the case where the list or hash table is storing single types rather than + * structs, these data pointers may have values stuffed into them via macros + * such as %GPOINTER_TO_INT. + * + * Use this function to ensure that all values are correctly stuffed into + * pointers, regardless of the machine's architecture or endianness. + * + * This function returns a pointer stuffed with the appropriate field of @arg, + * depending on the storage type of @info. + * + * Returns: A stuffed pointer, that can be stored in a #GHashTable, for example + * + * Since: 1.66 + */ +gpointer +g_type_info_hash_pointer_from_argument (GITypeInfo *info, + GIArgument *arg) +{ + GITypeTag type_tag = g_type_info_get_storage_type (info); + + switch (type_tag) + { + case GI_TYPE_TAG_BOOLEAN: + return GINT_TO_POINTER (arg->v_boolean); + case GI_TYPE_TAG_INT8: + return GINT_TO_POINTER (arg->v_int8); + case GI_TYPE_TAG_UINT8: + return GUINT_TO_POINTER (arg->v_uint8); + case GI_TYPE_TAG_INT16: + return GINT_TO_POINTER (arg->v_int16); + case GI_TYPE_TAG_UINT16: + return GUINT_TO_POINTER (arg->v_uint16); + case GI_TYPE_TAG_INT32: + return GINT_TO_POINTER (arg->v_int32); + case GI_TYPE_TAG_UINT32: + case GI_TYPE_TAG_UNICHAR: + return GUINT_TO_POINTER (arg->v_uint32); + case GI_TYPE_TAG_GTYPE: + return GSIZE_TO_POINTER (arg->v_size); + case GI_TYPE_TAG_UTF8: + case GI_TYPE_TAG_FILENAME: + case GI_TYPE_TAG_INTERFACE: + case GI_TYPE_TAG_ARRAY: + case GI_TYPE_TAG_GLIST: + case GI_TYPE_TAG_GSLIST: + case GI_TYPE_TAG_GHASH: + case GI_TYPE_TAG_ERROR: + return arg->v_pointer; + case GI_TYPE_TAG_INT64: + case GI_TYPE_TAG_UINT64: + case GI_TYPE_TAG_FLOAT: + case GI_TYPE_TAG_DOUBLE: + default: + g_critical ("Unsupported type for pointer-stuffing: %s", + g_type_tag_to_string (type_tag)); + return arg->v_pointer; + } +} diff --git a/gitypeinfo.h b/gitypeinfo.h index 4d5679c93..fd7d5be6e 100644 --- a/gitypeinfo.h +++ b/gitypeinfo.h @@ -80,6 +80,18 @@ gboolean g_type_info_is_zero_terminated (GITypeInfo *info); GI_AVAILABLE_IN_ALL GIArrayType g_type_info_get_array_type (GITypeInfo *info); +GI_AVAILABLE_IN_1_66 +GITypeTag g_type_info_get_storage_type (GITypeInfo *info); + +GI_AVAILABLE_IN_1_66 +void g_type_info_argument_from_hash_pointer (GITypeInfo *info, + gpointer hash_pointer, + GIArgument *arg); + +GI_AVAILABLE_IN_1_66 +gpointer g_type_info_hash_pointer_from_argument (GITypeInfo *info, + GIArgument *arg); + G_END_DECLS From 47136da0749cc39c6a15cbb9238d7fc3b0f52a13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Thu, 14 May 2020 15:20:25 +0000 Subject: [PATCH 619/692] Add missing nullable annotation to g_irepository_get_shared_library --- girepository.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girepository.c b/girepository.c index b7948d617..7d0348598 100644 --- a/girepository.c +++ b/girepository.c @@ -1144,7 +1144,7 @@ g_irepository_get_version (GIRepository *repository, * Note: The namespace must have already been loaded using a function * such as g_irepository_require() before calling this function. * - * Returns: Comma-separated list of paths to shared libraries, + * Returns: (nullable): Comma-separated list of paths to shared libraries, * or %NULL if none are associated */ const gchar * From d41f718dda57daf36a284337c85a78cc710b6079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Thu, 14 May 2020 17:26:21 +0200 Subject: [PATCH 620/692] Add missing nullable annotation to g_object_info_get_parent --- giobjectinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/giobjectinfo.c b/giobjectinfo.c index efb9ad76d..3f3423ccb 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -89,7 +89,7 @@ g_object_info_get_field_offset (GIObjectInfo *info, * * Obtain the parent of the object type. * - * Returns: (transfer full): the #GIObjectInfo. Free the struct by calling + * Returns: (transfer full) (nullable): the #GIObjectInfo. Free the struct by calling * g_base_info_unref() when done. */ GIObjectInfo * From da7e635b719aa220b19d8d088b7f3b56eaaad5a8 Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Thu, 14 May 2020 19:25:11 +0000 Subject: [PATCH 621/692] [Win32] Fix gi-dump-types.c to build on Windows --- gi-dump-types.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/gi-dump-types.c b/gi-dump-types.c index 69d8b12d4..f7c39fda0 100644 --- a/gi-dump-types.c +++ b/gi-dump-types.c @@ -1,16 +1,24 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ #include "gdump.c" -#include +#ifdef G_OS_WIN32 + #include +#else + #include +#endif int main (int argc, char **argv) { int i; - GOutputStream *stdout; + GOutputStream *Stdout; GModule *self; - stdout = g_unix_output_stream_new (1, FALSE); +#if defined(G_OS_WIN32) + Stdout = g_win32_output_stream_new (1, FALSE); +#else + Stdout = g_output_stream (1, FALSE); +#endif self = g_module_open (NULL, 0); @@ -26,7 +34,7 @@ main (int argc, g_clear_error (&error); } else - dump_type (type, argv[i], stdout); + dump_type (type, argv[i], Stdout); } return 0; From f7e4b797a82df80b660fb0c71abcbd02e23ac256 Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Thu, 14 May 2020 19:57:43 +0000 Subject: [PATCH 622/692] Obs! Change back to `g_unix_output_stream_new()` for non-Win32. --- gi-dump-types.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gi-dump-types.c b/gi-dump-types.c index f7c39fda0..bac32f2b6 100644 --- a/gi-dump-types.c +++ b/gi-dump-types.c @@ -17,7 +17,7 @@ main (int argc, #if defined(G_OS_WIN32) Stdout = g_win32_output_stream_new (1, FALSE); #else - Stdout = g_output_stream (1, FALSE); + Stdout = g_unix_output_stream_new (1, FALSE); #endif self = g_module_open (NULL, 0); From 1b5c989202e083e371dead85ae6318194c3fccdb Mon Sep 17 00:00:00 2001 From: Gisle Vanem Date: Fri, 15 May 2020 10:59:39 +0000 Subject: [PATCH 623/692] Use `_get_oshandle()` and `g_win32_output_stream_new()` instead since `g_win32_output_stream_new_from_fd()` is private in Gio. It's normally not exported unless `GLIB_STATIC_COMPILATION` is effective. PS. Why would i not be called `GIO_STATIC_COMPILATION` for Gio .c-files? --- gi-dump-types.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gi-dump-types.c b/gi-dump-types.c index bac32f2b6..8dae9c027 100644 --- a/gi-dump-types.c +++ b/gi-dump-types.c @@ -1,6 +1,7 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ #include "gdump.c" #ifdef G_OS_WIN32 + #include /* For _get_osfhandle() */ #include #else #include @@ -15,7 +16,10 @@ main (int argc, GModule *self; #if defined(G_OS_WIN32) - Stdout = g_win32_output_stream_new (1, FALSE); + HANDLE *hnd = (HANDLE) _get_osfhandle (1); + + g_return_val_if_fail (hnd && hnd != INVALID_HANDLE_VALUE, 1); + Stdout = g_win32_output_stream_new (hnd, FALSE); #else Stdout = g_unix_output_stream_new (1, FALSE); #endif From 06c8219ceea2b89851e484d63d6cecd10ec97a14 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Tue, 19 May 2020 19:39:34 +0200 Subject: [PATCH 624/692] meson: also build gi-dump-types on Windows --- gi-dump-types.c | 1 + meson.build | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gi-dump-types.c b/gi-dump-types.c index 8dae9c027..aeef774ce 100644 --- a/gi-dump-types.c +++ b/gi-dump-types.c @@ -1,6 +1,7 @@ /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ #include "gdump.c" #ifdef G_OS_WIN32 + #include #include /* For _get_osfhandle() */ #include #else diff --git a/meson.build b/meson.build index 6cd8fd303..c8ef6aa95 100644 --- a/meson.build +++ b/meson.build @@ -204,7 +204,7 @@ gthash_test = executable('gthash-test', 'gthash-test.c', test('gthash-test', gthash_test) -if giounix_dep.found() +if giounix_dep.found() or giowin_dep.found() executable('gi-dump-types', 'gi-dump-types.c', - dependencies: [girepo_dep, giounix_dep]) + dependencies: [girepo_dep, giounix_dep, giowin_dep]) endif From 7bebab4ac74d55ce14dedd78d41619b1f8984609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 23 May 2020 12:38:29 +0000 Subject: [PATCH 625/692] Add missing nullable annotations to GObjectInfo --- giobjectinfo.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/giobjectinfo.c b/giobjectinfo.c index efb9ad76d..747d4b6fe 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -419,7 +419,7 @@ g_object_info_get_method (GIObjectInfo *info, * Obtain a method of the object type given a @name. %NULL will be * returned if there's no method available with that name. * - * Returns: (transfer full): the #GIFunctionInfo. Free the struct by calling + * Returns: (transfer full) (nullable): the #GIFunctionInfo. Free the struct by calling * g_base_info_unref() when done. */ GIFunctionInfo * @@ -459,7 +459,7 @@ g_object_info_find_method (GIObjectInfo *info, * Note that this function does *not* search parent classes; you will have * to chain up if that's desired. * - * Returns: (transfer full): the #GIFunctionInfo. Free the struct by calling + * Returns: (transfer full) (nullable): the #GIFunctionInfo. Free the struct by calling * g_base_info_unref() when done. */ GIFunctionInfo * @@ -569,7 +569,7 @@ g_object_info_get_signal (GIObjectInfo *info, * * TODO * - * Returns: (transfer full): Info for the signal with name @name in @info, or %NULL on failure. + * Returns: (transfer full) (nullable): Info for the signal with name @name in @info, or %NULL on failure. */ GISignalInfo * g_object_info_find_signal (GIObjectInfo *info, @@ -668,7 +668,7 @@ g_object_info_get_vfunc (GIObjectInfo *info, * See the documentation for g_vfunc_info_get_invoker() for more * information on invoking virtuals. * - * Returns: (transfer full): the #GIVFuncInfo, or %NULL. Free it with + * Returns: (transfer full) (nullable): the #GIVFuncInfo, or %NULL. Free it with * g_base_info_unref() when done. */ GIVFuncInfo * @@ -713,7 +713,7 @@ g_object_info_find_vfunc (GIObjectInfo *info, * Note that this function does *not* search parent classes; you will have * to chain up if that's desired. * - * Returns: (transfer full): the #GIVFuncInfo. Free the struct by calling + * Returns: (transfer full) (nullable): the #GIVFuncInfo. Free the struct by calling * g_base_info_unref() when done. */ GIVFuncInfo * @@ -825,7 +825,7 @@ g_object_info_get_constant (GIObjectInfo *info, * Every #GObject has two structures; an instance structure and a class * structure. This function returns the metadata for the class structure. * - * Returns: (transfer full): the #GIStructInfo or %NULL. Free with + * Returns: (transfer full) (nullable): the #GIStructInfo or %NULL. Free with * g_base_info_unref() when done. */ GIStructInfo * @@ -889,7 +889,7 @@ _get_func(GIObjectInfo *info, * the symbol is %GIObjectInfoRefFunction, to fetch the function pointer * see g_object_info_get_ref_function(). * - * Returns: the symbol or %NULL + * Returns: (nullable): the symbol or %NULL */ const char * g_object_info_get_ref_function (GIObjectInfo *info) @@ -917,7 +917,7 @@ g_object_info_get_ref_function (GIObjectInfo *info) * This takes derivation into account and will reversely traverse * the base classes of this type, starting at the top type. * - * Returns: the function pointer or %NULL + * Returns: (nullable): the function pointer or %NULL */ GIObjectInfoRefFunction g_object_info_get_ref_function_pointer (GIObjectInfo *info) @@ -937,7 +937,7 @@ g_object_info_get_ref_function_pointer (GIObjectInfo *info) * the symbol is %GIObjectInfoUnrefFunction, to fetch the function pointer * see g_object_info_get_unref_function(). * - * Returns: the symbol or %NULL + * Returns: (nullable): the symbol or %NULL */ const char * g_object_info_get_unref_function (GIObjectInfo *info) @@ -965,7 +965,7 @@ g_object_info_get_unref_function (GIObjectInfo *info) * This takes derivation into account and will reversely traverse * the base classes of this type, starting at the top type. * - * Returns: the function pointer or %NULL + * Returns: (nullable): the function pointer or %NULL */ GIObjectInfoUnrefFunction g_object_info_get_unref_function_pointer (GIObjectInfo *info) @@ -986,7 +986,7 @@ g_object_info_get_unref_function_pointer (GIObjectInfo *info) * is %GIObjectInfoSetValueFunction, to fetch the function pointer * see g_object_info_get_set_value_function(). * - * Returns: the symbol or %NULL + * Returns: (nullable): the symbol or %NULL */ const char * g_object_info_get_set_value_function (GIObjectInfo *info) @@ -1014,7 +1014,7 @@ g_object_info_get_set_value_function (GIObjectInfo *info) * This takes derivation into account and will reversely traverse * the base classes of this type, starting at the top type. * - * Returns: the function pointer or %NULL + * Returns: (nullable): the function pointer or %NULL */ GIObjectInfoSetValueFunction g_object_info_get_set_value_function_pointer (GIObjectInfo *info) @@ -1035,7 +1035,7 @@ g_object_info_get_set_value_function_pointer (GIObjectInfo *info) * is %GIObjectInfoGetValueFunction, to fetch the function pointer * see g_object_info_get_get_value_function(). * - * Returns: the symbol or %NULL + * Returns: (nullable): the symbol or %NULL */ const char * g_object_info_get_get_value_function (GIObjectInfo *info) @@ -1063,7 +1063,7 @@ g_object_info_get_get_value_function (GIObjectInfo *info) * This takes derivation into account and will reversely traverse * the base classes of this type, starting at the top type. * - * Returns: the function pointer or %NULL + * Returns: (nullable): the function pointer or %NULL */ GIObjectInfoGetValueFunction g_object_info_get_get_value_function_pointer (GIObjectInfo *info) From 445c942f7d56e11cde9331d61af87427fad94f77 Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Sat, 6 Jun 2020 02:13:38 +0200 Subject: [PATCH 626/692] Add the notion of standalone doc sections. Up to now, section annotations had to match a class or interface name in order to be serialized in the gir. With this commit, they now get serialized as docsection nodes, for potential use by documentation tools. --- girparser.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index 53450baf5..ad676e33f 100644 --- a/girparser.c +++ b/girparser.c @@ -2830,7 +2830,8 @@ start_element_handler (GMarkupParseContext *context, ctx, error)) goto out; if (strcmp ("doc", element_name) == 0 || strcmp ("doc-deprecated", element_name) == 0 || - strcmp ("doc-stability", element_name) == 0 || strcmp ("doc-version", element_name) == 0) + strcmp ("doc-stability", element_name) == 0 || strcmp ("doc-version", element_name) == 0 || + strcmp ("docsection", element_name) == 0) { state_switch (ctx, STATE_PASSTHROUGH); goto out; From 7cfb47308b869592bc20f5eca457899775e5eb10 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 12 Mar 2021 18:54:47 +0000 Subject: [PATCH 627/692] Use g_memdup2() with newer versions of GLib The g_memdup() function has been deprecated, so we should use the new g_memdup2() function if available. --- giconstantinfo.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/giconstantinfo.c b/giconstantinfo.c index c18a9d3fc..a9d4cbc02 100644 --- a/giconstantinfo.c +++ b/giconstantinfo.c @@ -128,7 +128,15 @@ g_constant_info_get_value (GIConstantInfo *info, if (blob->type.flags.reserved == 0 && blob->type.flags.reserved2 == 0) { if (blob->type.flags.pointer) - value->v_pointer = g_memdup (&rinfo->typelib->data[blob->offset], blob->size); + { +#if GLIB_CHECK_VERSION (2, 67, 5) + gsize blob_size = blob->size; + + value->v_pointer = g_memdup2 (&rinfo->typelib->data[blob->offset], blob_size); +#else + value->v_pointer = g_memdup (&rinfo->typelib->data[blob->offset], blob->size); +#endif + } else { switch (blob->type.flags.tag) From c2ded0a66723207080c076d80846bef8d9c341b5 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Tue, 23 Feb 2021 13:11:22 -0500 Subject: [PATCH 628/692] Make test suite work with cross-related options Because of skepticism I received in #224, I made this PR which keeps the testsuite and CI improvements but doesn't add any new build options. I hope this would be less controversial: - no new knobs - tests for those using existing build options - CI tests `build_introspection_data = false` --- meson.build | 7 ------- 1 file changed, 7 deletions(-) diff --git a/meson.build b/meson.build index c8ef6aa95..786749a9e 100644 --- a/meson.build +++ b/meson.build @@ -185,13 +185,6 @@ girepo_lib = shared_library('girepository-1.0', install: true, ) -# Copy to builddir for use with giscanner/dumper.py when running uninstalled -configure_file(input : 'gdump.c', - output : 'gdump.c', - copy: true, - install_dir: join_paths(get_option('datadir'), 'gobject-introspection-1.0'), -) - girepo_dep = declare_dependency( link_with: girepo_lib, dependencies: [glib_dep, gobject_dep, gio_dep, gmodule_dep], From 62b1ebd822c3ffaea03d0f1829310344681fe209 Mon Sep 17 00:00:00 2001 From: David King Date: Thu, 20 May 2021 11:24:14 +0100 Subject: [PATCH 629/692] girepository: Fix leak in g_callable_info_invoke Found by Coverity. https://bugzilla.redhat.com/show_bug.cgi?id=1938731 --- gicallableinfo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gicallableinfo.c b/gicallableinfo.c index 3048e1624..16e391f9f 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -638,6 +638,7 @@ g_callable_info_invoke (GIFunctionInfo *info, case GI_DIRECTION_IN: tinfo = g_arg_info_get_type (ainfo); atypes[i+offset] = g_type_info_get_ffi_type (tinfo); + g_base_info_unref ((GIBaseInfo *)ainfo); g_base_info_unref ((GIBaseInfo *)tinfo); if (in_pos >= n_in_args) @@ -655,6 +656,7 @@ g_callable_info_invoke (GIFunctionInfo *info, break; case GI_DIRECTION_OUT: atypes[i+offset] = &ffi_type_pointer; + g_base_info_unref ((GIBaseInfo *)ainfo); if (out_pos >= n_out_args) { @@ -670,6 +672,7 @@ g_callable_info_invoke (GIFunctionInfo *info, break; case GI_DIRECTION_INOUT: atypes[i+offset] = &ffi_type_pointer; + g_base_info_unref ((GIBaseInfo *)ainfo); if (in_pos >= n_in_args) { @@ -694,9 +697,9 @@ g_callable_info_invoke (GIFunctionInfo *info, out_pos++; break; default: + g_base_info_unref ((GIBaseInfo *)ainfo); g_assert_not_reached (); } - g_base_info_unref ((GIBaseInfo *)ainfo); } if (throws) From 4e3ab408f1ab9755c24120406ed76d79f94e02b9 Mon Sep 17 00:00:00 2001 From: David King Date: Thu, 20 May 2021 11:37:56 +0100 Subject: [PATCH 630/692] girepository: Fix leak in _g_ir_parser_parse_file Found by Coverity. https://bugzilla.redhat.com/show_bug.cgi?id=1938731 --- girparser.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/girparser.c b/girparser.c index ad676e33f..f62b1de6f 100644 --- a/girparser.c +++ b/girparser.c @@ -3672,7 +3672,11 @@ _g_ir_parser_parse_file (GIrParser *parser, *dash = '\0'; if (!g_file_get_contents (filename, &buffer, &length, error)) - return NULL; + { + g_free (namespace); + + return NULL; + } module = _g_ir_parser_parse_string (parser, namespace, filename, buffer, length, error); From 16b064bea9e506535faf9c1090894cfd7bc16dea Mon Sep 17 00:00:00 2001 From: David King Date: Thu, 20 May 2021 12:35:37 +0100 Subject: [PATCH 631/692] girepository: Fix leak in write_field_info Unref type before reusing it. Found by Coverity. https://bugzilla.redhat.com/show_bug.cgi?id=1938731 --- girwriter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/girwriter.c b/girwriter.c index 7b255423f..cc14280b9 100644 --- a/girwriter.c +++ b/girwriter.c @@ -423,6 +423,7 @@ write_field_info (const gchar *namespace, if (branch) { xml_printf (file, " branch=\""); + g_base_info_unref ((GIBaseInfo *)type); type = g_constant_info_get_type (branch); g_constant_info_get_value (branch, &value); write_constant_value (namespace, type, &value, file); From 3ebf2f5140d02812cd0be5822e540a83dc5e1d3a Mon Sep 17 00:00:00 2001 From: David King Date: Thu, 20 May 2021 12:40:23 +0100 Subject: [PATCH 632/692] girepository: Fix leak in write_vfunc_info Found by Coverity. https://bugzilla.redhat.com/show_bug.cgi?id=1938731 --- girwriter.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/girwriter.c b/girwriter.c index cc14280b9..d092df10b 100644 --- a/girwriter.c +++ b/girwriter.c @@ -923,7 +923,10 @@ write_vfunc_info (const gchar *namespace, xml_printf (file, " offset=\"%d\"", offset); if (invoker) - xml_printf (file, " invoker=\"%s\"", g_base_info_get_name ((GIBaseInfo*)invoker)); + { + xml_printf (file, " invoker=\"%s\"", g_base_info_get_name ((GIBaseInfo*)invoker)); + g_base_info_unref ((GIBaseInfo *)invoker); + } write_callable_info (namespace, (GICallableInfo*)info, file); From 18745a0639f3c672e18e235c5fd26ae7d999328d Mon Sep 17 00:00:00 2001 From: David King Date: Thu, 20 May 2021 12:48:34 +0100 Subject: [PATCH 633/692] girepository: Fix leak in prefix_with_context Found by Coverity. https://bugzilla.redhat.com/show_bug.cgi?id=1938731 --- gitypelib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gitypelib.c b/gitypelib.c index de11748b5..904dff45a 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -2139,7 +2139,7 @@ prefix_with_context (GError **error, const char *section, ValidateContext *ctx) { - GString *str = g_string_new (NULL); + GString *str; GSList *link; char *buf; @@ -2150,6 +2150,8 @@ prefix_with_context (GError **error, return; } + str = g_string_new (NULL); + for (; link; link = link->next) { g_string_append (str, link->data); From 0cdd325c1a36ca2dab7fe15145a3b315db7f4e71 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 2 Jun 2021 12:39:00 +0100 Subject: [PATCH 634/692] Initialise argument Avoid a "maybe uninitialized" compiler warning. --- ginvoke.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ginvoke.c b/ginvoke.c index f7e644938..5d423b1e2 100644 --- a/ginvoke.c +++ b/ginvoke.c @@ -251,7 +251,7 @@ gi_cclosure_marshal_generic (GClosure *closure, gpointer invocation_hint, gpointer marshal_data) { - GIArgument return_ffi_value; + GIArgument return_ffi_value = { 0, }; ffi_type *rtype; void *rvalue; int n_args; From ce4448f9e77531a94a484c73acc29dce57a9d358 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 26 Jul 2021 16:39:24 +0100 Subject: [PATCH 635/692] Add version macros for 1.70 We are going to introduce new API. --- giversionmacros.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/giversionmacros.h b/giversionmacros.h index a941ee2d6..273af7253 100644 --- a/giversionmacros.h +++ b/giversionmacros.h @@ -165,4 +165,10 @@ # define GI_AVAILABLE_IN_1_66 _GI_EXTERN #endif +#if defined(GLIB_VERSION_2_70) && GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_70 +# define GI_AVAILABLE_IN_1_70 GLIB_UNAVAILABLE(2, 70) +#else +# define GI_AVAILABLE_IN_1_70 _GI_EXTERN +#endif + #endif /* __GIVERSIONMACROS_H__ */ From d127fc11363b85cc3ea40f00621b37ccefa0a87a Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Tue, 9 Feb 2021 11:38:27 +0000 Subject: [PATCH 636/692] Add "final" class attribute A "final" class is a leaf node in a derivable type hierarchy, and cannot be derived any further. This matches the changes in libgobject that introduced G_TYPE_FLAG_FINAL to the type flags. --- gdump.c | 11 +++++++++++ giobjectinfo.c | 25 +++++++++++++++++++++++++ giobjectinfo.h | 3 +++ girnode.c | 1 + girnode.h | 1 + girparser.c | 3 +++ girwriter.c | 5 +++++ gitypelib-internal.h | 8 +++++--- 8 files changed, 54 insertions(+), 3 deletions(-) diff --git a/gdump.c b/gdump.c index 0e8c60352..e79f17192 100644 --- a/gdump.c +++ b/gdump.c @@ -241,6 +241,12 @@ dump_object_type (GType type, const char *symbol, GOutputStream *out) if (G_TYPE_IS_ABSTRACT (type)) escaped_printf (out, " abstract=\"1\""); + +#if GLIB_CHECK_VERSION (2, 70, 0) + if (G_TYPE_IS_FINAL (type)) + escaped_printf (out, " final=\"1\""); +#endif + goutput_write (out, ">\n"); interfaces = g_type_interfaces (type, &n_interfaces); @@ -354,6 +360,11 @@ dump_fundamental_type (GType type, const char *symbol, GOutputStream *out) if (G_TYPE_IS_ABSTRACT (type)) escaped_printf (out, " abstract=\"1\""); +#if GLIB_CHECK_VERSION (2, 70, 0) + if (G_TYPE_IS_FINAL (type)) + escaped_printf (out, " final=\"1\""); +#endif + if (G_TYPE_IS_INSTANTIATABLE (type)) escaped_printf (out, " instantiatable=\"1\""); diff --git a/giobjectinfo.c b/giobjectinfo.c index 13cfdaa89..2042793a0 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -133,6 +133,31 @@ g_object_info_get_abstract (GIObjectInfo *info) return blob->abstract != 0; } +/** + * g_object_info_get_final: + * @info: a #GIObjectInfo + * + * Checks whether the object type is a final type, i.e. if it cannot + * be derived + * + * Returns: %TRUE if the object type is final + * + * Since: 1.70 + */ +gboolean +g_object_info_get_final (GIObjectInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *) info; + ObjectBlob *blob; + + g_return_val_if_fail (info != NULL, FALSE); + g_return_val_if_fail (GI_IS_OBJECT_INFO (info), FALSE); + + blob = (ObjectBlob *) &rinfo->typelib->data[rinfo->offset]; + + return blob->final_ != 0; +} + /** * g_object_info_get_fundamental: * @info: a #GIObjectInfo diff --git a/giobjectinfo.h b/giobjectinfo.h index dac95abff..aa6f9c9d0 100644 --- a/giobjectinfo.h +++ b/giobjectinfo.h @@ -87,6 +87,9 @@ const gchar * g_object_info_get_type_init (GIObjectInfo *info); GI_AVAILABLE_IN_ALL gboolean g_object_info_get_abstract (GIObjectInfo *info); +GI_AVAILABLE_IN_1_70 +gboolean g_object_info_get_final (GIObjectInfo *info); + GI_AVAILABLE_IN_ALL gboolean g_object_info_get_fundamental (GIObjectInfo *info); diff --git a/girnode.c b/girnode.c index fadfe56f7..796f2001f 100644 --- a/girnode.c +++ b/girnode.c @@ -2096,6 +2096,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob->blob_type = BLOB_TYPE_OBJECT; blob->abstract = object->abstract; blob->fundamental = object->fundamental; + blob->final_ = object->final_; blob->deprecated = object->deprecated; blob->reserved = 0; blob->name = _g_ir_write_string (node->name, strings, data, offset2); diff --git a/girnode.h b/girnode.h index e4ce85a4c..9b42accda 100644 --- a/girnode.h +++ b/girnode.h @@ -240,6 +240,7 @@ struct _GIrNodeInterface gboolean abstract; gboolean deprecated; gboolean fundamental; + gboolean final_; gchar *gtype_name; gchar *gtype_init; diff --git a/girparser.c b/girparser.c index f62b1de6f..b6983d1a6 100644 --- a/girparser.c +++ b/girparser.c @@ -1806,6 +1806,7 @@ start_class (GMarkupParseContext *context, const gchar *deprecated; const gchar *abstract; const gchar *fundamental; + const gchar *final; const gchar *ref_func; const gchar *unref_func; const gchar *set_value_func; @@ -1826,6 +1827,7 @@ start_class (GMarkupParseContext *context, typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); abstract = find_attribute ("abstract", attribute_names, attribute_values); + final = find_attribute ("final", attribute_names, attribute_values); fundamental = find_attribute ("glib:fundamental", attribute_names, attribute_values); ref_func = find_attribute ("glib:ref-func", attribute_names, attribute_values); unref_func = find_attribute ("glib:unref-func", attribute_names, attribute_values); @@ -1861,6 +1863,7 @@ start_class (GMarkupParseContext *context, iface->deprecated = FALSE; iface->abstract = abstract && strcmp (abstract, "1") == 0; + iface->final_ = final && strcmp (final, "1") == 0; if (fundamental) iface->fundamental = TRUE; diff --git a/girwriter.c b/girwriter.c index d092df10b..104ee633b 100644 --- a/girwriter.c +++ b/girwriter.c @@ -988,6 +988,7 @@ write_object_info (const gchar *namespace, gboolean deprecated; gboolean is_abstract; gboolean is_fundamental; + gboolean is_final; GIObjectInfo *pnode; GIStructInfo *class_struct; gint i; @@ -996,6 +997,7 @@ write_object_info (const gchar *namespace, deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); is_abstract = g_object_info_get_abstract (info); is_fundamental = g_object_info_get_fundamental (info); + is_final = g_object_info_get_final (info); type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); @@ -1019,6 +1021,9 @@ write_object_info (const gchar *namespace, if (is_abstract) xml_printf (file, " abstract=\"1\""); + if (is_final) + xml_printf (file, " final=\"1\""); + xml_printf (file, " glib:type-name=\"%s\" glib:get-type=\"%s\"", type_name, type_init); if (is_fundamental) diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 28b177d67..f25b863bf 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -1034,10 +1034,11 @@ typedef struct { /** * ObjectBlob: * @blob_type: #BLOB_TYPE_OBJECT - * @deprecated: TODO - * @abstract: TODO + * @deprecated: whether the type is deprecated + * @abstract: whether the type can be instantiated * @fundamental: this object is not a GObject derived type, instead it's * an additional fundamental type. + * @final: whether the type can be derived * @reserved: Reserved for future use. * @name: TODO * @gtype_name: String name of the associated #GType @@ -1076,7 +1077,8 @@ typedef struct { guint16 deprecated : 1; guint16 abstract : 1; guint16 fundamental : 1; - guint16 reserved :13; + guint16 final_ : 1; + guint16 reserved :12; guint32 name; guint32 gtype_name; From efa58b3f8d758d2011d9108e6109fffe93422c72 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 16 Jun 2021 19:15:05 +0100 Subject: [PATCH 637/692] Property accessors work for interfaces and objects We need to check the container type before trying to obtain a GIPropertyInfo for GIFunctionInfos that have a SETTER or a GETTER flag set. --- gifunctioninfo.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/gifunctioninfo.c b/gifunctioninfo.c index 366850d5a..b042b4e10 100644 --- a/gifunctioninfo.c +++ b/gifunctioninfo.c @@ -165,18 +165,30 @@ g_function_info_get_flags (GIFunctionInfo *info) GIPropertyInfo * g_function_info_get_property (GIFunctionInfo *info) { - GIRealInfo *rinfo; + GIRealInfo *rinfo, *container_rinfo; FunctionBlob *blob; - GIInterfaceInfo *container; g_return_val_if_fail (info != NULL, NULL); g_return_val_if_fail (GI_IS_FUNCTION_INFO (info), NULL); rinfo = (GIRealInfo *)info; blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; - container = (GIInterfaceInfo *)rinfo->container; + container_rinfo = (GIRealInfo *)rinfo->container; - return g_interface_info_get_property (container, blob->index); + if (container_rinfo->type == GI_INFO_TYPE_INTERFACE) + { + GIInterfaceInfo *container = (GIInterfaceInfo *)rinfo->container; + + return g_interface_info_get_property (container, blob->index); + } + else if (container_rinfo->type == GI_INFO_TYPE_OBJECT) + { + GIObjectInfo *container = (GIObjectInfo *)rinfo->container; + + return g_object_info_get_property (container, blob->index); + } + else + return NULL; } /** From 39d518267b056f734306757d490f21fa36532a98 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 16 Jun 2021 19:17:27 +0100 Subject: [PATCH 638/692] Add new annotations for property accessors We introduce two new annotations: - (set-property PROPERTY_NAME) - (get-property PROPERTY_NAME) These annotations are valid inside function blocks for methods on objects and interfaces, and define whether a function is a property accessor, e.g.: /** * gtk_widget_set_name: (set-property name) * @self: ... * @name: ... * * ... */ /** * gtk_widget_get_name: (get-property name) * @self: ... * * ... * * Returns: ... */ The annotations are transformed into the GIR data as attributes: - glib:set-property="PROPERTY_NAME" - glib:get-property="PROPERTY_NAME" The underlying typelib data has had flags for setter and getter functions for a while, but they have never been plugged into the GIR data or the introspection scanner. Now they are; you can retrieve the GIPropertyInfo from a GIFunctionInfo that has the GI_FUNCTION_IS_SETTER or GI_FUNCTION_IS_GETTER flags set. Fixes: #13 --- girnode.c | 20 ++++++++++++++++++-- girnode.h | 1 + girparser.c | 23 +++++++++++++++++++++++ girwriter.c | 20 ++++++++++++++++---- 4 files changed, 58 insertions(+), 6 deletions(-) diff --git a/girnode.c b/girnode.c index 796f2001f..5e74b0b01 100644 --- a/girnode.c +++ b/girnode.c @@ -218,6 +218,7 @@ _g_ir_node_free (GIrNode *node) g_free (node->name); g_free (function->symbol); + g_free (function->property); _g_ir_node_free ((GIrNode *)function->result); for (l = function->parameters; l; l = l->next) _g_ir_node_free ((GIrNode *)l->data); @@ -1648,8 +1649,8 @@ _g_ir_node_build_typelib (GIrNode *node, blob->blob_type = BLOB_TYPE_FUNCTION; blob->deprecated = function->deprecated; blob->is_static = !function->is_method; - blob->setter = function->is_setter; - blob->getter = function->is_getter; + blob->setter = FALSE; + blob->getter = FALSE; blob->constructor = function->is_constructor; blob->wraps_vfunc = function->wraps_vfunc; blob->throws = function->throws; /* Deprecated. Also stored in SignatureBlob. */ @@ -1658,6 +1659,21 @@ _g_ir_node_build_typelib (GIrNode *node, blob->symbol = _g_ir_write_string (function->symbol, strings, data, offset2); blob->signature = signature; + if (function->is_setter || function->is_getter) + { + int index = get_index_of_member_type ((GIrNodeInterface*)parent, + G_IR_NODE_PROPERTY, + function->property); + if (index == -1) + { + g_error ("Unknown property %s for accessor %s", function->property, node->name); + } + + blob->setter = function->is_setter; + blob->getter = function->is_getter; + blob->index = (guint) index; + } + /* function->result is special since it doesn't appear in the serialized format but * we do want the attributes for it to appear */ diff --git a/girnode.h b/girnode.h index 9b42accda..f2645b68d 100644 --- a/girnode.h +++ b/girnode.h @@ -103,6 +103,7 @@ struct _GIrNodeFunction gboolean instance_transfer_full; gchar *symbol; + char *property; GIrNodeParam *result; GList *parameters; diff --git a/girparser.c b/girparser.c index b6983d1a6..2d30f201d 100644 --- a/girparser.c +++ b/girparser.c @@ -807,6 +807,8 @@ start_function (GMarkupParseContext *context, const gchar *symbol; const gchar *deprecated; const gchar *throws; + const gchar *set_property; + const gchar *get_property; GIrNodeFunction *function; gboolean found = FALSE; ParseState in_embedded_state = STATE_NONE; @@ -854,6 +856,8 @@ start_function (GMarkupParseContext *context, symbol = find_attribute ("c:identifier", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); throws = find_attribute ("throws", attribute_names, attribute_values); + set_property = find_attribute ("glib:set-property", attribute_names, attribute_values); + get_property = find_attribute ("glib:get-property", attribute_names, attribute_values); if (name == NULL) { @@ -889,6 +893,25 @@ start_function (GMarkupParseContext *context, function->is_constructor = TRUE; else function->is_constructor = FALSE; + + if (set_property != NULL) + { + function->is_setter = TRUE; + function->is_getter = FALSE; + function->property = g_strdup (set_property); + } + else if (get_property != NULL) + { + function->is_setter = FALSE; + function->is_getter = TRUE; + function->property = g_strdup (get_property); + } + else + { + function->is_setter = FALSE; + function->is_getter = FALSE; + function->property = NULL; + } } else { diff --git a/girwriter.c b/girwriter.c index 104ee633b..2393e7d78 100644 --- a/girwriter.c +++ b/girwriter.c @@ -586,10 +586,22 @@ write_function_info (const gchar *namespace, xml_printf (file, " name=\"%s\" c:identifier=\"%s\"", name, symbol); - if (flags & GI_FUNCTION_IS_SETTER) - xml_printf (file, " type=\"setter\""); - else if (flags & GI_FUNCTION_IS_GETTER) - xml_printf (file, " type=\"getter\""); + if ((flags & GI_FUNCTION_IS_SETTER) || (flags & GI_FUNCTION_IS_GETTER)) + { + GIPropertyInfo *property = g_function_info_get_property (info); + + if (property != NULL) + { + const char *property_name = g_base_info_get_name ((GIBaseInfo *)property); + + if (flags & GI_FUNCTION_IS_SETTER) + xml_printf (file, " glib:set-property=\"%s\"", property_name); + else if (flags & GI_FUNCTION_IS_GETTER) + xml_printf (file, " glib:get-property=\"%s\"", property_name); + + g_base_info_unref (property); + } + } if (deprecated) xml_printf (file, " deprecated=\"1\""); From 400dfc2908b1b03cd31db920e7a087bb52a87132 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Thu, 17 Jun 2021 13:07:35 +0100 Subject: [PATCH 639/692] Add introspection data for property accessors A GObject property can be accessed generically through the GObject API, e.g. g_object_set_property() and g_object_get_property(). Properties typically also have public accessor functions, which are (according to our own best practices) called through the generic API. The introspection data is currently missing the relation between a property and its public accessor functions. With this information, a language binding could, for instance, avoid exposing the C API entirely, thus minimizing the chances of collisions between property names and accessor functions; alternatively, a binding could call the C API directly instead of going through the generic GObject API, thus avoiding the boxing and unboxing from a native type to a GIArgument and finally into a GValue, and vice versa. In the GIR, we add two new attributes to the `property` element: - setter="SYMBOL" - getter="SYMBOL" where "symbol" is the C function identifier of the setter and getter functions, respectively. The `setter` attribute is only applied to writable, non-construct-only properties; the `getter` attribute is only applied to readable properties. We maintain the ABI compatibility of the typelib data by using 20 bits of the 25 reserved bits inside the PropertyBlob structure. The data is exposed through two new GIPropertyInfo methods: - g_property_info_get_setter() - g_property_info_get_getter() which return the GIFunctionInfo for the setter and getter functions, respectively. --- gipropertyinfo.c | 79 ++++++++++++++++++++++++++++++++++++++++++++ gipropertyinfo.h | 6 ++++ girnode.c | 32 ++++++++++++++++++ girnode.h | 3 ++ girparser.c | 7 ++++ girwriter.c | 22 ++++++++++++ gitypelib-internal.h | 8 ++++- 7 files changed, 156 insertions(+), 1 deletion(-) diff --git a/gipropertyinfo.c b/gipropertyinfo.c index e58d46006..9b854b90a 100644 --- a/gipropertyinfo.c +++ b/gipropertyinfo.c @@ -132,3 +132,82 @@ g_property_info_get_ownership_transfer (GIPropertyInfo *info) else return GI_TRANSFER_NOTHING; } + +/** + * g_property_info_get_setter: + * @info: a #GIPropertyInfo + * + * Obtains the setter function associated with this #GIPropertyInfo. + * + * The setter is only available for %G_PARAM_WRITABLE properties that + * are also not %G_PARAM_CONSTRUCT_ONLY. + * + * Returns: (transfer full): the function info or %NULL if not set. + * Free it with g_base_info_unref() when done. + */ +GIFunctionInfo * +g_property_info_get_setter (GIPropertyInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + PropertyBlob *blob; + GIBaseInfo *container; + GIInfoType parent_type; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_PROPERTY_INFO (info), NULL); + + blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset]; + if (!blob->writable || blob->construct_only) + return NULL; + + if (blob->setter == 0x3ff) + return NULL; + + container = rinfo->container; + parent_type = g_base_info_get_type (container); + if (parent_type == GI_INFO_TYPE_OBJECT) + return g_object_info_get_method ((GIObjectInfo *) container, blob->setter); + else if (parent_type == GI_INFO_TYPE_INTERFACE) + return g_interface_info_get_method ((GIInterfaceInfo *) container, blob->setter); + else + return NULL; +} + +/** + * g_property_info_get_getter: + * @info: a #GIPropertyInfo + * + * Obtains the getter function associated with this #GIPropertyInfo. + * + * The setter is only available for %G_PARAM_READABLE properties. + * + * Returns: (transfer full): the function info or %NULL if not set. + * Free it with g_base_info_unref() when done. + */ +GIFunctionInfo * +g_property_info_get_getter (GIPropertyInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + PropertyBlob *blob; + GIBaseInfo *container; + GIInfoType parent_type; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_PROPERTY_INFO (info), NULL); + + blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset]; + if (!blob->readable) + return NULL; + + if (blob->getter == 0x3ff) + return NULL; + + container = rinfo->container; + parent_type = g_base_info_get_type (container); + if (parent_type == GI_INFO_TYPE_OBJECT) + return g_object_info_get_method ((GIObjectInfo *) container, blob->getter); + else if (parent_type == GI_INFO_TYPE_INTERFACE) + return g_interface_info_get_method ((GIInterfaceInfo *) container, blob->getter); + else + return NULL; +} diff --git a/gipropertyinfo.h b/gipropertyinfo.h index 7f9c89a07..4889f42eb 100644 --- a/gipropertyinfo.h +++ b/gipropertyinfo.h @@ -50,6 +50,12 @@ GITypeInfo * g_property_info_get_type (GIPropertyInfo *info); GI_AVAILABLE_IN_ALL GITransfer g_property_info_get_ownership_transfer (GIPropertyInfo *info); +GI_AVAILABLE_IN_1_70 +GIFunctionInfo *g_property_info_get_setter (GIPropertyInfo *info); + +GI_AVAILABLE_IN_1_70 +GIFunctionInfo *g_property_info_get_getter (GIPropertyInfo *info); + G_END_DECLS #endif /* __GIPROPERTYINFO_H__ */ diff --git a/girnode.c b/girnode.c index 5e74b0b01..9ea165de8 100644 --- a/girnode.c +++ b/girnode.c @@ -254,6 +254,8 @@ _g_ir_node_free (GIrNode *node) GIrNodeProperty *property = (GIrNodeProperty *)node; g_free (node->name); + g_free (property->setter); + g_free (property->getter); _g_ir_node_free ((GIrNode *)property->type); } break; @@ -1627,6 +1629,36 @@ _g_ir_node_build_typelib (GIrNode *node, blob->transfer_container_ownership = prop->shallow_transfer; blob->reserved = 0; + if (prop->setter != NULL) + { + int index = get_index_of_member_type ((GIrNodeInterface*)parent, + G_IR_NODE_FUNCTION, + prop->setter); + if (index == -1) + { + g_error ("Unknown setter %s for property %s", prop->setter, node->name); + } + + blob->setter = (guint) index; + } + else + blob->setter = 0x3ff; /* max of 10 bits */ + + if (prop->getter != NULL) + { + int index = get_index_of_member_type ((GIrNodeInterface*)parent, + G_IR_NODE_FUNCTION, + prop->getter); + if (index == -1) + { + g_error ("Unknown getter %s for property %s", prop->getter, node->name); + } + + blob->getter = (guint) index; + } + else + blob->getter = 0x3ff; + _g_ir_node_build_typelib ((GIrNode *)prop->type, node, build, offset, offset2, NULL); } diff --git a/girnode.h b/girnode.h index f2645b68d..7b8c97f62 100644 --- a/girnode.h +++ b/girnode.h @@ -174,6 +174,9 @@ struct _GIrNodeProperty gboolean transfer; gboolean shallow_transfer; + char *setter; + char *getter; + GIrNodeType *type; }; diff --git a/girparser.c b/girparser.c index 2d30f201d..470f0933f 100644 --- a/girparser.c +++ b/girparser.c @@ -1526,6 +1526,8 @@ start_property (GMarkupParseContext *context, const gchar *construct; const gchar *construct_only; const gchar *transfer; + const gchar *setter; + const gchar *getter; GIrNodeProperty *property; GIrNodeInterface *iface; @@ -1551,6 +1553,8 @@ start_property (GMarkupParseContext *context, construct = find_attribute ("construct", attribute_names, attribute_values); construct_only = find_attribute ("construct-only", attribute_names, attribute_values); transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values); + setter = find_attribute ("setter", attribute_names, attribute_values); + getter = find_attribute ("getter", attribute_names, attribute_values); if (name == NULL) { @@ -1582,6 +1586,9 @@ start_property (GMarkupParseContext *context, else property->construct_only = FALSE; + property->setter = g_strdup (setter); + property->getter = g_strdup (getter); + parse_property_transfer (property, transfer, ctx); iface = (GIrNodeInterface *)CURRENT_NODE (ctx); diff --git a/girwriter.c b/girwriter.c index 2393e7d78..a45edfd8d 100644 --- a/girwriter.c +++ b/girwriter.c @@ -977,6 +977,28 @@ write_property_info (const gchar *namespace, if (flags & G_PARAM_CONSTRUCT_ONLY) xml_printf (file, " construct-only=\"1\""); + if (flags & G_PARAM_READABLE) + { + GIFunctionInfo *getter = g_property_info_get_getter (info); + + if (getter != NULL) + { + xml_printf (file, " getter=\"%s\"", g_base_info_get_name ((GIBaseInfo *) getter)); + g_base_info_unref ((GIBaseInfo *) getter); + } + } + + if (flags & G_PARAM_WRITABLE) + { + GIFunctionInfo *setter = g_property_info_get_setter (info); + + if (setter != NULL) + { + xml_printf (file, " setter=\"%s\"", g_base_info_get_name ((GIBaseInfo *) setter)); + g_base_info_unref ((GIBaseInfo *) setter); + } + } + write_ownership_transfer (g_property_info_get_ownership_transfer (info), file); write_attributes (file, (GIBaseInfo*) info); diff --git a/gitypelib-internal.h b/gitypelib-internal.h index f25b863bf..2f1b86135 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -918,6 +918,10 @@ typedef struct { * ownership of the container, but not of its contents, is transferred. * This is typically the case when reading lists of statically allocated * things. + * @setter: the index of the setter function for this property, if @writable + * is set; if the method is not known, the value will be set to 0x3ff + * @getter: ths index of the getter function for this property, if @readable + * is set; if the method is not known, the value will be set to 0x3ff * @reserved: Reserved for future use. * @reserved2: Reserved for future use. * @type: Describes the type of the property. @@ -934,7 +938,9 @@ typedef struct { guint32 construct_only : 1; guint32 transfer_ownership : 1; guint32 transfer_container_ownership : 1; - guint32 reserved :25; + guint32 setter :10; + guint32 getter :10; + guint32 reserved : 5; guint32 reserved2; From 493441c84d17eb2360ecbf95483bb4d0365bbac0 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 28 Jun 2021 23:22:35 +0100 Subject: [PATCH 640/692] Use a macro for the missing accessor sentinel value Easier to read than `0x3ff`. --- gipropertyinfo.c | 8 ++++---- girnode.c | 4 ++-- gitypelib-internal.h | 6 ++++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/gipropertyinfo.c b/gipropertyinfo.c index 9b854b90a..4a291a069 100644 --- a/gipropertyinfo.c +++ b/gipropertyinfo.c @@ -142,7 +142,7 @@ g_property_info_get_ownership_transfer (GIPropertyInfo *info) * The setter is only available for %G_PARAM_WRITABLE properties that * are also not %G_PARAM_CONSTRUCT_ONLY. * - * Returns: (transfer full): the function info or %NULL if not set. + * Returns: (transfer full) (nullable): the function info or %NULL if not set. * Free it with g_base_info_unref() when done. */ GIFunctionInfo * @@ -160,7 +160,7 @@ g_property_info_get_setter (GIPropertyInfo *info) if (!blob->writable || blob->construct_only) return NULL; - if (blob->setter == 0x3ff) + if (blob->setter == ACCESSOR_SENTINEL) return NULL; container = rinfo->container; @@ -181,7 +181,7 @@ g_property_info_get_setter (GIPropertyInfo *info) * * The setter is only available for %G_PARAM_READABLE properties. * - * Returns: (transfer full): the function info or %NULL if not set. + * Returns: (transfer full) (nullable): the function info or %NULL if not set. * Free it with g_base_info_unref() when done. */ GIFunctionInfo * @@ -199,7 +199,7 @@ g_property_info_get_getter (GIPropertyInfo *info) if (!blob->readable) return NULL; - if (blob->getter == 0x3ff) + if (blob->getter == ACCESSOR_SENTINEL) return NULL; container = rinfo->container; diff --git a/girnode.c b/girnode.c index 9ea165de8..c550f177c 100644 --- a/girnode.c +++ b/girnode.c @@ -1642,7 +1642,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob->setter = (guint) index; } else - blob->setter = 0x3ff; /* max of 10 bits */ + blob->setter = ACCESSOR_SENTINEL; if (prop->getter != NULL) { @@ -1657,7 +1657,7 @@ _g_ir_node_build_typelib (GIrNode *node, blob->getter = (guint) index; } else - blob->getter = 0x3ff; + blob->getter = ACCESSOR_SENTINEL; _g_ir_node_build_typelib ((GIrNode *)prop->type, node, build, offset, offset2, NULL); diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 2f1b86135..7fe9128f2 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -903,6 +903,8 @@ typedef struct { ValueBlob values[]; } EnumBlob; +#define ACCESSOR_SENTINEL 0x3ff + /** * PropertyBlob: * @name: The name of the property. @@ -919,9 +921,9 @@ typedef struct { * This is typically the case when reading lists of statically allocated * things. * @setter: the index of the setter function for this property, if @writable - * is set; if the method is not known, the value will be set to 0x3ff + * is set; if the method is not known, the value will be set to %ACCESSOR_SENTINEL * @getter: ths index of the getter function for this property, if @readable - * is set; if the method is not known, the value will be set to 0x3ff + * is set; if the method is not known, the value will be set to %ACCESSOR_SENTINEL * @reserved: Reserved for future use. * @reserved2: Reserved for future use. * @type: Describes the type of the property. From c6adbd568ae5e665f15f89d2cf0f37ac953ddea9 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Tue, 27 Jul 2021 14:46:15 +0100 Subject: [PATCH 641/692] Improve readability of error message Use the parent type and the function symbol when erroring out if we can't find a property accessor. --- girnode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/girnode.c b/girnode.c index c550f177c..4db679d8d 100644 --- a/girnode.c +++ b/girnode.c @@ -1636,7 +1636,7 @@ _g_ir_node_build_typelib (GIrNode *node, prop->setter); if (index == -1) { - g_error ("Unknown setter %s for property %s", prop->setter, node->name); + g_error ("Unknown setter %s for property %s:%s", prop->setter, parent->name, node->name); } blob->setter = (guint) index; @@ -1651,7 +1651,7 @@ _g_ir_node_build_typelib (GIrNode *node, prop->getter); if (index == -1) { - g_error ("Unknown getter %s for property %s", prop->getter, node->name); + g_error ("Unknown getter %s for property %s:%s", prop->getter, parent->name, node->name); } blob->getter = (guint) index; @@ -1698,7 +1698,7 @@ _g_ir_node_build_typelib (GIrNode *node, function->property); if (index == -1) { - g_error ("Unknown property %s for accessor %s", function->property, node->name); + g_error ("Unknown property %s:%s for accessor %s", parent->name, function->property, function->symbol); } blob->setter = function->is_setter; From 6a8dce273a4699c74fdfac122ca5e05fd6a8efd1 Mon Sep 17 00:00:00 2001 From: Sergei Trofimovich Date: Sun, 27 Jun 2021 20:57:13 +0100 Subject: [PATCH 642/692] girffi.c: fix return value for g_callable_info_prepare_closure() The initial failure was observed on `meld` against recently released `libffi-3.4-rc1`. There `meld` crashes as: ``` $ meld Segmentation fault (core dumped) $ gdb --args /usr/bin/python3.9 /usr/bin/meld (gdb) run ... Thread 1 "python3.9" received signal SIGSEGV, Segmentation fault. 0x00007fffe9ac1ae8 in g_callable_info_free_closure ( callable_info=0x555555d45990, closure=0x7fffe9e70c20) at ../gobject-introspection-1.68.0/girepository/girffi.c:428 428 g_free (wrapper->ffi_closure.cif->arg_types); (gdb) bt callable_info=0x555555d45990, closure=0x7fffe9e70c20) at ../gobject-introspection-1.68.0/girepository/girffi.c:428 data=0x555555d252d0) at ../pygobject-3.40.1/gi/pygi-closure.c:635 ... ``` The bug here is in type mismatch between expected return value of `g_callable_info_prepare_closure()` and actual value (executable code pointer): ```c ffi_closure * g_callable_info_prepare_closure(...) { gpointer exec_ptr; ... status = ffi_prep_closure_loc (&closure->ffi_closure, cif, callback, user_data, exec_ptr); return exec_ptr; } ``` Note: `exec_ptr` is a code pointer that could be directly executed by caller, like `((rt (*)(a1,a2))exec_ptr)(1,2);` It should never be wrapped into an `ffi_closure*`, which is normally called via `ffi_call(closure, ...)`. We see the problem when we try to free direct code pointer instead of `ffi_closure()` as starting from libffi-3.4 executable trampoline and `ffi_closure()` don't necessarily live in the same block: https://github.com/libffi/libffi/commit/9ba559217bea0803263a9a9a0bafcf9203606f5b Signed-off-by: Sergei Trofimovich --- girffi.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/girffi.c b/girffi.c index 86a13052e..b3b921958 100644 --- a/girffi.c +++ b/girffi.c @@ -406,10 +406,7 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, return NULL; } - /* Return exec_ptr, which points to the same underlying memory as - * closure, but via an executable-non-writable mapping. - */ - return exec_ptr; + return &closure->ffi_closure; } /** From 5e053279b53e62b08e67f07f57f8abb667aa421f Mon Sep 17 00:00:00 2001 From: Sergei Trofimovich Date: Sat, 17 Jul 2021 18:19:17 +0100 Subject: [PATCH 643/692] girffi.h: add g_callable_info_get_closure_native_address() API Commit 6bab939bf ("girffi.c: fix return value for g_callable_info_prepare_closure()") effectively changes semantics of return value from code pointer to data pinter (closure). `gjs` (and probably other software) relies on old (incorrect) semantics of g_callable_info_prepare_closure(): https://gitlab.gnome.org/GNOME/gjs/-/issues/428 This change exposes the API that allows extracting directly callacble code pointer. `gjs` will have to adapt to the new API. Signed-off-by: Sergei Trofimovich --- girffi.c | 17 +++++++++++++++++ girffi.h | 5 +++++ 2 files changed, 22 insertions(+) diff --git a/girffi.c b/girffi.c index b3b921958..127702039 100644 --- a/girffi.c +++ b/girffi.c @@ -349,6 +349,7 @@ g_function_invoker_destroy (GIFunctionInvoker *invoker) typedef struct { ffi_closure ffi_closure; gpointer writable_self; + gpointer native_address; } GIClosureWrapper; /** @@ -386,6 +387,7 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, return NULL; } closure->writable_self = closure; + closure->native_address = exec_ptr; atypes = g_callable_info_get_ffi_arg_types (callable_info, &n_args); status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, n_args, @@ -409,6 +411,21 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, return &closure->ffi_closure; } +/** + * g_callable_info_get_closure_native_address: + * @callable_info: a callable info from a typelib + * @closure: ffi closure + * + * Gets callable code from ffi_closure prepared by g_callable_info_prepare_closure() + */ +gpointer * +g_callable_info_get_closure_native_address (GICallableInfo *callable_info, + ffi_closure *closure) +{ + GIClosureWrapper *wrapper = (GIClosureWrapper *)closure; + return wrapper->native_address; +} + /** * g_callable_info_free_closure: * @callable_info: a callable info from a typelib diff --git a/girffi.h b/girffi.h index d8a573698..c6cb5e91b 100644 --- a/girffi.h +++ b/girffi.h @@ -95,6 +95,11 @@ ffi_closure * g_callable_info_prepare_closure (GICallableInfo *callabl ffi_cif *cif, GIFFIClosureCallback callback, gpointer user_data); + +GI_AVAILABLE_IN_1_70 +gpointer * g_callable_info_get_closure_native_address (GICallableInfo *callable_info, + ffi_closure *closure); + GI_AVAILABLE_IN_ALL void g_callable_info_free_closure (GICallableInfo *callable_info, ffi_closure *closure); From 8e96029a32ef8be00ba8eee4306fc07722a94ef9 Mon Sep 17 00:00:00 2001 From: Cimbali Date: Mon, 1 Nov 2021 17:22:50 +0100 Subject: [PATCH 644/692] Create new API for libffi closures Deprecate the previous API as per discussion in !283. --- girffi.c | 75 ++++++++++++++++++++++++++++++++++++++++------- girffi.h | 21 +++++++++---- giversionmacros.h | 14 +++++++++ 3 files changed, 94 insertions(+), 16 deletions(-) diff --git a/girffi.c b/girffi.c index 127702039..851651321 100644 --- a/girffi.c +++ b/girffi.c @@ -353,7 +353,7 @@ typedef struct { } GIClosureWrapper; /** - * g_callable_info_prepare_closure: + * g_callable_info_create_closure: * @callable_info: a callable info from a typelib * @cif: a ffi_cif structure * @callback: the ffi callback @@ -362,13 +362,13 @@ typedef struct { * Prepares a callback for ffi invocation. * * Returns: the ffi_closure or NULL on error. The return value - * should be freed by calling g_callable_info_free_closure(). + * should be freed by calling g_callable_info_destroy_closure(). */ ffi_closure * -g_callable_info_prepare_closure (GICallableInfo *callable_info, - ffi_cif *cif, - GIFFIClosureCallback callback, - gpointer user_data) +g_callable_info_create_closure (GICallableInfo *callable_info, + ffi_cif *cif, + GIFFIClosureCallback callback, + gpointer user_data) { gpointer exec_ptr; int n_args; @@ -389,6 +389,7 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, closure->writable_self = closure; closure->native_address = exec_ptr; + atypes = g_callable_info_get_ffi_arg_types (callable_info, &n_args); status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, n_args, g_callable_info_get_ffi_return_type (callable_info), @@ -416,7 +417,7 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, * @callable_info: a callable info from a typelib * @closure: ffi closure * - * Gets callable code from ffi_closure prepared by g_callable_info_prepare_closure() + * Gets callable code from ffi_closure prepared by g_callable_info_create_closure() */ gpointer * g_callable_info_get_closure_native_address (GICallableInfo *callable_info, @@ -427,18 +428,70 @@ g_callable_info_get_closure_native_address (GICallableInfo *callable_info, } /** - * g_callable_info_free_closure: + * g_callable_info_destroy_closure: * @callable_info: a callable info from a typelib * @closure: ffi closure * - * Frees a ffi_closure returned from g_callable_info_prepare_closure() + * Frees a ffi_closure returned from g_callable_info_create_closure() */ void -g_callable_info_free_closure (GICallableInfo *callable_info, - ffi_closure *closure) +g_callable_info_destroy_closure (GICallableInfo *callable_info, + ffi_closure *closure) { GIClosureWrapper *wrapper = (GIClosureWrapper *)closure; g_free (wrapper->ffi_closure.cif->arg_types); ffi_closure_free (wrapper->writable_self); } + +/** + * g_callable_info_prepare_closure: + * @callable_info: a callable info from a typelib + * @cif: a ffi_cif structure + * @callback: the ffi callback + * @user_data: data to be passed into the callback + * + * Prepares a callback for ffi invocation. Deprecated + * + * Returns: the native address of the closre or NULL on error. The return value + * should be freed by calling g_callable_info_free_closure(). + */ +ffi_closure * +g_callable_info_prepare_closure (GICallableInfo *callable_info, + ffi_cif *cif, + GIFFIClosureCallback callback, + gpointer user_data) +{ + ffi_closure * closure; + + closure = g_callable_info_create_closure(callable_info, cif, callback, user_data); + if (!closure) + { + return NULL; + } + + g_warning ("g_callable_info_prepare_closure is deprecated, use g_callable_info_create_closure instead\n"); + + /* Return the native pointer which, on some systems and ffi versions without static exec trampolines, + * points to the same underlying memory as closure, but via an executable-non-writable mapping. + * Deprecated, and kept for backwards compatibility only. Risks segfaults on freeing the closure. + */ + return (ffi_closure *) g_callable_info_get_closure_native_address(callable_info, closure); +} + +/** + * g_callable_info_free_closure: + * @callable_info: a callable info from a typelib + * @closure: ffi closure + * + * Does nothing. (Leaks memory!) Use g_callable_info_destroy_closure() instead, + * in conjunction with g_callable_info_create_closure(). + * + * Should free a ffi_closure returned from g_callable_info_prepare_closure(), + * which may cause a segfault because the native address is returned instead + * of the closure address. + */ +void g_callable_info_free_closure (GICallableInfo *callable_info, ffi_closure *closure) +{ + g_warning ("g_callable_info_free_closure is deprecated and leaks memory\n"); +} diff --git a/girffi.h b/girffi.h index c6cb5e91b..2bbc97ac3 100644 --- a/girffi.h +++ b/girffi.h @@ -90,19 +90,30 @@ GI_AVAILABLE_IN_ALL void g_function_invoker_destroy (GIFunctionInvoker *invoker); -GI_AVAILABLE_IN_ALL +GI_DEPRECATED_IN_1_72_FOR(g_callable_info_create_closure) ffi_closure * g_callable_info_prepare_closure (GICallableInfo *callable_info, ffi_cif *cif, GIFFIClosureCallback callback, gpointer user_data); -GI_AVAILABLE_IN_1_70 +GI_DEPRECATED_IN_1_72_FOR(g_callable_info_destroy_closure) +void g_callable_info_free_closure (GICallableInfo *callable_info, + ffi_closure *closure); + + +GI_AVAILABLE_IN_1_72 +ffi_closure * g_callable_info_create_closure (GICallableInfo *callable_info, + ffi_cif *cif, + GIFFIClosureCallback callback, + gpointer user_data); + +GI_AVAILABLE_IN_1_72 gpointer * g_callable_info_get_closure_native_address (GICallableInfo *callable_info, ffi_closure *closure); -GI_AVAILABLE_IN_ALL -void g_callable_info_free_closure (GICallableInfo *callable_info, - ffi_closure *closure); +GI_AVAILABLE_IN_1_72 +void g_callable_info_destroy_closure (GICallableInfo *callable_info, + ffi_closure *closure); G_END_DECLS diff --git a/giversionmacros.h b/giversionmacros.h index 273af7253..d1b1733c0 100644 --- a/giversionmacros.h +++ b/giversionmacros.h @@ -171,4 +171,18 @@ # define GI_AVAILABLE_IN_1_70 _GI_EXTERN #endif +#if defined(GLIB_VERSION_2_72) && GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_72 +# define GI_DEPRECATED_IN_1_72 GLIB_DEPRECATED +# define GI_DEPRECATED_IN_1_72_FOR(f) GLIB_DEPRECATED_FOR(f) +#else +# define GI_DEPRECATED_IN_1_72 _GI_EXTERN +# define GI_DEPRECATED_IN_1_72_FOR(f) _GI_EXTERN +#endif + +#if defined(GLIB_VERSION_2_72) && GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_72 +# define GI_AVAILABLE_IN_1_72 GLIB_UNAVAILABLE(2, 72) +#else +# define GI_AVAILABLE_IN_1_72 _GI_EXTERN +#endif + #endif /* __GIVERSIONMACROS_H__ */ From f77269c4808549038db4fa3a260e7403d87f1e9e Mon Sep 17 00:00:00 2001 From: Cimbali Date: Mon, 1 Nov 2021 19:31:58 +0100 Subject: [PATCH 645/692] Avoid leaking memory from FFI closure if no segfault risk --- girffi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/girffi.c b/girffi.c index 851651321..4cf139d07 100644 --- a/girffi.c +++ b/girffi.c @@ -494,4 +494,7 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, void g_callable_info_free_closure (GICallableInfo *callable_info, ffi_closure *closure) { g_warning ("g_callable_info_free_closure is deprecated and leaks memory\n"); +#ifdef LEGACY_GIRFFI_FREE + g_callable_info_destroy_closure(callable_info, closure); +#endif } From b03c3d0a16442d106dae7710608aa68213b19fee Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 1 Nov 2021 20:54:55 +0000 Subject: [PATCH 646/692] Fix styling issues from suggestions --- girffi.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/girffi.c b/girffi.c index 4cf139d07..5bf974371 100644 --- a/girffi.c +++ b/girffi.c @@ -362,7 +362,7 @@ typedef struct { * Prepares a callback for ffi invocation. * * Returns: the ffi_closure or NULL on error. The return value - * should be freed by calling g_callable_info_destroy_closure(). + * should be freed by calling g_callable_info_destroy_closure(). */ ffi_closure * g_callable_info_create_closure (GICallableInfo *callable_info, @@ -453,8 +453,8 @@ g_callable_info_destroy_closure (GICallableInfo *callable_info, * * Prepares a callback for ffi invocation. Deprecated * - * Returns: the native address of the closre or NULL on error. The return value - * should be freed by calling g_callable_info_free_closure(). + * Returns: the native address of the closure or `NULL` on error. The return value + * should be freed by calling g_callable_info_free_closure(). */ ffi_closure * g_callable_info_prepare_closure (GICallableInfo *callable_info, @@ -464,7 +464,7 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, { ffi_closure * closure; - closure = g_callable_info_create_closure(callable_info, cif, callback, user_data); + closure = g_callable_info_create_closure (callable_info, cif, callback, user_data); if (!closure) { return NULL; @@ -491,7 +491,9 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, * which may cause a segfault because the native address is returned instead * of the closure address. */ -void g_callable_info_free_closure (GICallableInfo *callable_info, ffi_closure *closure) +void +g_callable_info_free_closure (GICallableInfo *callable_info, + ffi_closure *closure) { g_warning ("g_callable_info_free_closure is deprecated and leaks memory\n"); #ifdef LEGACY_GIRFFI_FREE From d991e197de22d2a2967fbdbad42463d9f11049fa Mon Sep 17 00:00:00 2001 From: Cimbali Date: Mon, 1 Nov 2021 22:03:26 +0100 Subject: [PATCH 647/692] Remove runtime warnings, add doxygen deprecation notices --- girffi.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/girffi.c b/girffi.c index 5bf974371..43d3f18f1 100644 --- a/girffi.c +++ b/girffi.c @@ -451,7 +451,9 @@ g_callable_info_destroy_closure (GICallableInfo *callable_info, * @callback: the ffi callback * @user_data: data to be passed into the callback * - * Prepares a callback for ffi invocation. Deprecated + * Prepares a callback for ffi invocation. + * + * Deprecated: 1.72: Use g_callable_info_create_closure() instead * * Returns: the native address of the closure or `NULL` on error. The return value * should be freed by calling g_callable_info_free_closure(). @@ -470,8 +472,6 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, return NULL; } - g_warning ("g_callable_info_prepare_closure is deprecated, use g_callable_info_create_closure instead\n"); - /* Return the native pointer which, on some systems and ffi versions without static exec trampolines, * points to the same underlying memory as closure, but via an executable-non-writable mapping. * Deprecated, and kept for backwards compatibility only. Risks segfaults on freeing the closure. @@ -484,18 +484,18 @@ g_callable_info_prepare_closure (GICallableInfo *callable_info, * @callable_info: a callable info from a typelib * @closure: ffi closure * - * Does nothing. (Leaks memory!) Use g_callable_info_destroy_closure() instead, - * in conjunction with g_callable_info_create_closure(). + * Deprecated: 1.72: Use g_callable_info_destroy_closure() instead, in + * conjunction with g_callable_info_create_closure(). * * Should free a ffi_closure returned from g_callable_info_prepare_closure(), - * which may cause a segfault because the native address is returned instead - * of the closure address. + * which may cause a segfault because the native address is returned instead of + * the closure address. May do nothing and leak memory instead of freeing to + * avoid segfaults. */ void g_callable_info_free_closure (GICallableInfo *callable_info, ffi_closure *closure) { - g_warning ("g_callable_info_free_closure is deprecated and leaks memory\n"); #ifdef LEGACY_GIRFFI_FREE g_callable_info_destroy_closure(callable_info, closure); #endif From 4027d2e12a2b594d1f6a4e1313d2d2563cc967fc Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 24 Nov 2021 16:41:01 +0000 Subject: [PATCH 648/692] Do not use GLib versioning symbols Libgirepository is not GLib, and it should not use GLIB_DEPRECATED, GLIB_DEPRECATED_FOR, and GLIB_UNAVAILABLE macros (as the GLib documentation clearly states). When using them, we don't get the proper macro expansion, so deprecated symbols suddenly disappear from our shared library. --- giversionmacros.h | 70 +++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/giversionmacros.h b/giversionmacros.h index d1b1733c0..67bb6c102 100644 --- a/giversionmacros.h +++ b/giversionmacros.h @@ -32,6 +32,16 @@ #define _GI_EXTERN extern #endif +#ifndef GI_DISABLE_DEPRECATION_WARNINGS +# define GI_DEPRECATED G_DEPRECATED _GI_EXTERN +# define GI_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f) _GI_EXTERN +# define GI_UNAVAILABLE(maj,min) G_UNAVAILABLE(maj, min) _GI_EXTERN +#else +# define GI_DEPRECATED _GI_EXTERN +# define GI_DEPRECATED_FOR(f) _GI_EXTERN +# define GI_UNAVAILABLE(maj,min) _GI_EXTERN +#endif + #define GI_AVAILABLE_IN_ALL _GI_EXTERN /* XXX: Every new stable minor release should add a set of macros here @@ -42,145 +52,145 @@ */ #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_32 -# define GI_DEPRECATED_IN_1_32 GLIB_DEPRECATED -# define GI_DEPRECATED_IN_1_32_FOR(f) GLIB_DEPRECATED_FOR(f) +# define GI_DEPRECATED_IN_1_32 GI_DEPRECATED +# define GI_DEPRECATED_IN_1_32_FOR(f) GI_DEPRECATED_FOR(f) #else # define GI_DEPRECATED_IN_1_32 _GI_EXTERN # define GI_DEPRECATED_IN_1_32_FOR(f) _GI_EXTERN #endif #if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_32 -# define GI_AVAILABLE_IN_1_32 GLIB_UNAVAILABLE(2, 32) +# define GI_AVAILABLE_IN_1_32 GI_UNAVAILABLE(2, 32) #else # define GI_AVAILABLE_IN_1_32 _GI_EXTERN #endif #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_34 -# define GI_DEPRECATED_IN_1_34 GLIB_DEPRECATED -# define GI_DEPRECATED_IN_1_34_FOR(f) GLIB_DEPRECATED_FOR(f) +# define GI_DEPRECATED_IN_1_34 GI_DEPRECATED +# define GI_DEPRECATED_IN_1_34_FOR(f) GI_DEPRECATED_FOR(f) #else # define GI_DEPRECATED_IN_1_34 _GI_EXTERN # define GI_DEPRECATED_IN_1_34_FOR(f) _GI_EXTERN #endif #if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_34 -# define GI_AVAILABLE_IN_1_34 GLIB_UNAVAILABLE(2, 34) +# define GI_AVAILABLE_IN_1_34 GI_UNAVAILABLE(2, 34) #else # define GI_AVAILABLE_IN_1_34 _GI_EXTERN #endif #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_36 -# define GI_DEPRECATED_IN_1_36 GLIB_DEPRECATED -# define GI_DEPRECATED_IN_1_36_FOR(f) GLIB_DEPRECATED_FOR(f) +# define GI_DEPRECATED_IN_1_36 GI_DEPRECATED +# define GI_DEPRECATED_IN_1_36_FOR(f) GI_DEPRECATED_FOR(f) #else # define GI_DEPRECATED_IN_1_36 _GI_EXTERN # define GI_DEPRECATED_IN_1_36_FOR(f) _GI_EXTERN #endif #if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_36 -# define GI_AVAILABLE_IN_1_36 GLIB_UNAVAILABLE(2, 36) +# define GI_AVAILABLE_IN_1_36 GI_UNAVAILABLE(2, 36) #else # define GI_AVAILABLE_IN_1_36 _GI_EXTERN #endif #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_38 -# define GI_DEPRECATED_IN_1_38 GLIB_DEPRECATED -# define GI_DEPRECATED_IN_1_38_FOR(f) GLIB_DEPRECATED_FOR(f) +# define GI_DEPRECATED_IN_1_38 GI_DEPRECATED +# define GI_DEPRECATED_IN_1_38_FOR(f) GI_DEPRECATED_FOR(f) #else # define GI_DEPRECATED_IN_1_38 _GI_EXTERN # define GI_DEPRECATED_IN_1_38_FOR(f) _GI_EXTERN #endif #if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_38 -# define GI_AVAILABLE_IN_1_38 GLIB_UNAVAILABLE(2, 38) +# define GI_AVAILABLE_IN_1_38 GI_UNAVAILABLE(2, 38) #else # define GI_AVAILABLE_IN_1_38 _GI_EXTERN #endif #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_40 -# define GI_DEPRECATED_IN_1_40 GLIB_DEPRECATED -# define GI_DEPRECATED_IN_1_40_FOR(f) GLIB_DEPRECATED_FOR(f) +# define GI_DEPRECATED_IN_1_40 GI_DEPRECATED +# define GI_DEPRECATED_IN_1_40_FOR(f) GI_DEPRECATED_FOR(f) #else # define GI_DEPRECATED_IN_1_40 _GI_EXTERN # define GI_DEPRECATED_IN_1_40_FOR(f) _GI_EXTERN #endif #if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_40 -# define GI_AVAILABLE_IN_1_40 GLIB_UNAVAILABLE(2, 40) +# define GI_AVAILABLE_IN_1_40 GI_UNAVAILABLE(2, 40) #else # define GI_AVAILABLE_IN_1_40 _GI_EXTERN #endif #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_42 -# define GI_DEPRECATED_IN_1_42 GLIB_DEPRECATED -# define GI_DEPRECATED_IN_1_42_FOR(f) GLIB_DEPRECATED_FOR(f) +# define GI_DEPRECATED_IN_1_42 GI_DEPRECATED +# define GI_DEPRECATED_IN_1_42_FOR(f) GI_DEPRECATED_FOR(f) #else # define GI_DEPRECATED_IN_1_42 _GI_EXTERN # define GI_DEPRECATED_IN_1_42_FOR(f) _GI_EXTERN #endif #if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_42 -# define GI_AVAILABLE_IN_1_42 GLIB_UNAVAILABLE(2, 42) +# define GI_AVAILABLE_IN_1_42 GI_UNAVAILABLE(2, 42) #else # define GI_AVAILABLE_IN_1_42 _GI_EXTERN #endif #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_44 -# define GI_DEPRECATED_IN_1_44 GLIB_DEPRECATED -# define GI_DEPRECATED_IN_1_44_FOR(f) GLIB_DEPRECATED_FOR(f) +# define GI_DEPRECATED_IN_1_44 GI_DEPRECATED +# define GI_DEPRECATED_IN_1_44_FOR(f) GI_DEPRECATED_FOR(f) #else # define GI_DEPRECATED_IN_1_44 _GI_EXTERN # define GI_DEPRECATED_IN_1_44_FOR(f) _GI_EXTERN #endif #if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_44 -# define GI_AVAILABLE_IN_1_44 GLIB_UNAVAILABLE(2, 44) +# define GI_AVAILABLE_IN_1_44 GI_UNAVAILABLE(2, 44) #else # define GI_AVAILABLE_IN_1_44 _GI_EXTERN #endif #if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_46 -# define GI_DEPRECATED_IN_1_46 GLIB_DEPRECATED -# define GI_DEPRECATED_IN_1_46_FOR(f) GLIB_DEPRECATED_FOR(f) +# define GI_DEPRECATED_IN_1_46 GI_DEPRECATED +# define GI_DEPRECATED_IN_1_46_FOR(f) GI_DEPRECATED_FOR(f) #else # define GI_DEPRECATED_IN_1_46 _GI_EXTERN # define GI_DEPRECATED_IN_1_46_FOR(f) _GI_EXTERN #endif #if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_46 -# define GI_AVAILABLE_IN_1_46 GLIB_UNAVAILABLE(2, 46) +# define GI_AVAILABLE_IN_1_46 GI_UNAVAILABLE(2, 46) #else # define GI_AVAILABLE_IN_1_46 _GI_EXTERN #endif #if defined(GLIB_VERSION_2_60) && GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_60 -# define GI_AVAILABLE_IN_1_60 GLIB_UNAVAILABLE(2, 60) +# define GI_AVAILABLE_IN_1_60 GI_UNAVAILABLE(2, 60) #else # define GI_AVAILABLE_IN_1_60 _GI_EXTERN #endif #if defined(GLIB_VERSION_2_66) && GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_66 -# define GI_AVAILABLE_IN_1_66 GLIB_UNAVAILABLE(2, 66) +# define GI_AVAILABLE_IN_1_66 GI_UNAVAILABLE(2, 66) #else # define GI_AVAILABLE_IN_1_66 _GI_EXTERN #endif #if defined(GLIB_VERSION_2_70) && GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_70 -# define GI_AVAILABLE_IN_1_70 GLIB_UNAVAILABLE(2, 70) +# define GI_AVAILABLE_IN_1_70 GI_UNAVAILABLE(2, 70) #else # define GI_AVAILABLE_IN_1_70 _GI_EXTERN #endif #if defined(GLIB_VERSION_2_72) && GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_72 -# define GI_DEPRECATED_IN_1_72 GLIB_DEPRECATED -# define GI_DEPRECATED_IN_1_72_FOR(f) GLIB_DEPRECATED_FOR(f) +# define GI_DEPRECATED_IN_1_72 GI_DEPRECATED +# define GI_DEPRECATED_IN_1_72_FOR(f) GI_DEPRECATED_FOR(f) #else # define GI_DEPRECATED_IN_1_72 _GI_EXTERN # define GI_DEPRECATED_IN_1_72_FOR(f) _GI_EXTERN #endif #if defined(GLIB_VERSION_2_72) && GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_72 -# define GI_AVAILABLE_IN_1_72 GLIB_UNAVAILABLE(2, 72) +# define GI_AVAILABLE_IN_1_72 GI_UNAVAILABLE(2, 72) #else # define GI_AVAILABLE_IN_1_72 _GI_EXTERN #endif From c493763ff2b9385ecf7eb48393a6830b6367f2d9 Mon Sep 17 00:00:00 2001 From: Rok Mandeljc Date: Sat, 27 Nov 2021 20:05:32 +0100 Subject: [PATCH 649/692] gitypelib.c: on macOS, treat @-prefixed shlib paths as absolute On macOS, @-prefixed shlib paths (@rpath, @executable_path, and @loader_path) need to be treated as absolute. Trying to combine them with a configured library path produces a mangled path that is unresolvable and may cause unintended side effects (such as loading the library from a fall-back location on macOS 12.0.1). --- gitypelib.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gitypelib.c b/gitypelib.c index 904dff45a..d5ef45064 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -2262,7 +2262,17 @@ load_one_shared_library (const char *shlib) GSList *p; GModule *m; +#ifdef __APPLE__ + /* On macOS, @-prefixed shlib paths (@rpath, @executable_path, @loader_path) + need to be treated as absolute; trying to combine them with a + configured library path produces a mangled path that is unresolvable + and may cause unintended side effects (such as loading the library + from a fall-back location on macOS 12.0.1). + */ + if (!g_path_is_absolute (shlib) && !g_str_has_prefix (shlib, "@")) +#else if (!g_path_is_absolute (shlib)) +#endif { /* First try in configured library paths */ for (p = library_paths; p; p = p->next) From 4398e1fde2eb127ac3c825db7fdc2bbe94bc6772 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 8 Apr 2020 20:04:03 +0100 Subject: [PATCH 650/692] Add "forever" scope Some functions are meant to exist for the entire duration of the process, and thus have no need for a notification function because one will never be called. Fixes: #49 --- girparser.c | 2 ++ girwriter.c | 3 +++ gitypes.h | 15 +++++++++------ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/girparser.c b/girparser.c index 470f0933f..e5878b431 100644 --- a/girparser.c +++ b/girparser.c @@ -1244,6 +1244,8 @@ start_parameter (GMarkupParseContext *context, param->scope = GI_SCOPE_TYPE_ASYNC; else if (scope && strcmp (scope, "notified") == 0) param->scope = GI_SCOPE_TYPE_NOTIFIED; + else if (scope && strcmp (scope, "forever") == 0) + param->scope = GI_SCOPE_TYPE_FOREVER; else param->scope = GI_SCOPE_TYPE_INVALID; diff --git a/girwriter.c b/girwriter.c index a45edfd8d..44e18801f 100644 --- a/girwriter.c +++ b/girwriter.c @@ -532,6 +532,9 @@ write_callable_info (const gchar *namespace, case GI_SCOPE_TYPE_NOTIFIED: xml_printf (file, " scope=\"notified\""); break; + case GI_SCOPE_TYPE_FOREVER: + xml_printf (file, " scope=\"forever\""); + break; default: g_assert_not_reached (); } diff --git a/gitypes.h b/gitypes.h index 338975203..83268e896 100644 --- a/gitypes.h +++ b/gitypes.h @@ -358,12 +358,14 @@ typedef enum { * GIScopeType: * @GI_SCOPE_TYPE_INVALID: The argument is not of callback type. * @GI_SCOPE_TYPE_CALL: The callback and associated user_data is only - * used during the call to this function. + * used during the call to this function. * @GI_SCOPE_TYPE_ASYNC: The callback and associated user_data is - * only used until the callback is invoked, and the callback. - * is invoked always exactly once. - * @GI_SCOPE_TYPE_NOTIFIED: The callback and and associated - * user_data is used until the caller is notfied via the destroy_notify. + * only used until the callback is invoked, and the callback. + * is invoked always exactly once. + * @GI_SCOPE_TYPE_NOTIFIED: The callback and associated + * user_data is used until the caller is notfied via the destroy_notify. + * @GI_SCOPE_TYPE_FOREVER: The callback and associated user_data is + * used until the process terminates * * Scope type of a #GIArgInfo representing callback, determines how the * callback is invoked and is used to decided when the invoke structs @@ -373,7 +375,8 @@ typedef enum { GI_SCOPE_TYPE_INVALID, GI_SCOPE_TYPE_CALL, GI_SCOPE_TYPE_ASYNC, - GI_SCOPE_TYPE_NOTIFIED + GI_SCOPE_TYPE_NOTIFIED, + GI_SCOPE_TYPE_FOREVER } GIScopeType; /** From 3d999b47e53a2f7ea844ceebf6e30aac41af940b Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Tue, 11 Jan 2022 15:59:43 +0000 Subject: [PATCH 651/692] cmph: Handle fgets() return value Newer versions of the GNU libc have started to warn if the result of the call is unused. --- cmph/cmph.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmph/cmph.c b/cmph/cmph.c index 0c4b67d12..3fd40a297 100644 --- a/cmph/cmph.c +++ b/cmph/cmph.c @@ -155,7 +155,7 @@ static cmph_uint32 count_nlfile_keys(FILE *fd) while(1) { char buf[BUFSIZ]; - fgets(buf, BUFSIZ, fd); + if (fgets(buf, BUFSIZ, fd) == NULL) break; if (feof(fd)) break; if (buf[strlen(buf) - 1] != '\n') continue; ++count; From 6583ad7f4f57e65c9193481afd936566ada94fc3 Mon Sep 17 00:00:00 2001 From: Lukas Oberhuber Date: Tue, 11 Jan 2022 23:01:08 +0000 Subject: [PATCH 652/692] girepository: avoids segfault in case of bad gtype If a (that's the way it appears in python's debugger) is returned, `g_type_name` returns NULL. This function therefore returns NULL at this time as subsequent calls to `strlen( data->gtype_name)` segfault. --- girepository.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/girepository.c b/girepository.c index 7d0348598..d7f6ceb4d 100644 --- a/girepository.c +++ b/girepository.c @@ -806,12 +806,14 @@ find_by_gtype (GHashTable *table, FindByGTypeData *data, gboolean check_prefix) */ GIBaseInfo * g_irepository_find_by_gtype (GIRepository *repository, - GType gtype) + GType gtype) { FindByGTypeData data; GIBaseInfo *cached; DirEntry *entry; + g_return_val_if_fail (gtype != G_TYPE_INVALID, NULL); + repository = get_repository (repository); cached = g_hash_table_lookup (repository->priv->info_by_gtype, From 75b48f1dbe717b04f01e3efa292b630c043759cb Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Fri, 28 Jan 2022 13:19:59 -0800 Subject: [PATCH 653/692] gitypeinfo: Add GI_TYPE_TAG_IS_NUMERIC macro This is a convenience for bindings that want to perform a similar action for all numeric types. It allows more expressive code in some cases: if (GI_TYPE_TAG_IS_NUMERIC(tag)) { do_one_thing(); return; } switch (tag) { case GI_TYPE_TAG_ARRAY: do_other_thing(); return; /* ... */ default: g_assert_not_reached(); } instead of listing out all of the numeric types in the switch statement. --- gitypeinfo.h | 10 ++++++++++ gitypes.h | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/gitypeinfo.h b/gitypeinfo.h index fd7d5be6e..69d0dad60 100644 --- a/gitypeinfo.h +++ b/gitypeinfo.h @@ -48,6 +48,16 @@ G_BEGIN_DECLS */ #define G_TYPE_TAG_IS_BASIC(tag) (tag < GI_TYPE_TAG_ARRAY || tag == GI_TYPE_TAG_UNICHAR) +/** + * GI_TYPE_TAG_IS_NUMERIC: + * @tag: a type tag + * + * Checks if @tag is a numeric type. That is, integer or floating point. + * + * Since: 1.72 + */ +#define GI_TYPE_TAG_IS_NUMERIC(tag) ((tag) >= GI_TYPE_TAG_INT8 && (tag) <= GI_TYPE_TAG_DOUBLE) + GI_AVAILABLE_IN_ALL const gchar* g_type_tag_to_string (GITypeTag type); diff --git a/gitypes.h b/gitypes.h index 83268e896..47df79039 100644 --- a/gitypes.h +++ b/gitypes.h @@ -411,7 +411,7 @@ typedef enum { /* Basic types */ GI_TYPE_TAG_VOID = 0, GI_TYPE_TAG_BOOLEAN = 1, - GI_TYPE_TAG_INT8 = 2, + GI_TYPE_TAG_INT8 = 2, /* Start of GI_TYPE_TAG_IS_NUMERIC types */ GI_TYPE_TAG_UINT8 = 3, GI_TYPE_TAG_INT16 = 4, GI_TYPE_TAG_UINT16 = 5, @@ -420,7 +420,7 @@ typedef enum { GI_TYPE_TAG_INT64 = 8, GI_TYPE_TAG_UINT64 = 9, GI_TYPE_TAG_FLOAT = 10, - GI_TYPE_TAG_DOUBLE = 11, + GI_TYPE_TAG_DOUBLE = 11, /* End of numeric types */ GI_TYPE_TAG_GTYPE = 12, GI_TYPE_TAG_UTF8 = 13, GI_TYPE_TAG_FILENAME = 14, From 8f047f11f64eab1aa91674ca8a1c40e0027b5f0c Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Sat, 29 Jan 2022 17:54:27 -0800 Subject: [PATCH 654/692] gitypeinfo: Add GI_TYPE_TAG_IS_CONTAINER macro Like GI_TYPE_TAG_IS_NUMERIC, this is a convenience for bindings that want to perform a similar action for all container types. --- gitypeinfo.h | 12 ++++++++++++ gitypes.h | 8 ++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/gitypeinfo.h b/gitypeinfo.h index 69d0dad60..a8674fd9b 100644 --- a/gitypeinfo.h +++ b/gitypeinfo.h @@ -58,6 +58,18 @@ G_BEGIN_DECLS */ #define GI_TYPE_TAG_IS_NUMERIC(tag) ((tag) >= GI_TYPE_TAG_INT8 && (tag) <= GI_TYPE_TAG_DOUBLE) +/** + * GI_TYPE_TAG_IS_CONTAINER: + * @tag: a type tag + * + * Checks if @tag is a container type. That is, a type which may have a nonnull + * return from g_type_info_get_param_type(). + * + * Since: 1.72 + */ + #define GI_TYPE_TAG_IS_CONTAINER(tag) ((tag) == GI_TYPE_TAG_ARRAY || \ + ((tag) >= GI_TYPE_TAG_GLIST && (tag) <= GI_TYPE_TAG_GHASH)) + GI_AVAILABLE_IN_ALL const gchar* g_type_tag_to_string (GITypeTag type); diff --git a/gitypes.h b/gitypes.h index 47df79039..9c021ff23 100644 --- a/gitypes.h +++ b/gitypes.h @@ -425,11 +425,11 @@ typedef enum { GI_TYPE_TAG_UTF8 = 13, GI_TYPE_TAG_FILENAME = 14, /* Non-basic types; compare with G_TYPE_TAG_IS_BASIC */ - GI_TYPE_TAG_ARRAY = 15, + GI_TYPE_TAG_ARRAY = 15, /* container (see GI_TYPE_TAG_IS_CONTAINER) */ GI_TYPE_TAG_INTERFACE = 16, - GI_TYPE_TAG_GLIST = 17, - GI_TYPE_TAG_GSLIST = 18, - GI_TYPE_TAG_GHASH = 19, + GI_TYPE_TAG_GLIST = 17, /* container */ + GI_TYPE_TAG_GSLIST = 18, /* container */ + GI_TYPE_TAG_GHASH = 19, /* container */ GI_TYPE_TAG_ERROR = 20, /* Another basic type */ GI_TYPE_TAG_UNICHAR = 21 From 0f330c1581fdec115f8a01b98fded2c7625a0cca Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Fri, 28 Jan 2022 13:22:05 -0800 Subject: [PATCH 655/692] girepository: Clarify SimpleTypeBlob documentation The documentation comment for SimpleTypeBlob seemed to imply that a basic type was embedded if the reserved fields were nonzero. After examining the code, I believe that was actually due to some words missing, and the comment should say that the type is embedded if the fields are zero. --- gitypelib-internal.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 7fe9128f2..e4104089f 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -378,9 +378,9 @@ union _SimpleTypeBlob * references to types. * * SimpleTypeBlob is divided into two cases; first, if "reserved" and - * "reserved2", the type tag for a basic type is embedded in the "tag" bits. - * This allows e.g. GI_TYPE_TAG_UTF8, GI_TYPE_TAG_INT and the like to be - * embedded directly without taking up extra space. + * "reserved2" are both zero, the type tag for a basic type is embedded in the + * "tag" bits. This allows e.g. GI_TYPE_TAG_UTF8, GI_TYPE_TAG_INT and the like + * to be embedded directly without taking up extra space. * * References to "interfaces" (objects, interfaces) are more complicated; * In this case, the integer is actually an offset into the directory (see From aae9a3cdd148b2e8444de85e6a1e9ee2c58f1986 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Sat, 29 Jan 2022 23:35:52 -0800 Subject: [PATCH 656/692] girepository: Fix documentation comments It was driving me crazy that g_type_info_get_array_length() claimed to return an array length. --- gitypeinfo.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gitypeinfo.c b/gitypeinfo.c index e90f9463c..4fb7dddd2 100644 --- a/gitypeinfo.c +++ b/gitypeinfo.c @@ -221,8 +221,8 @@ g_type_info_get_interface (GITypeInfo *info) * g_type_info_get_array_length: * @info: a #GITypeInfo * - * Obtain the array length of the type. The type tag must be a - * #GI_TYPE_TAG_ARRAY or -1 will returned. + * Obtain the position of the argument which gives the array length of the type. + * The type tag must be a #GI_TYPE_TAG_ARRAY or -1 will be returned. * * Returns: the array length, or -1 if the type is not an array */ @@ -256,7 +256,7 @@ g_type_info_get_array_length (GITypeInfo *info) * @info: a #GITypeInfo * * Obtain the fixed array size of the type. The type tag must be a - * #GI_TYPE_TAG_ARRAY or -1 will returned. + * #GI_TYPE_TAG_ARRAY or -1 will be returned. * * Returns: the size or -1 if it's not an array */ @@ -290,7 +290,7 @@ g_type_info_get_array_fixed_size (GITypeInfo *info) * @info: a #GITypeInfo * * Obtain if the last element of the array is %NULL. The type tag must be a - * #GI_TYPE_TAG_ARRAY or %FALSE will returned. + * #GI_TYPE_TAG_ARRAY or %FALSE will be returned. * * Returns: %TRUE if zero terminated */ From b68a03b9b6eade76e173e9425038ebf952414670 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Thu, 3 Feb 2022 23:54:09 -0800 Subject: [PATCH 657/692] girffi: Add gi_type_tag_extract_ffi_return_value() This new API does the same thing as gi_type_info_extract_ffi_return_value, but takes a GITypeTag instead of GITypeInfo pointer, and additionally a GIInfoType if the GITypeTag is GI_TYPE_TAG_INTERFACE. (These pieces of data are the only things used from the GITypeInfo structure.) It's intended for bindings using an argument cache, such as GJS and PyGObject, so that they don't have to store a whole 64-bit GITypeInfo pointer in their cache in many common cases, and can just store the 5-bit type tag instead, or the 5-bit interface type in case of GI_TYPE_TAG_INTERFACE. The original gi_type_info_extract_ffi_return_value() is reimplemented in terms of the new gi_type_tag_extract_ffi_return_value(). --- gicallableinfo.c | 82 +++++++++++++++++++++++++++++++++--------------- girffi.h | 6 ++++ 2 files changed, 62 insertions(+), 26 deletions(-) diff --git a/gicallableinfo.c b/gicallableinfo.c index 16e391f9f..e224ea6ff 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -475,23 +475,31 @@ g_callable_info_iterate_return_attributes (GICallableInfo *info, } /** - * gi_type_info_extract_ffi_return_value: - * @return_info: TODO - * @ffi_value: TODO - * @arg: (out caller-allocates): TODO + * gi_type_tag_extract_ffi_return_value: + * @return_tag: #GITypeTag of the return value + * @interface_type: #GIInfoType of the underlying interface type + * @ffi_value: pointer to #GIFFIReturnValue union containing the return value + * from ffi_call() + * @arg: (out caller-allocates): pointer to an allocated #GIArgument * * Extract the correct bits from an ffi_arg return value into * GIArgument: https://bugzilla.gnome.org/show_bug.cgi?id=665152 * * Also see ffi_call3 * - the storage requirements for return values are "special". + * + * The @interface_type argument only applies if @return_tag is + * %GI_TYPE_TAG_INTERFACE. Otherwise it is ignored. + * + * Since: 1.72 */ void -gi_type_info_extract_ffi_return_value (GITypeInfo *return_info, - GIFFIReturnValue *ffi_value, - GIArgument *arg) +gi_type_tag_extract_ffi_return_value (GITypeTag return_tag, + GIInfoType interface_type, + GIFFIReturnValue *ffi_value, + GIArgument *arg) { - switch (g_type_info_get_tag (return_info)) { + switch (return_tag) { case GI_TYPE_TAG_INT8: arg->v_int8 = (gint8) ffi_value->v_long; break; @@ -525,24 +533,14 @@ gi_type_info_extract_ffi_return_value (GITypeInfo *return_info, arg->v_double = ffi_value->v_double; break; case GI_TYPE_TAG_INTERFACE: - { - GIBaseInfo* interface_info; - GIInfoType interface_type; - - interface_info = g_type_info_get_interface(return_info); - interface_type = g_base_info_get_type(interface_info); - - switch(interface_type) { - case GI_INFO_TYPE_ENUM: - case GI_INFO_TYPE_FLAGS: - arg->v_int32 = (gint32) ffi_value->v_long; - break; - default: - arg->v_pointer = (gpointer) ffi_value->v_pointer; - break; - } - - g_base_info_unref(interface_info); + switch(interface_type) { + case GI_INFO_TYPE_ENUM: + case GI_INFO_TYPE_FLAGS: + arg->v_int32 = (gint32) ffi_value->v_long; + break; + default: + arg->v_pointer = (gpointer) ffi_value->v_pointer; + break; } break; default: @@ -551,6 +549,38 @@ gi_type_info_extract_ffi_return_value (GITypeInfo *return_info, } } +/** + * gi_type_info_extract_ffi_return_value: + * @return_info: #GITypeInfo describing the return type + * @ffi_value: pointer to #GIFFIReturnValue union containing the return value + * from ffi_call() + * @arg: (out caller-allocates): pointer to an allocated #GIArgument + * + * Extract the correct bits from an ffi_arg return value into + * GIArgument: https://bugzilla.gnome.org/show_bug.cgi?id=665152 + * + * Also see ffi_call3 + * - the storage requirements for return values are "special". + */ +void +gi_type_info_extract_ffi_return_value (GITypeInfo *return_info, + GIFFIReturnValue *ffi_value, + GIArgument *arg) +{ + GITypeTag return_tag = g_type_info_get_tag (return_info); + GIInfoType interface_type = GI_INFO_TYPE_INVALID; + + if (return_tag == GI_TYPE_TAG_INTERFACE) + { + GIBaseInfo *interface_info = g_type_info_get_interface (return_info); + interface_type = g_base_info_get_type (interface_info); + g_base_info_unref (interface_info); + } + + return gi_type_tag_extract_ffi_return_value (return_tag, interface_type, + ffi_value, arg); +} + /** * g_callable_info_invoke: * @info: TODO diff --git a/girffi.h b/girffi.h index 2bbc97ac3..349ae57e1 100644 --- a/girffi.h +++ b/girffi.h @@ -75,6 +75,12 @@ void gi_type_info_extract_ffi_return_value (GITypeInfo GIFFIReturnValue *ffi_value, GIArgument *arg); +GI_AVAILABLE_IN_1_72 +void gi_type_tag_extract_ffi_return_value (GITypeTag tag, + GIInfoType interface_type, + GIFFIReturnValue *ffi_value, + GIArgument *arg); + GI_AVAILABLE_IN_ALL gboolean g_function_info_prep_invoker (GIFunctionInfo *info, GIFunctionInvoker *invoker, From edbd878523e89fe0e808921f50eeae99a620a074 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Sun, 13 Feb 2022 14:20:03 +0000 Subject: [PATCH 658/692] Use the proper private triglyph It's `/*< ... >*/`, not `/* <...> */`. --- gibaseinfo.h | 3 +-- girffi.h | 2 +- gitypelib-internal.h | 2 +- gitypes.h | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/gibaseinfo.h b/gibaseinfo.h index f8f7191b3..69dfe4c1e 100644 --- a/gibaseinfo.h +++ b/gibaseinfo.h @@ -40,7 +40,7 @@ G_BEGIN_DECLS * in a #GIBaseInfo struct. */ typedef struct { - /* */ + /*< private >*/ gpointer data; gpointer data2; gpointer data3; @@ -100,4 +100,3 @@ GIBaseInfo * g_info_new (GIInfoType type, G_END_DECLS #endif /* __GIBASEINFO_H__ */ - diff --git a/girffi.h b/girffi.h index 349ae57e1..a75c1213f 100644 --- a/girffi.h +++ b/girffi.h @@ -53,7 +53,7 @@ typedef struct _GIFunctionInvoker GIFunctionInvoker; struct _GIFunctionInvoker { ffi_cif cif; gpointer native_address; - /* */ + /*< private >*/ gpointer padding[3]; }; diff --git a/gitypelib-internal.h b/gitypelib-internal.h index e4104089f..a2835f835 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -1210,7 +1210,7 @@ typedef struct { } AttributeBlob; struct _GITypelib { - /* */ + /*< private >*/ guchar *data; gsize len; gboolean owns_memory; diff --git a/gitypes.h b/gitypes.h index 9c021ff23..69270720a 100644 --- a/gitypes.h +++ b/gitypes.h @@ -32,7 +32,7 @@ G_BEGIN_DECLS typedef struct _GIBaseInfoStub { - /* */ + /*< private >*/ gint32 dummy1; gint32 dummy2; gpointer dummy3; From 2ca3c1da83830113cf9543221bd2325e641dd5f3 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Sun, 13 Feb 2022 14:20:51 +0000 Subject: [PATCH 659/692] docs: Remove DocBook tags We are still using gtk-doc, but gtk-doc uses Markdown these days, not DocBook. --- giarginfo.c | 11 ++----- gibaseinfo.c | 73 +++++++++++++++++++++--------------------- gicallableinfo.c | 43 ++++++++++++------------- giconstantinfo.c | 14 +++----- gienuminfo.c | 18 ++++------- gifieldinfo.c | 21 +++++------- gifunctioninfo.c | 12 +------ giinterfaceinfo.c | 9 ------ giobjectinfo.c | 22 ++++++------- gipropertyinfo.c | 11 ++----- giregisteredtypeinfo.c | 21 +++--------- girepository.c | 11 ++++--- gisignalinfo.c | 17 +++------- gistructinfo.c | 9 ------ gitypeinfo.c | 16 +++------ gitypes.h | 19 ----------- giunioninfo.c | 9 ------ givfuncinfo.c | 15 ++------- 18 files changed, 111 insertions(+), 240 deletions(-) diff --git a/giarginfo.c b/giarginfo.c index 381c38395..96afccb6f 100644 --- a/giarginfo.c +++ b/giarginfo.c @@ -35,16 +35,9 @@ * @title: GIArgInfo * @short_description: Struct representing an argument * - * GIArgInfo represents an argument. An argument is always - * part of a #GICallableInfo. + * GIArgInfo represents an argument of a callable. * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GIArgInfo - * - * + * An argument is always part of a #GICallableInfo. */ /** diff --git a/gibaseinfo.c b/gibaseinfo.c index e47d5390c..d7a3a0171 100644 --- a/gibaseinfo.c +++ b/gibaseinfo.c @@ -185,43 +185,45 @@ _g_type_info_init (GIBaseInfo *info, * @title: GIBaseInfo * @short_description: Base struct for all GITypelib structs * - * GIBaseInfo is the common base struct of all other *Info structs + * GIBaseInfo is the common base struct of all other Info structs * accessible through the #GIRepository API. - * All other structs can be casted to a #GIBaseInfo, for instance: - * - * Casting a #GIFunctionInfo to #GIBaseInfo - * + * + * All info structures can be cast to a #GIBaseInfo, for instance: + * + * |[ * GIFunctionInfo *function_info = ...; - * GIBaseInfo *info = (GIBaseInfo*)function_info; - * - * - * Most #GIRepository APIs returning a #GIBaseInfo is actually creating a new struct, in other - * words, g_base_info_unref() has to be called when done accessing the data. - * GIBaseInfos are normally accessed by calling either - * g_irepository_find_by_name(), g_irepository_find_by_gtype() or g_irepository_get_info(). + * GIBaseInfo *info = (GIBaseInfo *) function_info; + * ]| * - * - * Getting the Button of the Gtk typelib - * - * GIBaseInfo *button_info = g_irepository_find_by_name(NULL, "Gtk", "Button"); - * ... use button_info ... - * g_base_info_unref(button_info); - * - * + * Most #GIRepository APIs returning a #GIBaseInfo is actually + * creating a new struct; in other words, g_base_info_unref() has to + * be called when done accessing the data. * - * - * Struct hierarchy - * + * #GIBaseInfo structuress are normally accessed by calling either + * g_irepository_find_by_name(), g_irepository_find_by_gtype() or + * g_irepository_get_info(). + * + * |[ + * GIBaseInfo *button_info = + * g_irepository_find_by_name (NULL, "Gtk", "Button"); + * + * // ... use button_info ... + * + * g_base_info_unref (button_info); + * ]| + * + * ## Hierarchy + * + * |[ * GIBaseInfo - * +----GIArgInfo - * +----GICallableInfo - * +----GIConstantInfo - * +----GIFieldInfo - * +----GIPropertyInfo - * +----GIRegisteredTypeInfo - * +----GITypeInfo - * - * + * +---- GIArgInfo + * +---- GICallableInfo + * +---- GIConstantInfo + * +---- GIFieldInfo + * +---- GIPropertyInfo + * +---- GIRegisteredTypeInfo + * +---- GITypeInfo + * ]| */ /** @@ -573,9 +575,7 @@ _attribute_blob_find_first (GIBaseInfo *info, * Both the @name and @value should be treated as constants * and must not be freed. * - * - * Iterating over attributes - * + * |[ * void * print_attributes (GIBaseInfo *info) * { @@ -587,8 +587,7 @@ _attribute_blob_find_first (GIBaseInfo *info, * g_print ("attribute name: %s value: %s", name, value); * } * } - * - * + * ]| * * Returns: %TRUE if there are more attributes */ diff --git a/gicallableinfo.c b/gicallableinfo.c index e224ea6ff..790c3d6a4 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -39,22 +39,15 @@ * @short_description: Struct representing a callable * * GICallableInfo represents an entity which is callable. - * Currently a function (#GIFunctionInfo), virtual function, - * (#GIVFuncInfo) or callback (#GICallbackInfo). + * + * Examples of callable are: + * + * - functions (#GIFunctionInfo) + * - virtual functions (#GIVFuncInfo) + * - callbacks (#GICallbackInfo). * * A callable has a list of arguments (#GIArgInfo), a return type, * direction and a flag which decides if it returns null. - * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GICallableInfo - * +----GIFunctionInfo - * +----GISignalInfo - * +----GIVFuncInfo - * - * */ static guint32 @@ -479,14 +472,16 @@ g_callable_info_iterate_return_attributes (GICallableInfo *info, * @return_tag: #GITypeTag of the return value * @interface_type: #GIInfoType of the underlying interface type * @ffi_value: pointer to #GIFFIReturnValue union containing the return value - * from ffi_call() + * from `ffi_call()` * @arg: (out caller-allocates): pointer to an allocated #GIArgument * - * Extract the correct bits from an ffi_arg return value into - * GIArgument: https://bugzilla.gnome.org/show_bug.cgi?id=665152 + * Extract the correct bits from an `ffi_arg` return value into + * GIArgument. * - * Also see ffi_call3 - * - the storage requirements for return values are "special". + * See: https://bugzilla.gnome.org/show_bug.cgi?id=665152 + * + * Also see `ffi_call(3)`: the storage requirements for return values + * are "special". * * The @interface_type argument only applies if @return_tag is * %GI_TYPE_TAG_INTERFACE. Otherwise it is ignored. @@ -553,14 +548,16 @@ gi_type_tag_extract_ffi_return_value (GITypeTag return_tag, * gi_type_info_extract_ffi_return_value: * @return_info: #GITypeInfo describing the return type * @ffi_value: pointer to #GIFFIReturnValue union containing the return value - * from ffi_call() + * from `ffi_call()` * @arg: (out caller-allocates): pointer to an allocated #GIArgument * - * Extract the correct bits from an ffi_arg return value into - * GIArgument: https://bugzilla.gnome.org/show_bug.cgi?id=665152 + * Extract the correct bits from an `ffi_arg` return value into + * #GIArgument. * - * Also see ffi_call3 - * - the storage requirements for return values are "special". + * See: https://bugzilla.gnome.org/show_bug.cgi?id=665152 + * + * Also see `ffi_call(3)`: the storage requirements for return values + * are "special". */ void gi_type_info_extract_ffi_return_value (GITypeInfo *return_info, diff --git a/giconstantinfo.c b/giconstantinfo.c index a9d4cbc02..148d66b61 100644 --- a/giconstantinfo.c +++ b/giconstantinfo.c @@ -34,17 +34,11 @@ * @title: GIConstantInfo * @short_description: Struct representing a constant * - * GIConstantInfo represents a constant. A constant has a type associated - * which can be obtained by calling g_constant_info_get_type() and a value, - * which can be obtained by calling g_constant_info_get_value(). + * GIConstantInfo represents a constant. * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GIConstantInfo - * - * + * A constant has a type associated which can be obtained by calling + * g_constant_info_get_type() and a value, which can be obtained by + * calling g_constant_info_get_value(). */ diff --git a/gienuminfo.c b/gienuminfo.c index 2dc4b167f..c41d0308e 100644 --- a/gienuminfo.c +++ b/gienuminfo.c @@ -33,18 +33,13 @@ * @title: GIEnumInfo * @short_description: Structs representing an enumeration and its values * - * A GIEnumInfo represents an enumeration and a GIValueInfo struct represents a value - * of an enumeration. The GIEnumInfo contains a set of values and a type - * The GIValueInfo is fetched by calling g_enum_info_get_value() on a #GIEnumInfo. + * A GIEnumInfo represents an enumeration, and a GIValueInfo represents + * a value in the enumeration. * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GIRegisteredTypeInfo - * +----GIEnumInfo - * - * + * The GIEnumInfo contains a set of values and a type. + * + * The GIValueInfo is fetched by calling g_enum_info_get_value() on + * a GIEnumInfo. */ /** @@ -235,4 +230,3 @@ g_value_info_get_value (GIValueInfo *info) else return (gint64)blob->value; } - diff --git a/gifieldinfo.c b/gifieldinfo.c index 0a20bdb26..5bc19899b 100644 --- a/gifieldinfo.c +++ b/gifieldinfo.c @@ -34,20 +34,15 @@ * @title: GIFieldInfo * @short_description: Struct representing a struct or union field * - * A GIFieldInfo struct represents a field of a struct (see #GIStructInfo), - * union (see #GIUnionInfo) or an object (see #GIObjectInfo). The GIFieldInfo - * is fetched by calling g_struct_info_get_field(), g_union_info_get_field() - * or g_object_info_get_field(). - * A field has a size, type and a struct offset asssociated and a set of flags, - * which is currently #GI_FIELD_IS_READABLE or #GI_FIELD_IS_WRITABLE. + * A GIFieldInfo struct represents a field of a struct, union, or object. * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GIFieldInfo - * - * + * The GIFieldInfo is fetched by calling g_struct_info_get_field(), + * g_union_info_get_field() or g_object_info_get_field(). + * + * A field has a size, type and a struct offset asssociated and a set of flags, + * which are currently #GI_FIELD_IS_READABLE or #GI_FIELD_IS_WRITABLE. + * + * See also: #GIStructInfo, #GIUnionInfo, #GIObjectInfo */ /** diff --git a/gifunctioninfo.c b/gifunctioninfo.c index b042b4e10..ea6842d5b 100644 --- a/gifunctioninfo.c +++ b/gifunctioninfo.c @@ -36,22 +36,12 @@ * @short_description: Struct representing a function * * GIFunctionInfo represents a function, method or constructor. + * * To find out what kind of entity a #GIFunctionInfo represents, call * g_function_info_get_flags(). * * See also #GICallableInfo for information on how to retreive arguments and * other metadata. - * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GICallableInfo - * +----GIFunctionInfo - * +----GISignalInfo - * +----GIVFuncInfo - * - * */ GIFunctionInfo * diff --git a/giinterfaceinfo.c b/giinterfaceinfo.c index 203113b6e..f0d1d7af0 100644 --- a/giinterfaceinfo.c +++ b/giinterfaceinfo.c @@ -37,15 +37,6 @@ * * A GInterface has methods, fields, properties, signals, interfaces, constants, * virtual functions and prerequisites. - * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GIRegisteredTypeInfo - * +----GIInterfaceInfo - * - * */ /** diff --git a/giobjectinfo.c b/giobjectinfo.c index 2042793a0..82199b843 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -31,22 +31,18 @@ /** * SECTION:giobjectinfo * @title: GIObjectInfo - * @short_description: Struct representing a GObject + * @short_description: Struct representing a classed type * - * GIObjectInfo represents a #GObject. This doesn't represent a specific - * instance of a GObject, instead this represent the object type (eg class). + * GIObjectInfo represents a classed type. * - * A GObject has methods, fields, properties, signals, interfaces, constants - * and virtual functions. + * Classed types in GType inherit from #GTypeInstance; the most common + * type is #GObject. * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GIRegisteredTypeInfo - * +----GIObjectInfo - * - * + * A GIObjectInfo doesn't represent a specific instance of a classed type, + * instead this represent the object type (eg class). + * + * A GIObjectInfo has methods, fields, properties, signals, interfaces, + * constants and virtual functions. */ /** diff --git a/gipropertyinfo.c b/gipropertyinfo.c index 4a291a069..77bb13391 100644 --- a/gipropertyinfo.c +++ b/gipropertyinfo.c @@ -33,16 +33,9 @@ * @title: GIPropertyInfo * @short_description: Struct representing a property * - * GIPropertyInfo represents a property. A property belongs to - * either a #GIObjectInfo or a #GIInterfaceInfo. + * GIPropertyInfo represents a property in a #GObject. * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GIPropertyInfo - * - * + * A property belongs to either a #GIObjectInfo or a #GIInterfaceInfo. */ /** diff --git a/giregisteredtypeinfo.c b/giregisteredtypeinfo.c index 411b9b950..653befec6 100644 --- a/giregisteredtypeinfo.c +++ b/giregisteredtypeinfo.c @@ -35,27 +35,16 @@ * @title: GIRegisteredTypeInfo * @short_description: Struct representing a struct with a GType * - * GIRegisteredTypeInfo represents an entity with a GType associated. Could - * be either a #GIEnumInfo, #GIInterfaceInfo, #GIObjectInfo, #GIStructInfo or a - * #GIUnionInfo. + * GIRegisteredTypeInfo represents an entity with a GType associated. + * + * Could be either a #GIEnumInfo, #GIInterfaceInfo, #GIObjectInfo, + * #GIStructInfo or a #GIUnionInfo. * * A registered type info struct has a name and a type function. + * * To get the name call g_registered_type_info_get_type_name(). * Most users want to call g_registered_type_info_get_g_type() and don't worry * about the rest of the details. - * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GIRegisteredTypeInfo - * +----GIEnumInfo - * +----GIInterfaceInfo - * +----GIObjectInfo - * +----GIStructInfo - * +----GIUnionInfo - * - * */ /** diff --git a/girepository.c b/girepository.c index d7f6ceb4d..a0754f456 100644 --- a/girepository.c +++ b/girepository.c @@ -455,7 +455,7 @@ register_internal (GIRepository *repository, * @namespace_: Namespace of interest * * Return an array of the immediate versioned dependencies for @namespace_. - * Returned strings are of the form namespace-version. + * Returned strings are of the form `namespace-version`. * * Note: @namespace_ must have already been loaded using a function * such as g_irepository_require() before calling this function. @@ -537,9 +537,10 @@ get_typelib_dependencies_transitive (GIRepository *repository, * process-global default #GIRepository * @namespace_: Namespace of interest * - * Return an array of all (transitive) versioned dependencies for - * @namespace_. Returned strings are of the form - * namespace-version. + * Retrieves all (transitive) versioned dependencies for + * @namespace_. + * + * The strings are of the form `namespace-version`. * * Note: @namespace_ must have already been loaded using a function * such as g_irepository_require() before calling this function. @@ -547,7 +548,7 @@ get_typelib_dependencies_transitive (GIRepository *repository, * To get only the immediate dependencies for @namespace_, use * g_irepository_get_immediate_dependencies(). * - * Returns: (transfer full): Zero-terminated string array of all versioned + * Returns: (transfer full) (array zero-terminated=1): all versioned * dependencies */ char ** diff --git a/gisignalinfo.c b/gisignalinfo.c index 5f8fa880c..9d5abec56 100644 --- a/gisignalinfo.c +++ b/gisignalinfo.c @@ -33,22 +33,13 @@ * @title: GISignalInfo * @short_description: Struct representing a signal * - * GISignalInfo represents a signal. It's a sub-struct of #GICallableInfo - * and contains a set of flags and a class closure. + * GISignalInfo represents a signal. + * + * It's a sub-struct of #GICallableInfo and contains a set of flags and + * a class closure. * * See #GICallableInfo for information on how to retreive arguments * and other metadata from the signal. - * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GICallableInfo - * +----GIFunctionInfo - * +----GISignalInfo - * +----GIVFuncInfo - * - * */ /** diff --git a/gistructinfo.c b/gistructinfo.c index a1edfa9f9..a9ad73f6e 100644 --- a/gistructinfo.c +++ b/gistructinfo.c @@ -38,15 +38,6 @@ * GIStructInfo represents a generic C structure type. * * A structure has methods and fields. - * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GIRegisteredTypeInfo - * +----GIStructInfo - * - * */ /** diff --git a/gitypeinfo.c b/gitypeinfo.c index 4fb7dddd2..bdcc1c651 100644 --- a/gitypeinfo.c +++ b/gitypeinfo.c @@ -33,23 +33,17 @@ * @title: GITypeInfo * @short_description: Struct representing a type * - * GITypeInfo represents a type. You can retrieve a type info from - * an argument (see #GIArgInfo), a functions return value (see #GIFunctionInfo), - * a field (see #GIFieldInfo), a property (see #GIPropertyInfo), a constant + * GITypeInfo represents a type. + * + * You can retrieve a type info from an argument (see #GIArgInfo), a + * functions return value (see #GIFunctionInfo), a field (see + * #GIFieldInfo), a property (see #GIPropertyInfo), a constant * (see #GIConstantInfo) or for a union discriminator (see #GIUnionInfo). * * A type can either be a of a basic type which is a standard C primitive * type or an interface type. For interface types you need to call * g_type_info_get_interface() to get a reference to the base info for that * interface. - * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GITypeInfo - * - * */ /** diff --git a/gitypes.h b/gitypes.h index 69270720a..47b5a3eae 100644 --- a/gitypes.h +++ b/gitypes.h @@ -64,17 +64,6 @@ typedef GIBaseInfo GIFunctionInfo; * @short_description: Struct representing a callback * * GICallbackInfo represents a callback. - * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GICallableInfo - * +----GIFunctionInfo - * +----GISignalInfo - * +----GIVFuncInfo - * - * */ /** @@ -139,14 +128,6 @@ typedef GIBaseInfo GIConstantInfo; * @short_description: Struct representing a value * * GIValueInfo represents a value. - * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GIValueInfo - * - * */ /** diff --git a/giunioninfo.c b/giunioninfo.c index 7bc81aa0f..0089f11c2 100644 --- a/giunioninfo.c +++ b/giunioninfo.c @@ -38,15 +38,6 @@ * A union has methods and fields. Unions can optionally have a * discriminator, which is a field deciding what type of real union * fields is valid for specified instance. - * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GIRegisteredTypeInfo - * +----GIUnionInfo - * - * */ /** diff --git a/givfuncinfo.c b/givfuncinfo.c index 13ab654d3..5c3997c5e 100644 --- a/givfuncinfo.c +++ b/givfuncinfo.c @@ -35,19 +35,10 @@ * @title: GIVFuncInfo * @short_description: Struct representing a virtual function * - * GIVfuncInfo represents a virtual function. A property belongs to - * either a #GIObjectInfo or a #GIInterfaceInfo. + * GIVfuncInfo represents a virtual function. * - * - * Struct hierarchy - * - * GIBaseInfo - * +----GICallableInfo - * +----GIFunctionInfo - * +----GISignalInfo - * +----GIVFuncInfo - * - * + * A virtual function is a callable object that belongs to either a + * #GIObjectInfo or a #GIInterfaceInfo. */ GIVFuncInfo * From 822d284221d5d9e9e4be6c05fc201cafcf5e1cc7 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Sun, 13 Feb 2022 14:27:09 +0000 Subject: [PATCH 660/692] docs: Reformat a long description --- gitypelib-internal.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gitypelib-internal.h b/gitypelib-internal.h index a2835f835..09af067e6 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -37,6 +37,7 @@ G_BEGIN_DECLS * * The "typelib" is a binary, readonly, memory-mappable database * containing reflective information about a GObject library. + * * What the typelib describes and the types used are the same for every * platform so, apart the endianness of its scalar values, the typelib * database must be considered architecture-independent. @@ -45,6 +46,7 @@ G_BEGIN_DECLS * format. * * Some of the differences to XPCOM include: + * * - Type information is stored not quite as compactly (XPCOM stores it inline * in function descriptions in variable-sized blobs of 1 to n bytes. We store * 16 bits of type information for each parameter, which is enough to encode @@ -57,6 +59,7 @@ G_BEGIN_DECLS * * The typelib has the following general format: * + * |[ * typelib ::= header, section-index, directory, blobs, attributes, attributedata * * directory ::= list of entries @@ -65,6 +68,7 @@ G_BEGIN_DECLS * blob ::= function|callback|struct|boxed|enum|flags|object|interface|constant|union * attribute ::= offset, key, value * attributedata ::= string data for attributes + * ]| * * Details * From f7b01419065a27e1916437b48eb5d403e0c63505 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Sun, 13 Feb 2022 14:27:30 +0000 Subject: [PATCH 661/692] docs: Rename a field annotation --- gitypelib-internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 09af067e6..77c4d6f37 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -1050,7 +1050,7 @@ typedef struct { * @abstract: whether the type can be instantiated * @fundamental: this object is not a GObject derived type, instead it's * an additional fundamental type. - * @final: whether the type can be derived + * @final_: whether the type can be derived * @reserved: Reserved for future use. * @name: TODO * @gtype_name: String name of the associated #GType From 13f09c5594f19b9c5c3b0a86888b63da76c185d3 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Sun, 13 Feb 2022 14:33:10 +0000 Subject: [PATCH 662/692] Add GI_TYPE_TAG_IS_BASIC And deprecate G_TYPE_TAG_IS_BASIC. Let's avoid hijacking the G namespace any further. --- gitypeinfo.h | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/gitypeinfo.h b/gitypeinfo.h index a8674fd9b..39912ae7e 100644 --- a/gitypeinfo.h +++ b/gitypeinfo.h @@ -45,8 +45,40 @@ G_BEGIN_DECLS * @tag: a type tag * * Checks if @tag is a basic type. + * + * Deprecated: 1.72: Use GI_TYPE_TAG_IS_BASIC() instead */ -#define G_TYPE_TAG_IS_BASIC(tag) (tag < GI_TYPE_TAG_ARRAY || tag == GI_TYPE_TAG_UNICHAR) +#define G_TYPE_TAG_IS_BASIC(tag) GI_TYPE_TAG_IS_BASIC(tag) + +/** + * GI_TYPE_TAG_IS_BASIC + * @tag: a type tag + * + * Checks if @tag is a basic type. + * + * Since: 1.72 + */ +#define GI_TYPE_TAG_IS_BASIC(tag) ((tag) < GI_TYPE_TAG_ARRAY || (tag) == GI_TYPE_TAG_UNICHAR) + +/** + * GI_TYPE_TAG_IS_NUMERIC: + * @tag: a type tag + * + * Checks if @tag is a numeric type. That is, integer or floating point. + * + * Since: 1.72 + */ +#define GI_TYPE_TAG_IS_NUMERIC(tag) ((tag) >= GI_TYPE_TAG_INT8 && (tag) <= GI_TYPE_TAG_DOUBLE) + +/** + * GI_TYPE_TAG_IS_NUMERIC: + * @tag: a type tag + * + * Checks if @tag is a numeric type. That is, integer or floating point. + * + * Since: 1.72 + */ +#define GI_TYPE_TAG_IS_NUMERIC(tag) ((tag) >= GI_TYPE_TAG_INT8 && (tag) <= GI_TYPE_TAG_DOUBLE) /** * GI_TYPE_TAG_IS_NUMERIC: From f4a7efaa2ebf2ea4886c9e0e5f1328ed11f6c8bc Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Sun, 13 Feb 2022 14:35:53 +0000 Subject: [PATCH 663/692] Use GI_TYPE_TAG_IS_BASIC Now that we have it. --- girnode.c | 6 +++--- girwriter.c | 2 +- gitypelib.c | 2 +- gitypes.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/girnode.c b/girnode.c index 4db679d8d..34b7dea81 100644 --- a/girnode.c +++ b/girnode.c @@ -632,7 +632,7 @@ _g_ir_node_get_full_size_internal (GIrNode *parent, { GIrNodeType *type = (GIrNodeType *)node; size = sizeof (SimpleTypeBlob); - if (!G_TYPE_TAG_IS_BASIC(type->tag)) + if (!GI_TYPE_TAG_IS_BASIC (type->tag)) { g_debug ("node %p type tag '%s'", node, g_type_tag_to_string (type->tag)); @@ -1208,7 +1208,7 @@ serialize_type (GIrTypelibBuild *build, { gint i; - if (G_TYPE_TAG_IS_BASIC(node->tag)) + if (GI_TYPE_TAG_IS_BASIC (node->tag)) { g_string_append_printf (str, "%s%s", g_type_tag_to_string (node->tag), node->is_pointer ? "*" : ""); @@ -1430,7 +1430,7 @@ _g_ir_node_build_typelib (GIrNode *node, *offset += sizeof (SimpleTypeBlob); - if (G_TYPE_TAG_IS_BASIC (type->tag)) + if (GI_TYPE_TAG_IS_BASIC (type->tag)) { blob->flags.reserved = 0; blob->flags.reserved2 = 0; diff --git a/girwriter.c b/girwriter.c index 44e18801f..ea148f320 100644 --- a/girwriter.c +++ b/girwriter.c @@ -231,7 +231,7 @@ write_type_info (const gchar *namespace, xml_end_element (file, "type"); } - else if (G_TYPE_TAG_IS_BASIC (tag)) + else if (GI_TYPE_TAG_IS_BASIC (tag)) { xml_start_element (file, "type"); xml_printf (file, " name=\"%s\"", g_type_tag_to_string (tag)); diff --git a/gitypelib.c b/gitypelib.c index d5ef45064..29349da33 100644 --- a/gitypelib.c +++ b/gitypelib.c @@ -792,7 +792,7 @@ validate_type_blob (GITypelib *typelib, if (simple->flags.reserved == 0 && simple->flags.reserved2 == 0) { - if (!G_TYPE_TAG_IS_BASIC(simple->flags.tag)) + if (!GI_TYPE_TAG_IS_BASIC(simple->flags.tag)) { g_set_error (error, G_TYPELIB_ERROR, diff --git a/gitypes.h b/gitypes.h index 47b5a3eae..9a9cb1e18 100644 --- a/gitypes.h +++ b/gitypes.h @@ -405,7 +405,7 @@ typedef enum { GI_TYPE_TAG_GTYPE = 12, GI_TYPE_TAG_UTF8 = 13, GI_TYPE_TAG_FILENAME = 14, - /* Non-basic types; compare with G_TYPE_TAG_IS_BASIC */ + /* Non-basic types; compare with GI_TYPE_TAG_IS_BASIC */ GI_TYPE_TAG_ARRAY = 15, /* container (see GI_TYPE_TAG_IS_CONTAINER) */ GI_TYPE_TAG_INTERFACE = 16, GI_TYPE_TAG_GLIST = 17, /* container */ From 4dbd25b033faa8ce30f9627e955e8b98c35d705b Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Sun, 13 Feb 2022 14:41:48 +0000 Subject: [PATCH 664/692] Rename argument in the declation It must match the argument in the definition and the documentation. --- girffi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/girffi.h b/girffi.h index a75c1213f..dbe4c1ecb 100644 --- a/girffi.h +++ b/girffi.h @@ -76,7 +76,7 @@ void gi_type_info_extract_ffi_return_value (GITypeInfo GIArgument *arg); GI_AVAILABLE_IN_1_72 -void gi_type_tag_extract_ffi_return_value (GITypeTag tag, +void gi_type_tag_extract_ffi_return_value (GITypeTag return_tag, GIInfoType interface_type, GIFFIReturnValue *ffi_value, GIArgument *arg); From 62bbd6cf172733a1b30eeda1f3d4035fd70ec64b Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Fri, 2 Apr 2021 11:42:09 +0800 Subject: [PATCH 665/692] brz.c: Avoid C4715 warnings Later GLib versions assume that warning C4715 is an error as we want ot be sure that functions that return a value do indeed return one by all means. Avoid this warning by adding a 'return 0' in brz_search_packed(), it might be pointless but does indeed avoid the warning. --- cmph/brz.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmph/brz.c b/cmph/brz.c index cd35c8d8e..2fff05bf5 100644 --- a/cmph/brz.c +++ b/cmph/brz.c @@ -1028,7 +1028,9 @@ cmph_uint32 brz_search_packed(void *packed_mphf, const char *key, cmph_uint32 ke return brz_fch_search_packed(ptr, key, keylen, fingerprint); case CMPH_BMZ8: return brz_bmz8_search_packed(ptr, key, keylen, fingerprint); - default: assert(0); + default: + assert(0); + return 0; /* To avoid warnings that value must be returned */ } } From c138becc4dddf8af6e3629736ee2da7d850e7f40 Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Fri, 2 Apr 2021 12:34:17 +0800 Subject: [PATCH 666/692] brz.c: Consider _WIN64 for 64-bit pointers too The __ia64 and __x86_64__ macros are defined for GCC but not Visual Studio, but actually this code path should also be taken for Visual Studio when doing a 64-bit build (x86_64/x64 and aarch64/arm64, _WIN64 will be defined for these cases), since Windows is an LLP64 platform. This will avoid C4311/C4312 warnings on Visual Studio builds, which are often warnings of concern as we are dealing with pointers with differing sizes on 32-bit and 64-bit Windows builds. --- cmph/brz.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/cmph/brz.c b/cmph/brz.c index 2fff05bf5..25feb6536 100644 --- a/cmph/brz.c +++ b/cmph/brz.c @@ -20,6 +20,10 @@ //#define DEBUG #include "debug.h" +#if defined (__ia64) || defined (__x86_64__) || defined (_WIN64) +# define __brz_use_64bit__ +#endif + static int brz_gen_mphf(cmph_config_t *mph); static cmph_uint32 brz_min_index(cmph_uint32 * vector, cmph_uint32 n); static void brz_destroy_keys_vd(cmph_uint8 ** keys_vd, cmph_uint32 nkeys); @@ -751,7 +755,7 @@ void brz_pack(cmph_t *mphf, void *packed_mphf) cmph_uint8 * ptr = packed_mphf; cmph_uint32 i,n; CMPH_HASH h0_type, h1_type, h2_type; -#if defined (__ia64) || defined (__x86_64__) +#ifdef __brz_use_64bit__ cmph_uint64 * g_is_ptr; #else cmph_uint32 * g_is_ptr; @@ -797,7 +801,7 @@ void brz_pack(cmph_t *mphf, void *packed_mphf) memcpy(ptr, data->offset, sizeof(cmph_uint32)*data->k); ptr += sizeof(cmph_uint32)*data->k; - #if defined (__ia64) || defined (__x86_64__) + #ifdef __brz_use_64bit__ g_is_ptr = (cmph_uint64 *)ptr; #else g_is_ptr = (cmph_uint32 *)ptr; @@ -807,7 +811,7 @@ void brz_pack(cmph_t *mphf, void *packed_mphf) for(i = 0; i < data->k; i++) { - #if defined (__ia64) || defined (__x86_64__) + #ifdef __brz_use_64bit__ *g_is_ptr++ = (cmph_uint64)g_i; #else *g_is_ptr++ = (cmph_uint32)g_i; @@ -855,7 +859,7 @@ cmph_uint32 brz_packed_size(cmph_t *mphf) size = (cmph_uint32)(2*sizeof(CMPH_ALGO) + 3*sizeof(CMPH_HASH) + hash_state_packed_size(h0_type) + sizeof(cmph_uint32) + sizeof(double) + sizeof(cmph_uint8)*data->k + sizeof(cmph_uint32)*data->k); // pointers to g_is - #if defined (__ia64) || defined (__x86_64__) + #ifdef __brz_use_64bit__ size += (cmph_uint32) sizeof(cmph_uint64)*data->k; #else size += (cmph_uint32) sizeof(cmph_uint32)*data->k; @@ -893,7 +897,7 @@ static cmph_uint32 brz_bmz8_search_packed(cmph_uint32 *packed_mphf, const char * register double c; register CMPH_HASH h1_type, h2_type; register cmph_uint8 * size; -#if defined (__ia64) || defined (__x86_64__) +#ifdef __brz_use_64bit__ register cmph_uint64 * g_is_ptr; #else register cmph_uint32 * g_is_ptr; @@ -925,7 +929,7 @@ static cmph_uint32 brz_bmz8_search_packed(cmph_uint32 *packed_mphf, const char * m = size[h0]; n = (cmph_uint32)ceil(c * m); - #if defined (__ia64) || defined (__x86_64__) + #ifdef __brz_use_64bit__ g_is_ptr = (cmph_uint64 *)packed_mphf; #else g_is_ptr = packed_mphf; @@ -957,7 +961,7 @@ static cmph_uint32 brz_fch_search_packed(cmph_uint32 *packed_mphf, const char *k register CMPH_HASH h1_type, h2_type; register cmph_uint8 *size, *h1_ptr, *h2_ptr, *g; register cmph_uint32 *offset; -#if defined (__ia64) || defined (__x86_64__) +#ifdef __brz_use_64bit__ register cmph_uint64 * g_is_ptr; #else register cmph_uint32 * g_is_ptr; @@ -989,7 +993,7 @@ static cmph_uint32 brz_fch_search_packed(cmph_uint32 *packed_mphf, const char *k p1 = fch_calc_p1(m); p2 = fch_calc_p2(b); - #if defined (__ia64) || defined (__x86_64__) + #ifdef __brz_use_64bit__ g_is_ptr = (cmph_uint64 *)packed_mphf; #else g_is_ptr = packed_mphf; From 0cccf62cea2de8179226b6e6361c6f8831582de6 Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Fri, 2 Apr 2021 12:37:47 +0800 Subject: [PATCH 667/692] bdz.c: Some cleanups We can just update the for loop condition to be >0 for all builds, which is actually equivilant to >=1 as we are essentially comparing an unsigned 32-bit int, so that we don't need to worry about fixing the VS2012 bug invasively, as Visual Studio 2012 x64 is more sensitive about sizes of variables (e.g. pointer sizes in this case) --- cmph/bdz.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/cmph/bdz.c b/cmph/bdz.c index 34898ad54..e70f1183e 100644 --- a/cmph/bdz.c +++ b/cmph/bdz.c @@ -423,7 +423,7 @@ static void assigning(bdz_config_data_t *bdz, bdz_graph3_t* graph3, bdz_queue_t memset(marked_vertices, 0, (size_t)(bdz->n >> 3) + 1); memset(bdz->g, 0xff, (size_t)(sizeg)); - for(i=nedges-1;i+1>=1;i--){ + for(i=nedges-1;i+1>0;i--){ curr_edge=queue[i]; v0=graph3->edges[curr_edge].vertices[0]; v1=graph3->edges[curr_edge].vertices[1]; @@ -455,14 +455,6 @@ static void assigning(bdz_config_data_t *bdz, bdz_graph3_t* graph3, bdz_queue_t SETBIT(marked_vertices, v2); } DEBUGP("A:%u %u %u -- %u %u %u\n", v0, v1, v2, GETVALUE(bdz->g, v0), GETVALUE(bdz->g, v1), GETVALUE(bdz->g, v2)); - -#if (_MSC_VER > 1699 && _MSC_VER < 1800) - /* This is bad, MSVC 2012 X64 getting confused with the value of i... */ - /* an obvious MSVC 2012 X64 compiler bug :| */ - if (i <= 0) - break; -#endif - }; free(marked_vertices); } From 3556c864ede86fcc6dfe6e934686824502b7c34e Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Wed, 16 Feb 2022 10:37:39 -0800 Subject: [PATCH 668/692] gitypeinfo: Add pointer-stuffing functions for GITypeTag storage type This adds gi_type_tag_argument_from_hash_pointer() and gi_type_tag_hash_pointer_from_argument(). They do the same thing as the corresponding g_type_info_... functions, which are used to pack and unpack the correct field of a GIArgument into/from a data pointer in GHashTable or GList, regardless of machine architecture or endianness. These functions take a GITypeTag obtained from g_type_info_get_storage_type(), instead of a GITypeInfo pointer. (The storage type is the only piece of data that is actually used from the GITypeInfo structure.) It's intended for bindings using an argument cache, such as GJS and PyGObject, so that they don't have to store a whole 64-bit GITypeInfo pointer in their cache in many common cases, and can just store the 5-bit type tag instead. The original g_type_info_... functions are reimplemented in terms of the new g_type_tag... functions. --- gitypeinfo.c | 95 +++++++++++++++++++++++++++++++++++++++++----------- gitypeinfo.h | 9 +++++ 2 files changed, 84 insertions(+), 20 deletions(-) diff --git a/gitypeinfo.c b/gitypeinfo.c index bdcc1c651..6aa10e058 100644 --- a/gitypeinfo.c +++ b/gitypeinfo.c @@ -372,8 +372,8 @@ g_type_info_get_storage_type (GITypeInfo *info) } /** - * g_type_info_argument_from_hash_pointer: - * @info: a #GITypeInfo + * gi_type_tag_argument_from_hash_pointer: + * @storage_type: a #GITypeTag obtained from g_type_info_get_storage_type() * @hash_pointer: A pointer, such as a #GHashTable data pointer * @arg: A #GIArgument to fill in * @@ -387,18 +387,16 @@ g_type_info_get_storage_type (GITypeInfo *info) * stuffed pointers, regardless of the machine's architecture or endianness. * * This function fills in the appropriate field of @arg with the value extracted - * from @hash_pointer, depending on the storage type of @info. + * from @hash_pointer, depending on @storage_type. * - * Since: 1.66 + * Since: 1.72 */ void -g_type_info_argument_from_hash_pointer (GITypeInfo *info, - gpointer hash_pointer, +gi_type_tag_argument_from_hash_pointer (GITypeTag storage_type, + gpointer hash_pointer, GIArgument *arg) { - GITypeTag type_tag = g_type_info_get_storage_type (info); - - switch (type_tag) + switch (storage_type) { case GI_TYPE_TAG_BOOLEAN: arg->v_boolean = !!GPOINTER_TO_INT (hash_pointer); @@ -440,15 +438,45 @@ g_type_info_argument_from_hash_pointer (GITypeInfo *info, case GI_TYPE_TAG_FLOAT: case GI_TYPE_TAG_DOUBLE: default: - g_critical ("Unsupported type for pointer-stuffing: %s", - g_type_tag_to_string (type_tag)); + g_critical ("Unsupported storage type for pointer-stuffing: %s", + g_type_tag_to_string (storage_type)); arg->v_pointer = hash_pointer; } } /** - * g_type_info_hash_pointer_from_argument: + * g_type_info_argument_from_hash_pointer: * @info: a #GITypeInfo + * @hash_pointer: A pointer, such as a #GHashTable data pointer + * @arg: A #GIArgument to fill in + * + * GLib data structures, such as #GList, #GSList, and #GHashTable, all store + * data pointers. + * In the case where the list or hash table is storing single types rather than + * structs, these data pointers may have values stuffed into them via macros + * such as %GPOINTER_TO_INT. + * + * Use this function to ensure that all values are correctly extracted from + * stuffed pointers, regardless of the machine's architecture or endianness. + * + * This function fills in the appropriate field of @arg with the value extracted + * from @hash_pointer, depending on the storage type of @info. + * + * Since: 1.66 + */ +void +g_type_info_argument_from_hash_pointer (GITypeInfo *info, + gpointer hash_pointer, + GIArgument *arg) +{ + GITypeTag storage_type = g_type_info_get_storage_type (info); + return gi_type_tag_argument_from_hash_pointer (storage_type, hash_pointer, + arg); +} + +/** + * gi_type_tag_hash_pointer_from_argument: + * @storage_type: a #GITypeTag obtained from g_type_info_get_storage_type() * @arg: A #GIArgument with the value to stuff into a pointer * * GLib data structures, such as #GList, #GSList, and #GHashTable, all store @@ -461,19 +489,17 @@ g_type_info_argument_from_hash_pointer (GITypeInfo *info, * pointers, regardless of the machine's architecture or endianness. * * This function returns a pointer stuffed with the appropriate field of @arg, - * depending on the storage type of @info. + * depending on @storage_type. * * Returns: A stuffed pointer, that can be stored in a #GHashTable, for example * - * Since: 1.66 + * Since: 1.72 */ gpointer -g_type_info_hash_pointer_from_argument (GITypeInfo *info, +gi_type_tag_hash_pointer_from_argument (GITypeTag storage_type, GIArgument *arg) { - GITypeTag type_tag = g_type_info_get_storage_type (info); - - switch (type_tag) + switch (storage_type) { case GI_TYPE_TAG_BOOLEAN: return GINT_TO_POINTER (arg->v_boolean); @@ -506,8 +532,37 @@ g_type_info_hash_pointer_from_argument (GITypeInfo *info, case GI_TYPE_TAG_FLOAT: case GI_TYPE_TAG_DOUBLE: default: - g_critical ("Unsupported type for pointer-stuffing: %s", - g_type_tag_to_string (type_tag)); + g_critical ("Unsupported storage type for pointer-stuffing: %s", + g_type_tag_to_string (storage_type)); return arg->v_pointer; } } + +/** + * g_type_info_hash_pointer_from_argument: + * @info: a #GITypeInfo + * @arg: A #GIArgument with the value to stuff into a pointer + * + * GLib data structures, such as #GList, #GSList, and #GHashTable, all store + * data pointers. + * In the case where the list or hash table is storing single types rather than + * structs, these data pointers may have values stuffed into them via macros + * such as %GPOINTER_TO_INT. + * + * Use this function to ensure that all values are correctly stuffed into + * pointers, regardless of the machine's architecture or endianness. + * + * This function returns a pointer stuffed with the appropriate field of @arg, + * depending on the storage type of @info. + * + * Returns: A stuffed pointer, that can be stored in a #GHashTable, for example + * + * Since: 1.66 + */ +gpointer +g_type_info_hash_pointer_from_argument (GITypeInfo *info, + GIArgument *arg) +{ + GITypeTag storage_type = g_type_info_get_storage_type (info); + return gi_type_tag_hash_pointer_from_argument (storage_type, arg); +} diff --git a/gitypeinfo.h b/gitypeinfo.h index 39912ae7e..283658ef3 100644 --- a/gitypeinfo.h +++ b/gitypeinfo.h @@ -146,6 +146,15 @@ GI_AVAILABLE_IN_1_66 gpointer g_type_info_hash_pointer_from_argument (GITypeInfo *info, GIArgument *arg); +GI_AVAILABLE_IN_1_72 +void gi_type_tag_argument_from_hash_pointer (GITypeTag storage_type, + gpointer hash_pointer, + GIArgument *arg); + +GI_AVAILABLE_IN_1_72 +gpointer gi_type_tag_hash_pointer_from_argument (GITypeTag storage_type, + GIArgument *arg); + G_END_DECLS From a068c6c3031cbda8964e11829d9e0252e8135d43 Mon Sep 17 00:00:00 2001 From: Chun-wei Fan Date: Thu, 10 Mar 2022 18:11:05 +0800 Subject: [PATCH 669/692] gi[callable|type]info.c: Avoid MSVC C4098 warnings We attempted to return a value in void-return-type functions in both gicallableinfo.c and gitypeinfo.c, so avoid that since that will trigger a C4098 warning on Visual Studio, which is considered an error if we are building against an installed version of GLib 2.68.x or later. This will fix builds against GLib-2.68.x and later on Visual Studio. --- gicallableinfo.c | 4 ++-- gitypeinfo.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gicallableinfo.c b/gicallableinfo.c index 790c3d6a4..8b9fb3da2 100644 --- a/gicallableinfo.c +++ b/gicallableinfo.c @@ -574,8 +574,8 @@ gi_type_info_extract_ffi_return_value (GITypeInfo *return_info, g_base_info_unref (interface_info); } - return gi_type_tag_extract_ffi_return_value (return_tag, interface_type, - ffi_value, arg); + gi_type_tag_extract_ffi_return_value (return_tag, interface_type, + ffi_value, arg); } /** diff --git a/gitypeinfo.c b/gitypeinfo.c index 6aa10e058..f3c596583 100644 --- a/gitypeinfo.c +++ b/gitypeinfo.c @@ -470,8 +470,8 @@ g_type_info_argument_from_hash_pointer (GITypeInfo *info, GIArgument *arg) { GITypeTag storage_type = g_type_info_get_storage_type (info); - return gi_type_tag_argument_from_hash_pointer (storage_type, hash_pointer, - arg); + gi_type_tag_argument_from_hash_pointer (storage_type, hash_pointer, + arg); } /** From ac01cf93f42d7dbcc25faade136bfa3327333cf5 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Tue, 19 Jul 2022 18:03:59 +0200 Subject: [PATCH 670/692] build: disable some clang warnings for code not under our control cmph is vendored and other one is bison/flex generated code. Not much we can do here, so disable those warnings there. --- cmph/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/cmph/meson.build b/cmph/meson.build index 2a0cef7e4..157b09e96 100644 --- a/cmph/meson.build +++ b/cmph/meson.build @@ -43,6 +43,7 @@ if cc.get_id() != 'msvc' '-Wno-cast-align', '-Wno-unused-function', '-Wno-return-type', + '-Wno-sometimes-uninitialized', ]) endif From f7cc968eb99b7ec5358aa35dc4ac499df052453f Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Sat, 6 Aug 2022 13:52:01 -0700 Subject: [PATCH 671/692] docs: Remove inaccurate description This parameter may not be NULL even if the function described by the GIFunctionInfo has a void return type, so we should not say this in the documentation. --- gifunctioninfo.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gifunctioninfo.c b/gifunctioninfo.c index ea6842d5b..8b38bd5e0 100644 --- a/gifunctioninfo.c +++ b/gifunctioninfo.c @@ -237,8 +237,7 @@ g_invoke_error_quark (void) * may be %NULL * @n_out_args: the length of the @out_args array * @return_value: return location for the return value of the - * function. If the function returns void, @return_value may be - * %NULL + * function. * @error: return location for detailed error information, or %NULL * * Invokes the function described in @info with the given From 8742fb6c9952dd182180bba44358e0cea27ed96b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 6 Oct 2022 03:52:17 +0200 Subject: [PATCH 672/692] cmph: Do not set debug variables if debug is not set Fixes clang builds --- cmph/chd_ph.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmph/chd_ph.c b/cmph/chd_ph.c index 8356bded9..ae986b425 100644 --- a/cmph/chd_ph.c +++ b/cmph/chd_ph.c @@ -579,7 +579,7 @@ static inline cmph_uint8 chd_ph_check_bin_hashing(chd_ph_config_data_t *chd_ph, { register cmph_uint32 bucket_size, i, j; register cmph_uint32 position, probe0_num, probe1_num; - register cmph_uint32 m = 0; + G_GNUC_UNUSED register cmph_uint32 m = 0; register chd_ph_item_t * item; if(chd_ph->keys_per_bin > 1) memset(chd_ph->occup_table, 0, chd_ph->n); @@ -596,7 +596,9 @@ static inline cmph_uint8 chd_ph_check_bin_hashing(chd_ph_config_data_t *chd_ph, probe1_num = disp_table[buckets[i].bucket_id] / chd_ph->n; for(; j > 0; j--) { +#ifdef DEBUG m++; +#endif position = (cmph_uint32)((item->f + ((cmph_uint64 )item->h) * probe0_num + probe1_num) % chd_ph->n); if(chd_ph->keys_per_bin > 1) { From 7e8a8bfb14d7f4280261346b333af672d5fa916c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 6 Oct 2022 04:04:51 +0200 Subject: [PATCH 673/692] Add missing (void) arguments to comply with -Wstrict-prototypes --- cmph/fch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmph/fch.c b/cmph/fch.c index 33b959e24..f12b6fcd2 100644 --- a/cmph/fch.c +++ b/cmph/fch.c @@ -21,7 +21,7 @@ static cmph_uint8 check_for_collisions_h2(fch_config_data_t *fch, fch_buckets_t static void permut(cmph_uint32 * vector, cmph_uint32 n); static cmph_uint8 searching(fch_config_data_t *fch, fch_buckets_t *buckets, cmph_uint32 *sorted_indexes); -fch_config_data_t *fch_config_new() +fch_config_data_t *fch_config_new(void) { fch_config_data_t *fch; fch = (fch_config_data_t *)malloc(sizeof(fch_config_data_t)); From 30636153136adb2431dcdbb21fccb3af739a44e5 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Tue, 30 Aug 2022 23:43:51 +0100 Subject: [PATCH 674/692] Dump the default value of object properties We use g_param_spec_get_default_value() to get the default GValue of a GParamSpec, and then we serialize it into a string according to the value's own contents and type. --- gdump.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/gdump.c b/gdump.c index e79f17192..3ee687b6c 100644 --- a/gdump.c +++ b/gdump.c @@ -119,6 +119,40 @@ invoke_error_quark (GModule *self, const char *symbol, GError **error) return sym (); } +/* A simpler version of g_strdup_value_contents(), but with stable + * output and less complex semantics + */ +static char * +value_to_string (const GValue *value) +{ + if (G_VALUE_HOLDS_STRING (value)) + { + const char *s = g_value_get_string (value); + + if (s == NULL) + return g_strdup ("NULL"); + + return g_strescape (s, NULL); + } + else if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING)) + { + GValue tmp = G_VALUE_INIT; + char *s; + + g_value_init (&tmp, G_TYPE_STRING); + g_value_transform (value, &tmp); + s = g_strescape (g_value_get_string (&tmp), NULL); + g_value_unset (&tmp); + + if (s == NULL) + return g_strdup ("NULL"); + + return s; + } + else + return g_strdup ("NULL"); +} + static void dump_properties (GType type, GOutputStream *out) { @@ -147,9 +181,18 @@ dump_properties (GType type, GOutputStream *out) if (prop->owner_type != type) continue; - escaped_printf (out, " \n", - prop->name, g_type_name (prop->value_type), prop->flags); + const GValue *v = g_param_spec_get_default_value (prop); + char *default_value = value_to_string (v); + + escaped_printf (out, " \n", + prop->name, + g_type_name (prop->value_type), + prop->flags, + default_value); + + g_free (default_value); } + g_free (props); } From 967f993108b690ba2447d353108c481d1834f037 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Sun, 8 Jan 2023 14:20:06 +0000 Subject: [PATCH 675/692] Skip default-value for non-transformable properties If we can't transform a property default value to string, we are not going to add a default-value attribute to the GIR. This is necessary because non-transformable values may not always be pointers, so we cannot default to "NULL". --- gdump.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/gdump.c b/gdump.c index 3ee687b6c..e68c4d14a 100644 --- a/gdump.c +++ b/gdump.c @@ -137,20 +137,22 @@ value_to_string (const GValue *value) else if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING)) { GValue tmp = G_VALUE_INIT; - char *s; + char *s = NULL; g_value_init (&tmp, G_TYPE_STRING); - g_value_transform (value, &tmp); - s = g_strescape (g_value_get_string (&tmp), NULL); + + if (g_value_transform (value, &tmp)) + s = g_strescape (g_value_get_string (&tmp), NULL); + g_value_unset (&tmp); if (s == NULL) - return g_strdup ("NULL"); + return NULL; return s; } else - return g_strdup ("NULL"); + return NULL; } static void @@ -184,11 +186,21 @@ dump_properties (GType type, GOutputStream *out) const GValue *v = g_param_spec_get_default_value (prop); char *default_value = value_to_string (v); - escaped_printf (out, " \n", - prop->name, - g_type_name (prop->value_type), - prop->flags, - default_value); + if (default_value != NULL) + { + escaped_printf (out, " \n", + prop->name, + g_type_name (prop->value_type), + prop->flags, + default_value); + } + else + { + escaped_printf (out, " \n", + prop->name, + g_type_name (prop->value_type), + prop->flags); + } g_free (default_value); } From 47b674d30f432473d04c6bc687b643bd1fd44e5a Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Sat, 29 Oct 2022 18:08:15 +0100 Subject: [PATCH 676/692] Open g-i 1.75 development --- giversionmacros.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/giversionmacros.h b/giversionmacros.h index 67bb6c102..1a7e11ddb 100644 --- a/giversionmacros.h +++ b/giversionmacros.h @@ -195,4 +195,18 @@ # define GI_AVAILABLE_IN_1_72 _GI_EXTERN #endif +#if defined(GLIB_VERSION_2_76) && GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_76 +# define GI_DEPRECATED_IN_1_76 GI_DEPRECATED +# define GI_DEPRECATED_IN_1_76_FOR(f) GI_DEPRECATED_FOR(f) +#else +# define GI_DEPRECATED_IN_1_76 _GI_EXTERN +# define GI_DEPRECATED_IN_1_76_FOR(f) _GI_EXTERN +#endif + +#if defined(GLIB_VERSION_2_76) && GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_76 +# define GI_AVAILABLE_IN_1_76 GI_UNAVAILABLE(2, 76) +#else +# define GI_AVAILABLE_IN_1_76 _GI_EXTERN +#endif + #endif /* __GIVERSIONMACROS_H__ */ From 605fdf70467db932c572fe679cdcacc97a790d32 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Sat, 29 Oct 2022 18:09:23 +0100 Subject: [PATCH 677/692] Add copy and free function annotations for POD types Plain Old Data (POD) types with or without a representation in the GType type system can still have a copy and/or a free function. We should allow annotating these types with their corresponding functions for copying their data into a new instance, and freeing their data. From a language bindings perspective, POD types should have a boxed GType wrapper around them, so they can use the generic GBoxed API to copy and free instances; from a documentation perspective, though, it'd be good to have a way to match a structured type, like a struct or a union, with its copy and free functions. In order to do that, we add two new header block annotations: - (copy-func function_name) - (free-func function_name) These annotations work exactly like ref-func and unref-func for typed instances: /** * GdkRGBA: (copy-func gdk_rgba_copy) * (free-func gdk_rgba_free) * @red: ... * @green: ... * @blue: ... * @alpha: ... * * ... */ The function is stored in the GIR data as two new attributes for the `` and `` elements: The annotations are not mandatory. See: #14 --- girnode.c | 22 ++++++++++++++++++ girnode.h | 6 +++++ girparser.c | 17 +++++++++++++- girwriter.c | 18 +++++++++++++++ gistructinfo.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ gistructinfo.h | 7 +++++- gitypelib-internal.h | 20 +++++++++------- giunioninfo.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ giunioninfo.h | 6 +++++ 9 files changed, 194 insertions(+), 10 deletions(-) diff --git a/girnode.c b/girnode.c index 34b7dea81..4a8d78b93 100644 --- a/girnode.c +++ b/girnode.c @@ -370,6 +370,8 @@ _g_ir_node_free (GIrNode *node) g_free (node->name); g_free (struct_->gtype_name); g_free (struct_->gtype_init); + g_free (struct_->copy_func); + g_free (struct_->free_func); for (l = struct_->members; l; l = l->next) _g_ir_node_free ((GIrNode *)l->data); @@ -403,6 +405,8 @@ _g_ir_node_free (GIrNode *node) g_free (node->name); g_free (union_->gtype_name); g_free (union_->gtype_init); + g_free (union_->copy_func); + g_free (union_->free_func); _g_ir_node_free ((GIrNode *)union_->discriminator_type); for (l = union_->members; l; l = l->next) @@ -755,6 +759,10 @@ _g_ir_node_get_full_size_internal (GIrNode *parent, size += ALIGN_VALUE (strlen (struct_->gtype_name) + 1, 4); if (struct_->gtype_init) size += ALIGN_VALUE (strlen (struct_->gtype_init) + 1, 4); + if (struct_->copy_func) + size += ALIGN_VALUE (strlen (struct_->copy_func) + 1, 4); + if (struct_->free_func) + size += ALIGN_VALUE (strlen (struct_->free_func) + 1, 4); for (l = struct_->members; l; l = l->next) size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); } @@ -855,6 +863,10 @@ _g_ir_node_get_full_size_internal (GIrNode *parent, size += ALIGN_VALUE (strlen (union_->gtype_name) + 1, 4); if (union_->gtype_init) size += ALIGN_VALUE (strlen (union_->gtype_init) + 1, 4); + if (union_->copy_func) + size += ALIGN_VALUE (strlen (union_->copy_func) + 1, 4); + if (union_->free_func) + size += ALIGN_VALUE (strlen (union_->free_func) + 1, 4); for (l = union_->members; l; l = l->next) size += _g_ir_node_get_full_size_internal (node, (GIrNode *)l->data); for (l = union_->discriminators; l; l = l->next) @@ -1956,6 +1968,11 @@ _g_ir_node_build_typelib (GIrNode *node, blob->gtype_init = 0; } + if (struct_->copy_func) + blob->copy_func = _g_ir_write_string (struct_->copy_func, strings, data, offset2); + if (struct_->free_func) + blob->free_func = _g_ir_write_string (struct_->free_func, strings, data, offset2); + blob->n_fields = 0; blob->n_methods = 0; @@ -2040,6 +2057,11 @@ _g_ir_node_build_typelib (GIrNode *node, blob->discriminator_offset = union_->discriminator_offset; + if (union_->copy_func) + blob->copy_func = _g_ir_write_string (union_->copy_func, strings, data, offset2); + if (union_->free_func) + blob->free_func = _g_ir_write_string (union_->free_func, strings, data, offset2); + /* We don't support Union discriminators right now. */ /* if (union_->discriminator_type) diff --git a/girnode.h b/girnode.h index 7b8c97f62..45a81477e 100644 --- a/girnode.h +++ b/girnode.h @@ -328,6 +328,9 @@ struct _GIrNodeStruct gchar *gtype_name; gchar *gtype_init; + gchar *copy_func; + gchar *free_func; + gint alignment; gint size; @@ -346,6 +349,9 @@ struct _GIrNodeUnion gchar *gtype_name; gchar *gtype_init; + gchar *copy_func; + gchar *free_func; + gint alignment; gint size; diff --git a/girparser.c b/girparser.c index e5878b431..5ac4aefed 100644 --- a/girparser.c +++ b/girparser.c @@ -477,7 +477,9 @@ parse_basic (const char *str) static GIrNodeType * parse_type_internal (GIrModule *module, - const gchar *str, char **next, gboolean in_glib, + const gchar *str, + char **next, + gboolean in_glib, gboolean in_gobject) { const BasicTypeInfo *basic; @@ -2560,6 +2562,8 @@ start_struct (GMarkupParseContext *context, const gchar *gtype_init; const gchar *gtype_struct; const gchar *foreign; + const gchar *copy_func; + const gchar *free_func; GIrNodeStruct *struct_; if (!(strcmp (element_name, "record") == 0 && @@ -2579,6 +2583,8 @@ start_struct (GMarkupParseContext *context, gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values); gtype_struct = find_attribute ("glib:is-gtype-struct-for", attribute_names, attribute_values); foreign = find_attribute ("foreign", attribute_names, attribute_values); + copy_func = find_attribute ("copy-function", attribute_names, attribute_values); + free_func = find_attribute ("free-function", attribute_names, attribute_values); if (name == NULL && ctx->node_stack == NULL) { @@ -2615,6 +2621,9 @@ start_struct (GMarkupParseContext *context, struct_->foreign = (g_strcmp0 (foreign, "1") == 0); + struct_->copy_func = g_strdup (copy_func); + struct_->free_func = g_strdup (free_func); + if (ctx->node_stack == NULL) ctx->current_module->entries = g_list_append (ctx->current_module->entries, struct_); @@ -2634,6 +2643,8 @@ start_union (GMarkupParseContext *context, const gchar *deprecated; const gchar *typename; const gchar *typeinit; + const gchar *copy_func; + const gchar *free_func; GIrNodeUnion *union_; if (!(strcmp (element_name, "union") == 0 && @@ -2650,6 +2661,8 @@ start_union (GMarkupParseContext *context, deprecated = find_attribute ("deprecated", attribute_names, attribute_values); typename = find_attribute ("glib:type-name", attribute_names, attribute_values); typeinit = find_attribute ("glib:get-type", attribute_names, attribute_values); + copy_func = find_attribute ("copy-function", attribute_names, attribute_values); + free_func = find_attribute ("free-function", attribute_names, attribute_values); if (name == NULL && ctx->node_stack == NULL) { @@ -2663,6 +2676,8 @@ start_union (GMarkupParseContext *context, ((GIrNode *)union_)->name = g_strdup (name ? name : ""); union_->gtype_name = g_strdup (typename); union_->gtype_init = g_strdup (typeinit); + union_->copy_func = g_strdup (copy_func); + union_->free_func = g_strdup (free_func); if (deprecated) union_->deprecated = TRUE; else diff --git a/girwriter.c b/girwriter.c index ea148f320..276bb6762 100644 --- a/girwriter.c +++ b/girwriter.c @@ -642,6 +642,7 @@ write_struct_info (const gchar *namespace, const gchar *name; const gchar *type_name; const gchar *type_init; + const gchar *func; gboolean deprecated; gboolean is_gtype_struct; gboolean foreign; @@ -676,6 +677,14 @@ write_struct_info (const gchar *namespace, if (is_gtype_struct) xml_printf (file, " glib:is-gtype-struct=\"1\""); + func = g_struct_info_get_copy_function (info); + if (func) + xml_printf (file, " copy-function=\"%s\"", func); + + func = g_struct_info_get_free_function (info); + if (func) + xml_printf (file, " free-function=\"%s\"", func); + write_attributes (file, (GIBaseInfo*) info); size = g_struct_info_get_size (info); @@ -1237,6 +1246,7 @@ write_union_info (const gchar *namespace, const gchar *name; const gchar *type_name; const gchar *type_init; + const gchar *func; gboolean deprecated; gint i; gint size; @@ -1260,6 +1270,14 @@ write_union_info (const gchar *namespace, if (file->show_all && size >= 0) xml_printf (file, " size=\"%d\"", size); + func = g_union_info_get_copy_function (info); + if (func) + xml_printf (file, " copy-function=\"%s\"", func); + + func = g_union_info_get_free_function (info); + if (func) + xml_printf (file, " free-function=\"%s\"", func); + write_attributes (file, (GIBaseInfo*) info); if (g_union_info_is_discriminated (info)) diff --git a/gistructinfo.c b/gistructinfo.c index a9ad73f6e..c13cb7163 100644 --- a/gistructinfo.c +++ b/gistructinfo.c @@ -281,3 +281,57 @@ g_struct_info_is_gtype_struct (GIStructInfo *info) return blob->is_gtype_struct; } + +/** + * g_struct_info_get_copy_function: + * @info: a struct information blob + * + * Retrieves the name of the copy function for @info, if any is set. + * + * Returns: (transfer none) (nullable): the name of the copy function + * + * Since: 1.76 + */ +const char * +g_struct_info_get_copy_function (GIStructInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_STRUCT_INFO (info), NULL); + + blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->copy_func) + return g_typelib_get_string (rinfo->typelib, blob->copy_func); + + return NULL; +} + +/** + * g_struct_info_get_free_function: + * @info: a struct information blob + * + * Retrieves the name of the free function for @info, if any is set. + * + * Returns: (transfer none) (nullable): the name of the free function + * + * Since: 1.76 + */ +const char * +g_struct_info_get_free_function (GIStructInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + StructBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_STRUCT_INFO (info), NULL); + + blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->free_func) + return g_typelib_get_string (rinfo->typelib, blob->free_func); + + return NULL; +} diff --git a/gistructinfo.h b/gistructinfo.h index 6e70fea71..8ff10d3ce 100644 --- a/gistructinfo.h +++ b/gistructinfo.h @@ -75,7 +75,12 @@ gboolean g_struct_info_is_gtype_struct (GIStructInfo *info); GI_AVAILABLE_IN_ALL gboolean g_struct_info_is_foreign (GIStructInfo *info); +GI_AVAILABLE_IN_1_76 +const char * g_struct_info_get_copy_function (GIStructInfo *info); + +GI_AVAILABLE_IN_1_76 +const char * g_struct_info_get_free_function (GIStructInfo *info); + G_END_DECLS - #endif /* __GISTRUCTINFO_H__ */ diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 77c4d6f37..494ab2b37 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -792,8 +792,10 @@ typedef struct { * @size: The size of the struct in bytes. * @n_fields: TODO * @n_methods: TODO - * @reserved2: Reserved for future use. - * @reserved3: Reserved for future use. + * @copy_func: String pointing to a function which can be called to copy + * the contents of this struct type + * @free_func: String pointing to a function which can be called to free + * the contents of this struct type * * TODO */ @@ -817,8 +819,8 @@ typedef struct { guint16 n_fields; guint16 n_methods; - guint32 reserved2; - guint32 reserved3; + guint32 copy_func; + guint32 free_func; } StructBlob; /** @@ -835,8 +837,10 @@ typedef struct { * @size: TODO * @n_fields: Length of the arrays * @n_functions: TODO - * @reserved2: Reserved for future use. - * @reserved3: Reserved for future use. + * @copy_func: String pointing to a function which can be called to copy + * the contents of this union type + * @free_func: String pointing to a function which can be called to free + * the contents of this union type * @discriminator_offset: Offset from the beginning of the union where the * discriminator of a discriminated union is located. The value 0xFFFF * indicates that the discriminator offset is unknown. @@ -861,8 +865,8 @@ typedef struct { guint16 n_fields; guint16 n_functions; - guint32 reserved2; - guint32 reserved3; + guint32 copy_func; + guint32 free_func; gint32 discriminator_offset; SimpleTypeBlob discriminator_type; diff --git a/giunioninfo.c b/giunioninfo.c index 0089f11c2..32a2e3072 100644 --- a/giunioninfo.c +++ b/giunioninfo.c @@ -267,3 +267,57 @@ g_union_info_get_alignment (GIUnionInfo *info) return blob->alignment; } + +/** + * g_union_info_get_copy_function: + * @info: a union information blob + * + * Retrieves the name of the copy function for @info, if any is set. + * + * Returns: (transfer none) (nullable): the name of the copy function + * + * Since: 1.76 + */ +const char * +g_union_info_get_copy_function (GIUnionInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_UNION_INFO (info), NULL); + + blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->copy_func) + return g_typelib_get_string (rinfo->typelib, blob->copy_func); + + return NULL; +} + +/** + * g_union_info_get_free_function: + * @info: a union information blob + * + * Retrieves the name of the free function for @info, if any is set. + * + * Returns: (transfer none) (nullable): the name of the free function + * + * Since: 1.76 + */ +const char * +g_union_info_get_free_function (GIUnionInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo *)info; + UnionBlob *blob; + + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (GI_IS_UNION_INFO (info), NULL); + + blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset]; + + if (blob->free_func) + return g_typelib_get_string (rinfo->typelib, blob->free_func); + + return NULL; +} diff --git a/giunioninfo.h b/giunioninfo.h index 62951b852..4087ed4dc 100644 --- a/giunioninfo.h +++ b/giunioninfo.h @@ -77,6 +77,12 @@ gsize g_union_info_get_size (GIUnionInfo *info); GI_AVAILABLE_IN_ALL gsize g_union_info_get_alignment (GIUnionInfo *info); +GI_AVAILABLE_IN_1_76 +const char * g_union_info_get_copy_function (GIUnionInfo *info); + +GI_AVAILABLE_IN_1_76 +const char * g_union_info_get_free_function (GIUnionInfo *info); + G_END_DECLS From ffba6509daab8ae9adbc2cf9f578bc2492bc40e7 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 13 Jul 2022 13:26:44 +0100 Subject: [PATCH 678/692] Use the pointer attribute in libgirepository The "disguised" attribute is there only for backward compatibility; we use the "pointer" attribute as the authoritative way to indicate a typedef to a struct pointer. --- girmodule.c | 14 +++++++++++ girmodule.h | 9 +++++-- girnode.h | 2 ++ girparser.c | 70 +++++++++++++++++++++++++++++++++++++++-------------- 4 files changed, 75 insertions(+), 20 deletions(-) diff --git a/girmodule.c b/girmodule.c index 66b33fa10..943db971d 100644 --- a/girmodule.c +++ b/girmodule.c @@ -74,6 +74,7 @@ _g_ir_module_free (GIrModule *module) g_list_free (module->include_modules); g_hash_table_destroy (module->aliases); + g_hash_table_destroy (module->pointer_structures); g_hash_table_destroy (module->disguised_structures); g_slice_free (GIrModule, module); @@ -141,6 +142,16 @@ add_alias_foreach (gpointer key, g_hash_table_replace (module->aliases, g_strdup (key), g_strdup (value)); } +static void +add_pointer_structure_foreach (gpointer key, + gpointer value, + gpointer data) +{ + GIrModule *module = data; + + g_hash_table_replace (module->pointer_structures, g_strdup (key), value); +} + static void add_disguised_structure_foreach (gpointer key, gpointer value, @@ -162,6 +173,9 @@ _g_ir_module_add_include_module (GIrModule *module, add_alias_foreach, module); + g_hash_table_foreach (include_module->pointer_structures, + add_pointer_structure_foreach, + module); g_hash_table_foreach (include_module->disguised_structures, add_disguised_structure_foreach, module); diff --git a/girmodule.h b/girmodule.h index 7837f2cf2..fca7ebbf6 100644 --- a/girmodule.h +++ b/girmodule.h @@ -55,8 +55,13 @@ struct _GIrModule /* Aliases defined in the module or in included modules */ GHashTable *aliases; - /* Structures with the 'disguised' flag (typedef struct _X *X) - * in the module or in included modules */ + /* Structures with the 'pointer' flag (typedef struct _X *X) + * in the module or in included modules + */ + GHashTable *pointer_structures; + /* Same as 'pointer' structures, but with the deprecated + * 'disguised' flag + */ GHashTable *disguised_structures; }; diff --git a/girnode.h b/girnode.h index 45a81477e..a35834335 100644 --- a/girnode.h +++ b/girnode.h @@ -322,6 +322,8 @@ struct _GIrNodeStruct gboolean deprecated; gboolean disguised; + gboolean opaque; + gboolean pointer; gboolean is_gtype_struct; gboolean foreign; diff --git a/girparser.c b/girparser.c index 5ac4aefed..3edeac34e 100644 --- a/girparser.c +++ b/girparser.c @@ -114,6 +114,7 @@ struct _ParseContext GList *dependencies; GHashTable *aliases; GHashTable *disguised_structures; + GHashTable *pointer_structures; const char *file_path; const char *namespace; @@ -235,11 +236,20 @@ firstpass_start_element_handler (GMarkupParseContext *context, { const gchar *name; const gchar *disguised; + const gchar *pointer; name = find_attribute ("name", attribute_names, attribute_values); disguised = find_attribute ("disguised", attribute_names, attribute_values); + pointer = find_attribute ("pointer", attribute_names, attribute_values); - if (disguised && strcmp (disguised, "1") == 0) + if (g_strcmp0 (pointer, "1") == 0) + { + char *key; + + key = g_strdup_printf ("%s.%s", ctx->namespace, name); + g_hash_table_replace (ctx->pointer_structures, key, GINT_TO_POINTER (1)); + } + else if (g_strcmp0 (disguised, "1") == 0) { char *key; @@ -660,12 +670,14 @@ resolve_aliases (ParseContext *ctx, const gchar *type) return lookup; } -static gboolean -is_disguised_structure (ParseContext *ctx, const gchar *type) +static void +is_pointer_or_disguised_structure (ParseContext *ctx, + const gchar *type, + gboolean *is_pointer, + gboolean *is_disguised) { const gchar *lookup; gchar *prefixed; - gboolean result; if (strchr (type, '.') == NULL) { @@ -678,12 +690,12 @@ is_disguised_structure (ParseContext *ctx, const gchar *type) prefixed = NULL; } - result = g_hash_table_lookup (ctx->current_module->disguised_structures, - lookup) != NULL; + if (is_pointer != NULL) + *is_pointer = g_hash_table_lookup (ctx->current_module->pointer_structures, lookup) != NULL; + if (is_disguised != NULL) + *is_disguised = g_hash_table_lookup (ctx->current_module->disguised_structures, lookup) != NULL; g_free (prefixed); - - return result; } static GIrNodeType * @@ -2096,12 +2108,22 @@ start_type (GMarkupParseContext *context, typenode = parse_type (ctx, name); - /* A 'disguised' structure is one where the c:type is a typedef that - * doesn't look like a pointer, but is internally. + /* A "pointer" structure is one where the c:type is a typedef that + * to a pointer to a structure; we used to call them "disguised" + * structures as well. */ - if (typenode->tag == GI_TYPE_TAG_INTERFACE && - is_disguised_structure (ctx, typenode->giinterface)) - pointer_depth++; + if (typenode->tag == GI_TYPE_TAG_INTERFACE) + { + gboolean is_pointer = FALSE; + gboolean is_disguised = FALSE; + + is_pointer_or_disguised_structure (ctx, typenode->giinterface, + &is_pointer, + &is_disguised); + + if (is_pointer || is_disguised) + pointer_depth++; + } if (pointer_depth > 0) typenode->is_pointer = TRUE; @@ -2558,6 +2580,8 @@ start_struct (GMarkupParseContext *context, const gchar *name; const gchar *deprecated; const gchar *disguised; + const gchar *opaque; + const gchar *pointer; const gchar *gtype_name; const gchar *gtype_init; const gchar *gtype_struct; @@ -2579,6 +2603,8 @@ start_struct (GMarkupParseContext *context, name = find_attribute ("name", attribute_names, attribute_values); deprecated = find_attribute ("deprecated", attribute_names, attribute_values); disguised = find_attribute ("disguised", attribute_names, attribute_values); + pointer = find_attribute ("pointer", attribute_names, attribute_values); + opaque = find_attribute ("opaque", attribute_names, attribute_values); gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values); gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values); gtype_struct = find_attribute ("glib:is-gtype-struct-for", attribute_names, attribute_values); @@ -2611,9 +2637,15 @@ start_struct (GMarkupParseContext *context, else struct_->deprecated = FALSE; - if (disguised && strcmp (disguised, "1") == 0) + if (g_strcmp0 (disguised, "1") == 0) struct_->disguised = TRUE; + if (g_strcmp0 (pointer, "1") == 0) + struct_->pointer = TRUE; + + if (g_strcmp0 (opaque, "1") == 0) + struct_->opaque = TRUE; + struct_->is_gtype_struct = gtype_struct != NULL; struct_->gtype_name = g_strdup (gtype_name); @@ -3033,7 +3065,9 @@ start_element_handler (GMarkupParseContext *context, ctx->current_module->aliases = ctx->aliases; ctx->aliases = NULL; ctx->current_module->disguised_structures = ctx->disguised_structures; + ctx->current_module->pointer_structures = ctx->pointer_structures; ctx->disguised_structures = NULL; + ctx->pointer_structures = NULL; for (l = ctx->include_modules; l; l = l->next) _g_ir_module_add_include_module (ctx->current_module, l->data); @@ -3622,6 +3656,7 @@ _g_ir_parser_parse_string (GIrParser *parser, ctx.include_modules = NULL; ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); ctx.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + ctx.pointer_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); ctx.type_depth = 0; ctx.dependencies = NULL; ctx.current_module = NULL; @@ -3654,10 +3689,9 @@ _g_ir_parser_parse_string (GIrParser *parser, /* An error occurred before we created a module, so we haven't * transferred ownership of these hash tables to the module. */ - if (ctx.aliases != NULL) - g_hash_table_destroy (ctx.aliases); - if (ctx.disguised_structures != NULL) - g_hash_table_destroy (ctx.disguised_structures); + g_clear_pointer (&ctx.aliases, g_hash_table_unref); + g_clear_pointer (&ctx.disguised_structures, g_hash_table_unref); + g_clear_pointer (&ctx.pointer_structures, g_hash_table_unref); g_list_free (ctx.include_modules); } From 650090eefb81149ae5179996cecc1c26c62d5799 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 20 Mar 2023 18:49:40 +0000 Subject: [PATCH 679/692] Protect ourselves against properties with no default value If the GParamSpec does not have a default value, we should not try to turn it into a string. --- gdump.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gdump.c b/gdump.c index e68c4d14a..a4ff42aae 100644 --- a/gdump.c +++ b/gdump.c @@ -125,6 +125,9 @@ invoke_error_quark (GModule *self, const char *symbol, GError **error) static char * value_to_string (const GValue *value) { + if (value == NULL) + return NULL; + if (G_VALUE_HOLDS_STRING (value)) { const char *s = g_value_get_string (value); @@ -186,7 +189,7 @@ dump_properties (GType type, GOutputStream *out) const GValue *v = g_param_spec_get_default_value (prop); char *default_value = value_to_string (v); - if (default_value != NULL) + if (v != NULL && default_value != NULL) { escaped_printf (out, " \n", prop->name, From 92bbb0033b4f6f6c5a2f82cb1dfc09c83bd0d91c Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 20 Mar 2023 21:56:57 +0000 Subject: [PATCH 680/692] Special-case pointer-sized value types GValues containing pointer-sized things can hold a NULL value, and various transformation functions in the wild are not NULL safe. Fixes: #457 See also: https://gitlab.gnome.org/GNOME/mutter/-/issues/2625 --- gdump.c | 67 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 18 deletions(-) diff --git a/gdump.c b/gdump.c index a4ff42aae..055a8b8c1 100644 --- a/gdump.c +++ b/gdump.c @@ -119,6 +119,27 @@ invoke_error_quark (GModule *self, const char *symbol, GError **error) return sym (); } +static char * +value_transform_to_string (const GValue *value) +{ + GValue tmp = G_VALUE_INIT; + char *s = NULL; + + g_value_init (&tmp, G_TYPE_STRING); + + if (g_value_transform (value, &tmp)) + { + const char *str = g_value_get_string (&tmp); + + if (str != NULL) + s = g_strescape (str, NULL); + } + + g_value_unset (&tmp); + + return s; +} + /* A simpler version of g_strdup_value_contents(), but with stable * output and less complex semantics */ @@ -137,25 +158,35 @@ value_to_string (const GValue *value) return g_strescape (s, NULL); } - else if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING)) - { - GValue tmp = G_VALUE_INIT; - char *s = NULL; - - g_value_init (&tmp, G_TYPE_STRING); - - if (g_value_transform (value, &tmp)) - s = g_strescape (g_value_get_string (&tmp), NULL); - - g_value_unset (&tmp); - - if (s == NULL) - return NULL; - - return s; - } else - return NULL; + { + GType value_type = G_VALUE_TYPE (value); + + switch (G_TYPE_FUNDAMENTAL (value_type)) + { + case G_TYPE_BOXED: + if (g_value_get_boxed (value) == NULL) + return NULL; + else + return value_transform_to_string (value); + break; + + case G_TYPE_OBJECT: + if (g_value_get_object (value) == NULL) + return NULL; + else + return value_transform_to_string (value); + break; + + case G_TYPE_POINTER: + return NULL; + + default: + return value_transform_to_string (value); + } + } + + return NULL; } static void From fcd202650666c2487153d03e35d543ea05be2c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Mon, 24 Aug 2020 13:48:24 +0200 Subject: [PATCH 681/692] gitypelib-internal: Use a switch to check if blob is a registered type No need to go through all the possible blob types, while we can use an inline function to check it. Use an attribute to ensure the function will be inlined, when this is not available just fallback to the previous definition --- gitypelib-internal.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/gitypelib-internal.h b/gitypelib-internal.h index 494ab2b37..4ba53a2a5 100644 --- a/gitypelib-internal.h +++ b/gitypelib-internal.h @@ -185,6 +185,32 @@ typedef enum { BLOB_TYPE_UNION } GTypelibBlobType; + +#if defined (G_CAN_INLINE) && defined (G_ALWAYS_INLINE) + +G_ALWAYS_INLINE +inline gboolean +_blob_is_registered_type (GTypelibBlobType blob_type) +{ + switch (blob_type) + { + case BLOB_TYPE_STRUCT: + case BLOB_TYPE_UNION: + case BLOB_TYPE_ENUM: + case BLOB_TYPE_FLAGS: + case BLOB_TYPE_OBJECT: + case BLOB_TYPE_INTERFACE: + return TRUE; + default: + return FALSE; + } +} + +#define BLOB_IS_REGISTERED_TYPE(blob) \ + _blob_is_registered_type ((GTypelibBlobType) (blob)->blob_type) + +#else + #define BLOB_IS_REGISTERED_TYPE(blob) \ ((blob)->blob_type == BLOB_TYPE_STRUCT || \ (blob)->blob_type == BLOB_TYPE_UNION || \ @@ -193,6 +219,8 @@ typedef enum { (blob)->blob_type == BLOB_TYPE_OBJECT || \ (blob)->blob_type == BLOB_TYPE_INTERFACE) +#endif /* defined (G_CAN_INLINE) && defined (G_ALWAYS_INLINE) */ + /** * Header: * @magic: See #G_IR_MAGIC. From 9a910e44aa4198a64e664cd9e123f28bd81879ec Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Sun, 18 Jun 2023 17:46:42 +0100 Subject: [PATCH 682/692] Add versioning macros for 1.78 --- giversionmacros.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/giversionmacros.h b/giversionmacros.h index 1a7e11ddb..372889e4c 100644 --- a/giversionmacros.h +++ b/giversionmacros.h @@ -209,4 +209,18 @@ # define GI_AVAILABLE_IN_1_76 _GI_EXTERN #endif +#if defined(GLIB_VERSION_2_78) && GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_78 +# define GI_DEPRECATED_IN_1_78 GI_DEPRECATED +# define GI_DEPRECATED_IN_1_78_FOR(f) GI_DEPRECATED_FOR(f) +#else +# define GI_DEPRECATED_IN_1_78 _GI_EXTERN +# define GI_DEPRECATED_IN_1_78_FOR(f) _GI_EXTERN +#endif + +#if defined(GLIB_VERSION_2_78) && GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_78 +# define GI_AVAILABLE_IN_1_78 GI_UNAVAILABLE(2, 78) +#else +# define GI_AVAILABLE_IN_1_78 _GI_EXTERN +#endif + #endif /* __GIVERSIONMACROS_H__ */ From a194c4212983b44db08349d2ae65389ecf4dd786 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Tue, 18 Jul 2023 11:07:59 -0400 Subject: [PATCH 683/692] gdump: Fix leaked io streams This makes Meson unit test fail: https://github.com/mesonbuild/meson/issues/11754 --- gdump.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gdump.c b/gdump.c index 055a8b8c1..449b260a4 100644 --- a/gdump.c +++ b/gdump.c @@ -594,6 +594,7 @@ g_irepository_dump (const char *arg, GError **error) if (output == NULL) { g_input_stream_close (G_INPUT_STREAM (input), NULL, NULL); + g_object_unref (input); return FALSE; } @@ -674,11 +675,12 @@ g_irepository_dump (const char *arg, GError **error) ioerror = NULL; else ioerror = error; - if (!g_input_stream_close (G_INPUT_STREAM (in), NULL, ioerror)) - return FALSE; - if (!g_output_stream_close (G_OUTPUT_STREAM (output), NULL, ioerror)) - return FALSE; + caught_error |= !g_input_stream_close (G_INPUT_STREAM (in), NULL, ioerror); + caught_error |= !g_output_stream_close (G_OUTPUT_STREAM (output), NULL, ioerror); } + g_object_unref (in); + g_object_unref (output); + return !caught_error; } From 0d739996c65edabab33d1e68fb9152cf67d4bbce Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Tue, 8 Aug 2023 15:21:36 -0400 Subject: [PATCH 684/692] parser: filename can contain "\" separator on Windows --- girparser.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/girparser.c b/girparser.c index 3edeac34e..5ce44262c 100644 --- a/girparser.c +++ b/girparser.c @@ -3728,7 +3728,6 @@ _g_ir_parser_parse_file (GIrParser *parser, gchar *buffer; gsize length; GIrModule *module; - const char *slash; char *dash; char *namespace; @@ -3743,11 +3742,7 @@ _g_ir_parser_parse_file (GIrParser *parser, g_debug ("[parsing] filename %s", filename); - slash = g_strrstr (filename, "/"); - if (!slash) - namespace = g_strdup (filename); - else - namespace = g_strdup (slash+1); + namespace = g_path_get_basename (filename); namespace[strlen(namespace)-4] = '\0'; /* Remove version */ From 79e1bc5bef05624de34c2a1af72a1bdddb2e0395 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 1 Feb 2023 11:23:34 +0000 Subject: [PATCH 685/692] girparser: Emit debug messages to show the GIR XML search path This makes it a bit easier to see what is going on than using strace. Helps: #323, #455 Signed-off-by: Simon McVittie --- girparser.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/girparser.c b/girparser.c index 5ce44262c..cde1a4bfa 100644 --- a/girparser.c +++ b/girparser.c @@ -293,6 +293,7 @@ locate_gir (GIrParser *parser, const gchar *const *dir; char *path = NULL; + g_debug ("Looking for %s", girname); datadirs = g_get_system_data_dirs (); if (parser->includes != NULL) @@ -300,6 +301,7 @@ locate_gir (GIrParser *parser, for (dir = (const gchar *const *)parser->includes; *dir; dir++) { path = g_build_filename (*dir, girname, NULL); + g_debug ("Trying %s from includes", path); if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) return path; g_free (path); @@ -309,6 +311,7 @@ locate_gir (GIrParser *parser, for (dir = datadirs; *dir; dir++) { path = g_build_filename (*dir, GIR_SUFFIX, girname, NULL); + g_debug ("Trying %s from system data dirs", path); if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) return path; g_free (path); @@ -316,9 +319,12 @@ locate_gir (GIrParser *parser, } path = g_build_filename (GIR_DIR, girname, NULL); + g_debug ("Trying %s from GIR_DIR", path); if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) return path; g_free (path); + + g_debug ("Did not find %s", girname); return NULL; } From 9d8bcc981755849fe83e28aaf10ed74d846fd4c9 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 9 Aug 2023 11:45:07 +0100 Subject: [PATCH 686/692] girparser: Make ownership transfers out of locate_gir() more obvious Signed-off-by: Simon McVittie --- girparser.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/girparser.c b/girparser.c index cde1a4bfa..e004ad2e8 100644 --- a/girparser.c +++ b/girparser.c @@ -303,7 +303,7 @@ locate_gir (GIrParser *parser, path = g_build_filename (*dir, girname, NULL); g_debug ("Trying %s from includes", path); if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) - return path; + return g_steal_pointer (&path); g_free (path); path = NULL; } @@ -313,7 +313,7 @@ locate_gir (GIrParser *parser, path = g_build_filename (*dir, GIR_SUFFIX, girname, NULL); g_debug ("Trying %s from system data dirs", path); if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) - return path; + return g_steal_pointer (&path); g_free (path); path = NULL; } @@ -321,7 +321,7 @@ locate_gir (GIrParser *parser, path = g_build_filename (GIR_DIR, girname, NULL); g_debug ("Trying %s from GIR_DIR", path); if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) - return path; + return g_steal_pointer (&path); g_free (path); g_debug ("Did not find %s", girname); From 59ae4e65d259b2d2a6faf36d9e5a47441bce57b7 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 9 Aug 2023 11:46:07 +0100 Subject: [PATCH 687/692] girparser: Use g_clear_pointer() in locate_gir() This makes the ownership semantics a bit more obvious. Signed-off-by: Simon McVittie --- girparser.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/girparser.c b/girparser.c index e004ad2e8..b5b5771c2 100644 --- a/girparser.c +++ b/girparser.c @@ -304,8 +304,7 @@ locate_gir (GIrParser *parser, g_debug ("Trying %s from includes", path); if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) return g_steal_pointer (&path); - g_free (path); - path = NULL; + g_clear_pointer (&path, g_free); } } for (dir = datadirs; *dir; dir++) @@ -314,15 +313,14 @@ locate_gir (GIrParser *parser, g_debug ("Trying %s from system data dirs", path); if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) return g_steal_pointer (&path); - g_free (path); - path = NULL; + g_clear_pointer (&path, g_free); } path = g_build_filename (GIR_DIR, girname, NULL); g_debug ("Trying %s from GIR_DIR", path); if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) return g_steal_pointer (&path); - g_free (path); + g_clear_pointer (&path, g_free); g_debug ("Did not find %s", girname); return NULL; From 19f14589d35dacc68d4313235d7d93e7aab784c6 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 10 Feb 2021 11:45:26 +0000 Subject: [PATCH 688/692] Add GI_GIR_PATH environment variable This is searched after any command-line includes paths, but before the XDG_DATA_DIRS or any built-in paths. For example, if libraries are installed in /opt/gnome and GObject-Introspection was configured with -Dgir_dir_prefix=lib64, you could set either GI_GIR_PATH=/opt/gnome/lib64/gir-1.0 or XDG_DATA_DIRS=/opt/gnome/lib64:/opt/gnome/share:${XDG_DATA_DIRS}. Use this to communicate the ../gir directory to giscanner instead of modifying Python's builtins. Helps: #323, #455 Signed-off-by: Simon McVittie --- girparser.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/girparser.c b/girparser.c index b5b5771c2..f13e08715 100644 --- a/girparser.c +++ b/girparser.c @@ -58,6 +58,7 @@ struct _GIrParser { gchar **includes; + gchar **gi_gir_path; GList *parsed_modules; /* All previously parsed modules */ }; @@ -184,6 +185,10 @@ GIrParser * _g_ir_parser_new (void) { GIrParser *parser = g_slice_new0 (GIrParser); + const char *gi_gir_path = g_getenv ("GI_GIR_PATH"); + + if (gi_gir_path != NULL) + parser->gi_gir_path = g_strsplit (gi_gir_path, G_SEARCHPATH_SEPARATOR_S, 0); return parser; } @@ -193,8 +198,8 @@ _g_ir_parser_free (GIrParser *parser) { GList *l; - if (parser->includes) - g_strfreev (parser->includes); + g_strfreev (parser->includes); + g_strfreev (parser->gi_gir_path); for (l = parser->parsed_modules; l; l = l->next) _g_ir_module_free (l->data); @@ -206,8 +211,7 @@ void _g_ir_parser_set_includes (GIrParser *parser, const gchar *const *includes) { - if (parser->includes) - g_strfreev (parser->includes); + g_strfreev (parser->includes); parser->includes = g_strdupv ((char **)includes); } @@ -307,6 +311,22 @@ locate_gir (GIrParser *parser, g_clear_pointer (&path, g_free); } } + + if (parser->gi_gir_path != NULL) + { + for (dir = (const gchar *const *) parser->gi_gir_path; *dir; dir++) + { + if (**dir == '\0') + continue; + + path = g_build_filename (*dir, girname, NULL); + g_debug ("Trying %s from GI_GIR_PATH", path); + if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) + return g_steal_pointer (&path); + g_clear_pointer (&path, g_free); + } + } + for (dir = datadirs; *dir; dir++) { path = g_build_filename (*dir, GIR_SUFFIX, girname, NULL); From 4758e1ee1985e4e48230b4bf1b38459756b95add Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 10 Feb 2021 12:01:44 +0000 Subject: [PATCH 689/692] girepository: Search the same paths as the Python code The Python code historically always searched DATADIR/gir-1.0 (always) and /usr/share/gir-1.0 (only on Unix); since the previous commit, they are searched after the GIR_DIR. Do the same here, to make the C and Python search paths match up. With the default gir_dir_prefix, searching both GIR_DIR and DATADIR/gir-1.0 is redundant. However, if gir_dir_prefix is changed to something else, for example -Dgir_dir_prefix=lib64, always searching DATADIR/gir-1.0 provides backwards compatibility with pre-existing GIR that might already be stored in DATADIR/gir-1.0. Resolves: #455 (in conjunction with previous commit) Helps: #323 Signed-off-by: Simon McVittie --- girparser.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/girparser.c b/girparser.c index f13e08715..dcfaacd17 100644 --- a/girparser.c +++ b/girparser.c @@ -342,6 +342,20 @@ locate_gir (GIrParser *parser, return g_steal_pointer (&path); g_clear_pointer (&path, g_free); + path = g_build_filename (GOBJECT_INTROSPECTION_DATADIR, GIR_SUFFIX, girname, NULL); + g_debug ("Trying %s from DATADIR", path); + if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) + return g_steal_pointer (&path); + g_clear_pointer (&path, g_free); + +#ifdef G_OS_UNIX + path = g_build_filename ("/usr/share", GIR_SUFFIX, girname, NULL); + g_debug ("Trying %s", path); + if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) + return g_steal_pointer (&path); + g_clear_pointer (&path, g_free); +#endif + g_debug ("Did not find %s", girname); return NULL; } From d3d6fd68090673f66ead8ba97e2b2a4893304e2c Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 10 Feb 2021 12:07:56 +0000 Subject: [PATCH 690/692] Search XDG_DATA_HOME/gir-1.0 for GIR XML too For completeness. There probably won't be any, but the XDG base directory specification is most useful if it's consistently followed everywhere, and the specification says to look in XDG_DATA_HOME before XDG_DATA_DIRS. Signed-off-by: Simon McVittie --- girparser.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/girparser.c b/girparser.c index dcfaacd17..9a7554ca1 100644 --- a/girparser.c +++ b/girparser.c @@ -327,6 +327,12 @@ locate_gir (GIrParser *parser, } } + path = g_build_filename (g_get_user_data_dir (), GIR_SUFFIX, girname, NULL); + g_debug ("Trying %s from user data dir", path); + if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) + return g_steal_pointer (&path); + g_clear_pointer (&path, g_free); + for (dir = datadirs; *dir; dir++) { path = g_build_filename (*dir, GIR_SUFFIX, girname, NULL); From b347a44e5ed4303ba98e738ba1b372d708ba5b55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 11 Aug 2023 00:42:10 +0200 Subject: [PATCH 691/692] gdump: Do not overwrite GError contents In case of multiple IO failures we may try to use a GError multiple times, avoid so. See: https://gitlab.gnome.org/GNOME/gobject-introspection/-/merge_requests/411#note_1812951 --- gdump.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/gdump.c b/gdump.c index 449b260a4..c63dc4556 100644 --- a/gdump.c +++ b/gdump.c @@ -669,14 +669,11 @@ g_irepository_dump (const char *arg, GError **error) goutput_write (G_OUTPUT_STREAM (output), "\n"); { - GError **ioerror; /* Avoid overwriting an earlier set error */ - if (caught_error) - ioerror = NULL; - else - ioerror = error; - caught_error |= !g_input_stream_close (G_INPUT_STREAM (in), NULL, ioerror); - caught_error |= !g_output_stream_close (G_OUTPUT_STREAM (output), NULL, ioerror); + caught_error |= !g_input_stream_close (G_INPUT_STREAM (in), NULL, + caught_error ? NULL : error); + caught_error |= !g_output_stream_close (G_OUTPUT_STREAM (output), NULL, + caught_error ? NULL : error); } g_object_unref (in); From 03d6c164348507e24f03fb9c527efce7869647fd Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Sun, 15 Oct 2023 17:56:05 +0100 Subject: [PATCH 692/692] Move girepository --- cmph-bdz-test.c => girepository/cmph-bdz-test.c | 0 {cmph => girepository/cmph}/README-CMPH-IMPORT.txt | 0 {cmph => girepository/cmph}/bdz.c | 0 {cmph => girepository/cmph}/bdz.h | 0 {cmph => girepository/cmph}/bdz_gen_lookup_table.c | 0 {cmph => girepository/cmph}/bdz_ph.c | 0 {cmph => girepository/cmph}/bdz_ph.h | 0 {cmph => girepository/cmph}/bdz_structs.h | 0 {cmph => girepository/cmph}/bdz_structs_ph.h | 0 {cmph => girepository/cmph}/bitbool.h | 0 {cmph => girepository/cmph}/bmz.c | 0 {cmph => girepository/cmph}/bmz.h | 0 {cmph => girepository/cmph}/bmz8.c | 0 {cmph => girepository/cmph}/bmz8.h | 0 {cmph => girepository/cmph}/bmz8_structs.h | 0 {cmph => girepository/cmph}/bmz_structs.h | 0 {cmph => girepository/cmph}/brz.c | 0 {cmph => girepository/cmph}/brz.h | 0 {cmph => girepository/cmph}/brz_structs.h | 0 {cmph => girepository/cmph}/buffer_entry.c | 0 {cmph => girepository/cmph}/buffer_entry.h | 0 {cmph => girepository/cmph}/buffer_manage.c | 0 {cmph => girepository/cmph}/buffer_manage.h | 0 {cmph => girepository/cmph}/buffer_manager.c | 0 {cmph => girepository/cmph}/buffer_manager.h | 0 {cmph => girepository/cmph}/chd.c | 0 {cmph => girepository/cmph}/chd.h | 0 {cmph => girepository/cmph}/chd_ph.c | 0 {cmph => girepository/cmph}/chd_ph.h | 0 {cmph => girepository/cmph}/chd_structs.h | 0 {cmph => girepository/cmph}/chd_structs_ph.h | 0 {cmph => girepository/cmph}/chm.c | 0 {cmph => girepository/cmph}/chm.h | 0 {cmph => girepository/cmph}/chm_structs.h | 0 {cmph => girepository/cmph}/cmph.c | 0 {cmph => girepository/cmph}/cmph.h | 0 {cmph => girepository/cmph}/cmph_structs.c | 0 {cmph => girepository/cmph}/cmph_structs.h | 0 {cmph => girepository/cmph}/cmph_time.h | 0 {cmph => girepository/cmph}/cmph_types.h | 0 {cmph => girepository/cmph}/compressed_rank.c | 0 {cmph => girepository/cmph}/compressed_rank.h | 0 {cmph => girepository/cmph}/compressed_seq.c | 0 {cmph => girepository/cmph}/compressed_seq.h | 0 {cmph => girepository/cmph}/debug.h | 0 {cmph => girepository/cmph}/djb2_hash.c | 0 {cmph => girepository/cmph}/djb2_hash.h | 0 {cmph => girepository/cmph}/fch.c | 0 {cmph => girepository/cmph}/fch.h | 0 {cmph => girepository/cmph}/fch_buckets.c | 0 {cmph => girepository/cmph}/fch_buckets.h | 0 {cmph => girepository/cmph}/fch_structs.h | 0 {cmph => girepository/cmph}/fnv_hash.c | 0 {cmph => girepository/cmph}/fnv_hash.h | 0 {cmph => girepository/cmph}/graph.c | 0 {cmph => girepository/cmph}/graph.h | 0 {cmph => girepository/cmph}/hash.c | 0 {cmph => girepository/cmph}/hash.h | 0 {cmph => girepository/cmph}/hash_state.h | 0 {cmph => girepository/cmph}/hashtree.c | 0 {cmph => girepository/cmph}/hashtree.h | 0 {cmph => girepository/cmph}/hashtree_structs.h | 0 {cmph => girepository/cmph}/jenkins_hash.c | 0 {cmph => girepository/cmph}/jenkins_hash.h | 0 {cmph => girepository/cmph}/main.c | 0 {cmph => girepository/cmph}/meson.build | 0 {cmph => girepository/cmph}/miller_rabin.c | 0 {cmph => girepository/cmph}/miller_rabin.h | 0 {cmph => girepository/cmph}/sdbm_hash.c | 0 {cmph => girepository/cmph}/sdbm_hash.h | 0 {cmph => girepository/cmph}/select.c | 0 {cmph => girepository/cmph}/select.h | 0 {cmph => girepository/cmph}/select_lookup_tables.h | 0 {cmph => girepository/cmph}/vqueue.c | 0 {cmph => girepository/cmph}/vqueue.h | 0 {cmph => girepository/cmph}/vstack.c | 0 {cmph => girepository/cmph}/vstack.h | 0 {cmph => girepository/cmph}/wingetopt.c | 0 {cmph => girepository/cmph}/wingetopt.h | 0 docs.c => girepository/docs.c | 0 gdump.c => girepository/gdump.c | 0 gi-dump-types.c => girepository/gi-dump-types.c | 0 giarginfo.c => girepository/giarginfo.c | 0 giarginfo.h => girepository/giarginfo.h | 0 gibaseinfo.c => girepository/gibaseinfo.c | 0 gibaseinfo.h => girepository/gibaseinfo.h | 0 gicallableinfo.c => girepository/gicallableinfo.c | 0 gicallableinfo.h => girepository/gicallableinfo.h | 0 giconstantinfo.c => girepository/giconstantinfo.c | 0 giconstantinfo.h => girepository/giconstantinfo.h | 0 gienuminfo.c => girepository/gienuminfo.c | 0 gienuminfo.h => girepository/gienuminfo.h | 0 gifieldinfo.c => girepository/gifieldinfo.c | 0 gifieldinfo.h => girepository/gifieldinfo.h | 0 gifunctioninfo.c => girepository/gifunctioninfo.c | 0 gifunctioninfo.h => girepository/gifunctioninfo.h | 0 giinterfaceinfo.c => girepository/giinterfaceinfo.c | 0 giinterfaceinfo.h => girepository/giinterfaceinfo.h | 0 ginvoke.c => girepository/ginvoke.c | 0 giobjectinfo.c => girepository/giobjectinfo.c | 0 giobjectinfo.h => girepository/giobjectinfo.h | 0 gipropertyinfo.c => girepository/gipropertyinfo.c | 0 gipropertyinfo.h => girepository/gipropertyinfo.h | 0 giregisteredtypeinfo.c => girepository/giregisteredtypeinfo.c | 0 giregisteredtypeinfo.h => girepository/giregisteredtypeinfo.h | 0 girepository-private.h => girepository/girepository-private.h | 0 girepository.c => girepository/girepository.c | 0 girepository.h => girepository/girepository.h | 0 girffi.c => girepository/girffi.c | 0 girffi.h => girepository/girffi.h | 0 girmodule.c => girepository/girmodule.c | 0 girmodule.h => girepository/girmodule.h | 0 girnode.c => girepository/girnode.c | 0 girnode.h => girepository/girnode.h | 0 giroffsets.c => girepository/giroffsets.c | 0 girparser.c => girepository/girparser.c | 0 girparser.h => girepository/girparser.h | 0 girwriter.c => girepository/girwriter.c | 0 girwriter.h => girepository/girwriter.h | 0 gisignalinfo.c => girepository/gisignalinfo.c | 0 gisignalinfo.h => girepository/gisignalinfo.h | 0 gistructinfo.c => girepository/gistructinfo.c | 0 gistructinfo.h => girepository/gistructinfo.h | 0 gitypeinfo.c => girepository/gitypeinfo.c | 0 gitypeinfo.h => girepository/gitypeinfo.h | 0 gitypelib-internal.h => girepository/gitypelib-internal.h | 0 gitypelib.c => girepository/gitypelib.c | 0 gitypelib.h => girepository/gitypelib.h | 0 gitypes.h => girepository/gitypes.h | 0 giunioninfo.c => girepository/giunioninfo.c | 0 giunioninfo.h => girepository/giunioninfo.h | 0 giversion.c => girepository/giversion.c | 0 giversion.h.in => girepository/giversion.h.in | 0 giversionmacros.h => girepository/giversionmacros.h | 0 givfuncinfo.c => girepository/givfuncinfo.c | 0 givfuncinfo.h => girepository/givfuncinfo.h | 0 gthash-test.c => girepository/gthash-test.c | 0 gthash.c => girepository/gthash.c | 0 meson.build => girepository/meson.build | 0 139 files changed, 0 insertions(+), 0 deletions(-) rename cmph-bdz-test.c => girepository/cmph-bdz-test.c (100%) rename {cmph => girepository/cmph}/README-CMPH-IMPORT.txt (100%) rename {cmph => girepository/cmph}/bdz.c (100%) rename {cmph => girepository/cmph}/bdz.h (100%) rename {cmph => girepository/cmph}/bdz_gen_lookup_table.c (100%) rename {cmph => girepository/cmph}/bdz_ph.c (100%) rename {cmph => girepository/cmph}/bdz_ph.h (100%) rename {cmph => girepository/cmph}/bdz_structs.h (100%) rename {cmph => girepository/cmph}/bdz_structs_ph.h (100%) rename {cmph => girepository/cmph}/bitbool.h (100%) rename {cmph => girepository/cmph}/bmz.c (100%) rename {cmph => girepository/cmph}/bmz.h (100%) rename {cmph => girepository/cmph}/bmz8.c (100%) rename {cmph => girepository/cmph}/bmz8.h (100%) rename {cmph => girepository/cmph}/bmz8_structs.h (100%) rename {cmph => girepository/cmph}/bmz_structs.h (100%) rename {cmph => girepository/cmph}/brz.c (100%) rename {cmph => girepository/cmph}/brz.h (100%) rename {cmph => girepository/cmph}/brz_structs.h (100%) rename {cmph => girepository/cmph}/buffer_entry.c (100%) rename {cmph => girepository/cmph}/buffer_entry.h (100%) rename {cmph => girepository/cmph}/buffer_manage.c (100%) rename {cmph => girepository/cmph}/buffer_manage.h (100%) rename {cmph => girepository/cmph}/buffer_manager.c (100%) rename {cmph => girepository/cmph}/buffer_manager.h (100%) rename {cmph => girepository/cmph}/chd.c (100%) rename {cmph => girepository/cmph}/chd.h (100%) rename {cmph => girepository/cmph}/chd_ph.c (100%) rename {cmph => girepository/cmph}/chd_ph.h (100%) rename {cmph => girepository/cmph}/chd_structs.h (100%) rename {cmph => girepository/cmph}/chd_structs_ph.h (100%) rename {cmph => girepository/cmph}/chm.c (100%) rename {cmph => girepository/cmph}/chm.h (100%) rename {cmph => girepository/cmph}/chm_structs.h (100%) rename {cmph => girepository/cmph}/cmph.c (100%) rename {cmph => girepository/cmph}/cmph.h (100%) rename {cmph => girepository/cmph}/cmph_structs.c (100%) rename {cmph => girepository/cmph}/cmph_structs.h (100%) rename {cmph => girepository/cmph}/cmph_time.h (100%) rename {cmph => girepository/cmph}/cmph_types.h (100%) rename {cmph => girepository/cmph}/compressed_rank.c (100%) rename {cmph => girepository/cmph}/compressed_rank.h (100%) rename {cmph => girepository/cmph}/compressed_seq.c (100%) rename {cmph => girepository/cmph}/compressed_seq.h (100%) rename {cmph => girepository/cmph}/debug.h (100%) rename {cmph => girepository/cmph}/djb2_hash.c (100%) rename {cmph => girepository/cmph}/djb2_hash.h (100%) rename {cmph => girepository/cmph}/fch.c (100%) rename {cmph => girepository/cmph}/fch.h (100%) rename {cmph => girepository/cmph}/fch_buckets.c (100%) rename {cmph => girepository/cmph}/fch_buckets.h (100%) rename {cmph => girepository/cmph}/fch_structs.h (100%) rename {cmph => girepository/cmph}/fnv_hash.c (100%) rename {cmph => girepository/cmph}/fnv_hash.h (100%) rename {cmph => girepository/cmph}/graph.c (100%) rename {cmph => girepository/cmph}/graph.h (100%) rename {cmph => girepository/cmph}/hash.c (100%) rename {cmph => girepository/cmph}/hash.h (100%) rename {cmph => girepository/cmph}/hash_state.h (100%) rename {cmph => girepository/cmph}/hashtree.c (100%) rename {cmph => girepository/cmph}/hashtree.h (100%) rename {cmph => girepository/cmph}/hashtree_structs.h (100%) rename {cmph => girepository/cmph}/jenkins_hash.c (100%) rename {cmph => girepository/cmph}/jenkins_hash.h (100%) rename {cmph => girepository/cmph}/main.c (100%) rename {cmph => girepository/cmph}/meson.build (100%) rename {cmph => girepository/cmph}/miller_rabin.c (100%) rename {cmph => girepository/cmph}/miller_rabin.h (100%) rename {cmph => girepository/cmph}/sdbm_hash.c (100%) rename {cmph => girepository/cmph}/sdbm_hash.h (100%) rename {cmph => girepository/cmph}/select.c (100%) rename {cmph => girepository/cmph}/select.h (100%) rename {cmph => girepository/cmph}/select_lookup_tables.h (100%) rename {cmph => girepository/cmph}/vqueue.c (100%) rename {cmph => girepository/cmph}/vqueue.h (100%) rename {cmph => girepository/cmph}/vstack.c (100%) rename {cmph => girepository/cmph}/vstack.h (100%) rename {cmph => girepository/cmph}/wingetopt.c (100%) rename {cmph => girepository/cmph}/wingetopt.h (100%) rename docs.c => girepository/docs.c (100%) rename gdump.c => girepository/gdump.c (100%) rename gi-dump-types.c => girepository/gi-dump-types.c (100%) rename giarginfo.c => girepository/giarginfo.c (100%) rename giarginfo.h => girepository/giarginfo.h (100%) rename gibaseinfo.c => girepository/gibaseinfo.c (100%) rename gibaseinfo.h => girepository/gibaseinfo.h (100%) rename gicallableinfo.c => girepository/gicallableinfo.c (100%) rename gicallableinfo.h => girepository/gicallableinfo.h (100%) rename giconstantinfo.c => girepository/giconstantinfo.c (100%) rename giconstantinfo.h => girepository/giconstantinfo.h (100%) rename gienuminfo.c => girepository/gienuminfo.c (100%) rename gienuminfo.h => girepository/gienuminfo.h (100%) rename gifieldinfo.c => girepository/gifieldinfo.c (100%) rename gifieldinfo.h => girepository/gifieldinfo.h (100%) rename gifunctioninfo.c => girepository/gifunctioninfo.c (100%) rename gifunctioninfo.h => girepository/gifunctioninfo.h (100%) rename giinterfaceinfo.c => girepository/giinterfaceinfo.c (100%) rename giinterfaceinfo.h => girepository/giinterfaceinfo.h (100%) rename ginvoke.c => girepository/ginvoke.c (100%) rename giobjectinfo.c => girepository/giobjectinfo.c (100%) rename giobjectinfo.h => girepository/giobjectinfo.h (100%) rename gipropertyinfo.c => girepository/gipropertyinfo.c (100%) rename gipropertyinfo.h => girepository/gipropertyinfo.h (100%) rename giregisteredtypeinfo.c => girepository/giregisteredtypeinfo.c (100%) rename giregisteredtypeinfo.h => girepository/giregisteredtypeinfo.h (100%) rename girepository-private.h => girepository/girepository-private.h (100%) rename girepository.c => girepository/girepository.c (100%) rename girepository.h => girepository/girepository.h (100%) rename girffi.c => girepository/girffi.c (100%) rename girffi.h => girepository/girffi.h (100%) rename girmodule.c => girepository/girmodule.c (100%) rename girmodule.h => girepository/girmodule.h (100%) rename girnode.c => girepository/girnode.c (100%) rename girnode.h => girepository/girnode.h (100%) rename giroffsets.c => girepository/giroffsets.c (100%) rename girparser.c => girepository/girparser.c (100%) rename girparser.h => girepository/girparser.h (100%) rename girwriter.c => girepository/girwriter.c (100%) rename girwriter.h => girepository/girwriter.h (100%) rename gisignalinfo.c => girepository/gisignalinfo.c (100%) rename gisignalinfo.h => girepository/gisignalinfo.h (100%) rename gistructinfo.c => girepository/gistructinfo.c (100%) rename gistructinfo.h => girepository/gistructinfo.h (100%) rename gitypeinfo.c => girepository/gitypeinfo.c (100%) rename gitypeinfo.h => girepository/gitypeinfo.h (100%) rename gitypelib-internal.h => girepository/gitypelib-internal.h (100%) rename gitypelib.c => girepository/gitypelib.c (100%) rename gitypelib.h => girepository/gitypelib.h (100%) rename gitypes.h => girepository/gitypes.h (100%) rename giunioninfo.c => girepository/giunioninfo.c (100%) rename giunioninfo.h => girepository/giunioninfo.h (100%) rename giversion.c => girepository/giversion.c (100%) rename giversion.h.in => girepository/giversion.h.in (100%) rename giversionmacros.h => girepository/giversionmacros.h (100%) rename givfuncinfo.c => girepository/givfuncinfo.c (100%) rename givfuncinfo.h => girepository/givfuncinfo.h (100%) rename gthash-test.c => girepository/gthash-test.c (100%) rename gthash.c => girepository/gthash.c (100%) rename meson.build => girepository/meson.build (100%) diff --git a/cmph-bdz-test.c b/girepository/cmph-bdz-test.c similarity index 100% rename from cmph-bdz-test.c rename to girepository/cmph-bdz-test.c diff --git a/cmph/README-CMPH-IMPORT.txt b/girepository/cmph/README-CMPH-IMPORT.txt similarity index 100% rename from cmph/README-CMPH-IMPORT.txt rename to girepository/cmph/README-CMPH-IMPORT.txt diff --git a/cmph/bdz.c b/girepository/cmph/bdz.c similarity index 100% rename from cmph/bdz.c rename to girepository/cmph/bdz.c diff --git a/cmph/bdz.h b/girepository/cmph/bdz.h similarity index 100% rename from cmph/bdz.h rename to girepository/cmph/bdz.h diff --git a/cmph/bdz_gen_lookup_table.c b/girepository/cmph/bdz_gen_lookup_table.c similarity index 100% rename from cmph/bdz_gen_lookup_table.c rename to girepository/cmph/bdz_gen_lookup_table.c diff --git a/cmph/bdz_ph.c b/girepository/cmph/bdz_ph.c similarity index 100% rename from cmph/bdz_ph.c rename to girepository/cmph/bdz_ph.c diff --git a/cmph/bdz_ph.h b/girepository/cmph/bdz_ph.h similarity index 100% rename from cmph/bdz_ph.h rename to girepository/cmph/bdz_ph.h diff --git a/cmph/bdz_structs.h b/girepository/cmph/bdz_structs.h similarity index 100% rename from cmph/bdz_structs.h rename to girepository/cmph/bdz_structs.h diff --git a/cmph/bdz_structs_ph.h b/girepository/cmph/bdz_structs_ph.h similarity index 100% rename from cmph/bdz_structs_ph.h rename to girepository/cmph/bdz_structs_ph.h diff --git a/cmph/bitbool.h b/girepository/cmph/bitbool.h similarity index 100% rename from cmph/bitbool.h rename to girepository/cmph/bitbool.h diff --git a/cmph/bmz.c b/girepository/cmph/bmz.c similarity index 100% rename from cmph/bmz.c rename to girepository/cmph/bmz.c diff --git a/cmph/bmz.h b/girepository/cmph/bmz.h similarity index 100% rename from cmph/bmz.h rename to girepository/cmph/bmz.h diff --git a/cmph/bmz8.c b/girepository/cmph/bmz8.c similarity index 100% rename from cmph/bmz8.c rename to girepository/cmph/bmz8.c diff --git a/cmph/bmz8.h b/girepository/cmph/bmz8.h similarity index 100% rename from cmph/bmz8.h rename to girepository/cmph/bmz8.h diff --git a/cmph/bmz8_structs.h b/girepository/cmph/bmz8_structs.h similarity index 100% rename from cmph/bmz8_structs.h rename to girepository/cmph/bmz8_structs.h diff --git a/cmph/bmz_structs.h b/girepository/cmph/bmz_structs.h similarity index 100% rename from cmph/bmz_structs.h rename to girepository/cmph/bmz_structs.h diff --git a/cmph/brz.c b/girepository/cmph/brz.c similarity index 100% rename from cmph/brz.c rename to girepository/cmph/brz.c diff --git a/cmph/brz.h b/girepository/cmph/brz.h similarity index 100% rename from cmph/brz.h rename to girepository/cmph/brz.h diff --git a/cmph/brz_structs.h b/girepository/cmph/brz_structs.h similarity index 100% rename from cmph/brz_structs.h rename to girepository/cmph/brz_structs.h diff --git a/cmph/buffer_entry.c b/girepository/cmph/buffer_entry.c similarity index 100% rename from cmph/buffer_entry.c rename to girepository/cmph/buffer_entry.c diff --git a/cmph/buffer_entry.h b/girepository/cmph/buffer_entry.h similarity index 100% rename from cmph/buffer_entry.h rename to girepository/cmph/buffer_entry.h diff --git a/cmph/buffer_manage.c b/girepository/cmph/buffer_manage.c similarity index 100% rename from cmph/buffer_manage.c rename to girepository/cmph/buffer_manage.c diff --git a/cmph/buffer_manage.h b/girepository/cmph/buffer_manage.h similarity index 100% rename from cmph/buffer_manage.h rename to girepository/cmph/buffer_manage.h diff --git a/cmph/buffer_manager.c b/girepository/cmph/buffer_manager.c similarity index 100% rename from cmph/buffer_manager.c rename to girepository/cmph/buffer_manager.c diff --git a/cmph/buffer_manager.h b/girepository/cmph/buffer_manager.h similarity index 100% rename from cmph/buffer_manager.h rename to girepository/cmph/buffer_manager.h diff --git a/cmph/chd.c b/girepository/cmph/chd.c similarity index 100% rename from cmph/chd.c rename to girepository/cmph/chd.c diff --git a/cmph/chd.h b/girepository/cmph/chd.h similarity index 100% rename from cmph/chd.h rename to girepository/cmph/chd.h diff --git a/cmph/chd_ph.c b/girepository/cmph/chd_ph.c similarity index 100% rename from cmph/chd_ph.c rename to girepository/cmph/chd_ph.c diff --git a/cmph/chd_ph.h b/girepository/cmph/chd_ph.h similarity index 100% rename from cmph/chd_ph.h rename to girepository/cmph/chd_ph.h diff --git a/cmph/chd_structs.h b/girepository/cmph/chd_structs.h similarity index 100% rename from cmph/chd_structs.h rename to girepository/cmph/chd_structs.h diff --git a/cmph/chd_structs_ph.h b/girepository/cmph/chd_structs_ph.h similarity index 100% rename from cmph/chd_structs_ph.h rename to girepository/cmph/chd_structs_ph.h diff --git a/cmph/chm.c b/girepository/cmph/chm.c similarity index 100% rename from cmph/chm.c rename to girepository/cmph/chm.c diff --git a/cmph/chm.h b/girepository/cmph/chm.h similarity index 100% rename from cmph/chm.h rename to girepository/cmph/chm.h diff --git a/cmph/chm_structs.h b/girepository/cmph/chm_structs.h similarity index 100% rename from cmph/chm_structs.h rename to girepository/cmph/chm_structs.h diff --git a/cmph/cmph.c b/girepository/cmph/cmph.c similarity index 100% rename from cmph/cmph.c rename to girepository/cmph/cmph.c diff --git a/cmph/cmph.h b/girepository/cmph/cmph.h similarity index 100% rename from cmph/cmph.h rename to girepository/cmph/cmph.h diff --git a/cmph/cmph_structs.c b/girepository/cmph/cmph_structs.c similarity index 100% rename from cmph/cmph_structs.c rename to girepository/cmph/cmph_structs.c diff --git a/cmph/cmph_structs.h b/girepository/cmph/cmph_structs.h similarity index 100% rename from cmph/cmph_structs.h rename to girepository/cmph/cmph_structs.h diff --git a/cmph/cmph_time.h b/girepository/cmph/cmph_time.h similarity index 100% rename from cmph/cmph_time.h rename to girepository/cmph/cmph_time.h diff --git a/cmph/cmph_types.h b/girepository/cmph/cmph_types.h similarity index 100% rename from cmph/cmph_types.h rename to girepository/cmph/cmph_types.h diff --git a/cmph/compressed_rank.c b/girepository/cmph/compressed_rank.c similarity index 100% rename from cmph/compressed_rank.c rename to girepository/cmph/compressed_rank.c diff --git a/cmph/compressed_rank.h b/girepository/cmph/compressed_rank.h similarity index 100% rename from cmph/compressed_rank.h rename to girepository/cmph/compressed_rank.h diff --git a/cmph/compressed_seq.c b/girepository/cmph/compressed_seq.c similarity index 100% rename from cmph/compressed_seq.c rename to girepository/cmph/compressed_seq.c diff --git a/cmph/compressed_seq.h b/girepository/cmph/compressed_seq.h similarity index 100% rename from cmph/compressed_seq.h rename to girepository/cmph/compressed_seq.h diff --git a/cmph/debug.h b/girepository/cmph/debug.h similarity index 100% rename from cmph/debug.h rename to girepository/cmph/debug.h diff --git a/cmph/djb2_hash.c b/girepository/cmph/djb2_hash.c similarity index 100% rename from cmph/djb2_hash.c rename to girepository/cmph/djb2_hash.c diff --git a/cmph/djb2_hash.h b/girepository/cmph/djb2_hash.h similarity index 100% rename from cmph/djb2_hash.h rename to girepository/cmph/djb2_hash.h diff --git a/cmph/fch.c b/girepository/cmph/fch.c similarity index 100% rename from cmph/fch.c rename to girepository/cmph/fch.c diff --git a/cmph/fch.h b/girepository/cmph/fch.h similarity index 100% rename from cmph/fch.h rename to girepository/cmph/fch.h diff --git a/cmph/fch_buckets.c b/girepository/cmph/fch_buckets.c similarity index 100% rename from cmph/fch_buckets.c rename to girepository/cmph/fch_buckets.c diff --git a/cmph/fch_buckets.h b/girepository/cmph/fch_buckets.h similarity index 100% rename from cmph/fch_buckets.h rename to girepository/cmph/fch_buckets.h diff --git a/cmph/fch_structs.h b/girepository/cmph/fch_structs.h similarity index 100% rename from cmph/fch_structs.h rename to girepository/cmph/fch_structs.h diff --git a/cmph/fnv_hash.c b/girepository/cmph/fnv_hash.c similarity index 100% rename from cmph/fnv_hash.c rename to girepository/cmph/fnv_hash.c diff --git a/cmph/fnv_hash.h b/girepository/cmph/fnv_hash.h similarity index 100% rename from cmph/fnv_hash.h rename to girepository/cmph/fnv_hash.h diff --git a/cmph/graph.c b/girepository/cmph/graph.c similarity index 100% rename from cmph/graph.c rename to girepository/cmph/graph.c diff --git a/cmph/graph.h b/girepository/cmph/graph.h similarity index 100% rename from cmph/graph.h rename to girepository/cmph/graph.h diff --git a/cmph/hash.c b/girepository/cmph/hash.c similarity index 100% rename from cmph/hash.c rename to girepository/cmph/hash.c diff --git a/cmph/hash.h b/girepository/cmph/hash.h similarity index 100% rename from cmph/hash.h rename to girepository/cmph/hash.h diff --git a/cmph/hash_state.h b/girepository/cmph/hash_state.h similarity index 100% rename from cmph/hash_state.h rename to girepository/cmph/hash_state.h diff --git a/cmph/hashtree.c b/girepository/cmph/hashtree.c similarity index 100% rename from cmph/hashtree.c rename to girepository/cmph/hashtree.c diff --git a/cmph/hashtree.h b/girepository/cmph/hashtree.h similarity index 100% rename from cmph/hashtree.h rename to girepository/cmph/hashtree.h diff --git a/cmph/hashtree_structs.h b/girepository/cmph/hashtree_structs.h similarity index 100% rename from cmph/hashtree_structs.h rename to girepository/cmph/hashtree_structs.h diff --git a/cmph/jenkins_hash.c b/girepository/cmph/jenkins_hash.c similarity index 100% rename from cmph/jenkins_hash.c rename to girepository/cmph/jenkins_hash.c diff --git a/cmph/jenkins_hash.h b/girepository/cmph/jenkins_hash.h similarity index 100% rename from cmph/jenkins_hash.h rename to girepository/cmph/jenkins_hash.h diff --git a/cmph/main.c b/girepository/cmph/main.c similarity index 100% rename from cmph/main.c rename to girepository/cmph/main.c diff --git a/cmph/meson.build b/girepository/cmph/meson.build similarity index 100% rename from cmph/meson.build rename to girepository/cmph/meson.build diff --git a/cmph/miller_rabin.c b/girepository/cmph/miller_rabin.c similarity index 100% rename from cmph/miller_rabin.c rename to girepository/cmph/miller_rabin.c diff --git a/cmph/miller_rabin.h b/girepository/cmph/miller_rabin.h similarity index 100% rename from cmph/miller_rabin.h rename to girepository/cmph/miller_rabin.h diff --git a/cmph/sdbm_hash.c b/girepository/cmph/sdbm_hash.c similarity index 100% rename from cmph/sdbm_hash.c rename to girepository/cmph/sdbm_hash.c diff --git a/cmph/sdbm_hash.h b/girepository/cmph/sdbm_hash.h similarity index 100% rename from cmph/sdbm_hash.h rename to girepository/cmph/sdbm_hash.h diff --git a/cmph/select.c b/girepository/cmph/select.c similarity index 100% rename from cmph/select.c rename to girepository/cmph/select.c diff --git a/cmph/select.h b/girepository/cmph/select.h similarity index 100% rename from cmph/select.h rename to girepository/cmph/select.h diff --git a/cmph/select_lookup_tables.h b/girepository/cmph/select_lookup_tables.h similarity index 100% rename from cmph/select_lookup_tables.h rename to girepository/cmph/select_lookup_tables.h diff --git a/cmph/vqueue.c b/girepository/cmph/vqueue.c similarity index 100% rename from cmph/vqueue.c rename to girepository/cmph/vqueue.c diff --git a/cmph/vqueue.h b/girepository/cmph/vqueue.h similarity index 100% rename from cmph/vqueue.h rename to girepository/cmph/vqueue.h diff --git a/cmph/vstack.c b/girepository/cmph/vstack.c similarity index 100% rename from cmph/vstack.c rename to girepository/cmph/vstack.c diff --git a/cmph/vstack.h b/girepository/cmph/vstack.h similarity index 100% rename from cmph/vstack.h rename to girepository/cmph/vstack.h diff --git a/cmph/wingetopt.c b/girepository/cmph/wingetopt.c similarity index 100% rename from cmph/wingetopt.c rename to girepository/cmph/wingetopt.c diff --git a/cmph/wingetopt.h b/girepository/cmph/wingetopt.h similarity index 100% rename from cmph/wingetopt.h rename to girepository/cmph/wingetopt.h diff --git a/docs.c b/girepository/docs.c similarity index 100% rename from docs.c rename to girepository/docs.c diff --git a/gdump.c b/girepository/gdump.c similarity index 100% rename from gdump.c rename to girepository/gdump.c diff --git a/gi-dump-types.c b/girepository/gi-dump-types.c similarity index 100% rename from gi-dump-types.c rename to girepository/gi-dump-types.c diff --git a/giarginfo.c b/girepository/giarginfo.c similarity index 100% rename from giarginfo.c rename to girepository/giarginfo.c diff --git a/giarginfo.h b/girepository/giarginfo.h similarity index 100% rename from giarginfo.h rename to girepository/giarginfo.h diff --git a/gibaseinfo.c b/girepository/gibaseinfo.c similarity index 100% rename from gibaseinfo.c rename to girepository/gibaseinfo.c diff --git a/gibaseinfo.h b/girepository/gibaseinfo.h similarity index 100% rename from gibaseinfo.h rename to girepository/gibaseinfo.h diff --git a/gicallableinfo.c b/girepository/gicallableinfo.c similarity index 100% rename from gicallableinfo.c rename to girepository/gicallableinfo.c diff --git a/gicallableinfo.h b/girepository/gicallableinfo.h similarity index 100% rename from gicallableinfo.h rename to girepository/gicallableinfo.h diff --git a/giconstantinfo.c b/girepository/giconstantinfo.c similarity index 100% rename from giconstantinfo.c rename to girepository/giconstantinfo.c diff --git a/giconstantinfo.h b/girepository/giconstantinfo.h similarity index 100% rename from giconstantinfo.h rename to girepository/giconstantinfo.h diff --git a/gienuminfo.c b/girepository/gienuminfo.c similarity index 100% rename from gienuminfo.c rename to girepository/gienuminfo.c diff --git a/gienuminfo.h b/girepository/gienuminfo.h similarity index 100% rename from gienuminfo.h rename to girepository/gienuminfo.h diff --git a/gifieldinfo.c b/girepository/gifieldinfo.c similarity index 100% rename from gifieldinfo.c rename to girepository/gifieldinfo.c diff --git a/gifieldinfo.h b/girepository/gifieldinfo.h similarity index 100% rename from gifieldinfo.h rename to girepository/gifieldinfo.h diff --git a/gifunctioninfo.c b/girepository/gifunctioninfo.c similarity index 100% rename from gifunctioninfo.c rename to girepository/gifunctioninfo.c diff --git a/gifunctioninfo.h b/girepository/gifunctioninfo.h similarity index 100% rename from gifunctioninfo.h rename to girepository/gifunctioninfo.h diff --git a/giinterfaceinfo.c b/girepository/giinterfaceinfo.c similarity index 100% rename from giinterfaceinfo.c rename to girepository/giinterfaceinfo.c diff --git a/giinterfaceinfo.h b/girepository/giinterfaceinfo.h similarity index 100% rename from giinterfaceinfo.h rename to girepository/giinterfaceinfo.h diff --git a/ginvoke.c b/girepository/ginvoke.c similarity index 100% rename from ginvoke.c rename to girepository/ginvoke.c diff --git a/giobjectinfo.c b/girepository/giobjectinfo.c similarity index 100% rename from giobjectinfo.c rename to girepository/giobjectinfo.c diff --git a/giobjectinfo.h b/girepository/giobjectinfo.h similarity index 100% rename from giobjectinfo.h rename to girepository/giobjectinfo.h diff --git a/gipropertyinfo.c b/girepository/gipropertyinfo.c similarity index 100% rename from gipropertyinfo.c rename to girepository/gipropertyinfo.c diff --git a/gipropertyinfo.h b/girepository/gipropertyinfo.h similarity index 100% rename from gipropertyinfo.h rename to girepository/gipropertyinfo.h diff --git a/giregisteredtypeinfo.c b/girepository/giregisteredtypeinfo.c similarity index 100% rename from giregisteredtypeinfo.c rename to girepository/giregisteredtypeinfo.c diff --git a/giregisteredtypeinfo.h b/girepository/giregisteredtypeinfo.h similarity index 100% rename from giregisteredtypeinfo.h rename to girepository/giregisteredtypeinfo.h diff --git a/girepository-private.h b/girepository/girepository-private.h similarity index 100% rename from girepository-private.h rename to girepository/girepository-private.h diff --git a/girepository.c b/girepository/girepository.c similarity index 100% rename from girepository.c rename to girepository/girepository.c diff --git a/girepository.h b/girepository/girepository.h similarity index 100% rename from girepository.h rename to girepository/girepository.h diff --git a/girffi.c b/girepository/girffi.c similarity index 100% rename from girffi.c rename to girepository/girffi.c diff --git a/girffi.h b/girepository/girffi.h similarity index 100% rename from girffi.h rename to girepository/girffi.h diff --git a/girmodule.c b/girepository/girmodule.c similarity index 100% rename from girmodule.c rename to girepository/girmodule.c diff --git a/girmodule.h b/girepository/girmodule.h similarity index 100% rename from girmodule.h rename to girepository/girmodule.h diff --git a/girnode.c b/girepository/girnode.c similarity index 100% rename from girnode.c rename to girepository/girnode.c diff --git a/girnode.h b/girepository/girnode.h similarity index 100% rename from girnode.h rename to girepository/girnode.h diff --git a/giroffsets.c b/girepository/giroffsets.c similarity index 100% rename from giroffsets.c rename to girepository/giroffsets.c diff --git a/girparser.c b/girepository/girparser.c similarity index 100% rename from girparser.c rename to girepository/girparser.c diff --git a/girparser.h b/girepository/girparser.h similarity index 100% rename from girparser.h rename to girepository/girparser.h diff --git a/girwriter.c b/girepository/girwriter.c similarity index 100% rename from girwriter.c rename to girepository/girwriter.c diff --git a/girwriter.h b/girepository/girwriter.h similarity index 100% rename from girwriter.h rename to girepository/girwriter.h diff --git a/gisignalinfo.c b/girepository/gisignalinfo.c similarity index 100% rename from gisignalinfo.c rename to girepository/gisignalinfo.c diff --git a/gisignalinfo.h b/girepository/gisignalinfo.h similarity index 100% rename from gisignalinfo.h rename to girepository/gisignalinfo.h diff --git a/gistructinfo.c b/girepository/gistructinfo.c similarity index 100% rename from gistructinfo.c rename to girepository/gistructinfo.c diff --git a/gistructinfo.h b/girepository/gistructinfo.h similarity index 100% rename from gistructinfo.h rename to girepository/gistructinfo.h diff --git a/gitypeinfo.c b/girepository/gitypeinfo.c similarity index 100% rename from gitypeinfo.c rename to girepository/gitypeinfo.c diff --git a/gitypeinfo.h b/girepository/gitypeinfo.h similarity index 100% rename from gitypeinfo.h rename to girepository/gitypeinfo.h diff --git a/gitypelib-internal.h b/girepository/gitypelib-internal.h similarity index 100% rename from gitypelib-internal.h rename to girepository/gitypelib-internal.h diff --git a/gitypelib.c b/girepository/gitypelib.c similarity index 100% rename from gitypelib.c rename to girepository/gitypelib.c diff --git a/gitypelib.h b/girepository/gitypelib.h similarity index 100% rename from gitypelib.h rename to girepository/gitypelib.h diff --git a/gitypes.h b/girepository/gitypes.h similarity index 100% rename from gitypes.h rename to girepository/gitypes.h diff --git a/giunioninfo.c b/girepository/giunioninfo.c similarity index 100% rename from giunioninfo.c rename to girepository/giunioninfo.c diff --git a/giunioninfo.h b/girepository/giunioninfo.h similarity index 100% rename from giunioninfo.h rename to girepository/giunioninfo.h diff --git a/giversion.c b/girepository/giversion.c similarity index 100% rename from giversion.c rename to girepository/giversion.c diff --git a/giversion.h.in b/girepository/giversion.h.in similarity index 100% rename from giversion.h.in rename to girepository/giversion.h.in diff --git a/giversionmacros.h b/girepository/giversionmacros.h similarity index 100% rename from giversionmacros.h rename to girepository/giversionmacros.h diff --git a/givfuncinfo.c b/girepository/givfuncinfo.c similarity index 100% rename from givfuncinfo.c rename to girepository/givfuncinfo.c diff --git a/givfuncinfo.h b/girepository/givfuncinfo.h similarity index 100% rename from givfuncinfo.h rename to girepository/givfuncinfo.h diff --git a/gthash-test.c b/girepository/gthash-test.c similarity index 100% rename from gthash-test.c rename to girepository/gthash-test.c diff --git a/gthash.c b/girepository/gthash.c similarity index 100% rename from gthash.c rename to girepository/gthash.c diff --git a/meson.build b/girepository/meson.build similarity index 100% rename from meson.build rename to girepository/meson.build