diff options
-rw-r--r-- | girepository/giobjectinfo.c | 71 | ||||
-rw-r--r-- | girepository/girparser.c | 41 | ||||
-rw-r--r-- | girepository/gitypelib.c | 9 | ||||
-rw-r--r-- | tests/scanner/Regress-1.0-C-expected/Regress.TestObj-function_ptr.page | 14 | ||||
-rw-r--r-- | tests/scanner/Regress-1.0-C-expected/Regress.TestObj.function_ptr.page | 24 | ||||
-rw-r--r-- | tests/scanner/Regress-1.0-Gjs-expected/Regress.TestObj.function_ptr.page | 19 | ||||
-rw-r--r-- | tests/scanner/Regress-1.0-Python-expected/Regress.TestObj.function_ptr.page | 21 | ||||
-rw-r--r-- | tests/scanner/Regress-1.0-expected.gir | 7 | ||||
-rw-r--r-- | tests/scanner/regress.h | 3 |
9 files changed, 159 insertions, 50 deletions
diff --git a/girepository/giobjectinfo.c b/girepository/giobjectinfo.c index 3e3b312c..d92a8615 100644 --- a/girepository/giobjectinfo.c +++ b/girepository/giobjectinfo.c @@ -48,6 +48,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/girepository/girparser.c b/girepository/girparser.c index 82005fc0..c7feb6ad 100644 --- a/girepository/girparser.c +++ b/girepository/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/girepository/gitypelib.c b/girepository/gitypelib.c index 8883496e..41b54fd8 100644 --- a/girepository/gitypelib.c +++ b/girepository/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)) diff --git a/tests/scanner/Regress-1.0-C-expected/Regress.TestObj-function_ptr.page b/tests/scanner/Regress-1.0-C-expected/Regress.TestObj-function_ptr.page new file mode 100644 index 00000000..dca9a51f --- /dev/null +++ b/tests/scanner/Regress-1.0-C-expected/Regress.TestObj-function_ptr.page @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<page id="Regress.TestObj-function_ptr" + type="topic" + style="field" + xmlns="http://projectmallard.org/1.0/" + xmlns:api="http://projectmallard.org/experimental/api/" + xmlns:ui="http://projectmallard.org/1.0/ui/"> + <info> + <link xref="Regress.TestObj" group="field" type="guide"/> + </info> + <title>Regress.TestObj->function_ptr</title> + + +</page> diff --git a/tests/scanner/Regress-1.0-C-expected/Regress.TestObj.function_ptr.page b/tests/scanner/Regress-1.0-C-expected/Regress.TestObj.function_ptr.page new file mode 100644 index 00000000..34565407 --- /dev/null +++ b/tests/scanner/Regress-1.0-C-expected/Regress.TestObj.function_ptr.page @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<page id="Regress.TestObj.function_ptr" + type="topic" + style="callback" + xmlns="http://projectmallard.org/1.0/" + xmlns:api="http://projectmallard.org/experimental/api/" + xmlns:ui="http://projectmallard.org/1.0/ui/"> + <info> + <link xref="index" group="callback" type="guide"/> + </info> + <title>Regress.TestObj.function_ptr</title> + <synopsis><code mime="text/x-csrc"> +void function_ptr (void); + </code></synopsis> + + +<terms> +<item> +<title><code>Returns</code></title> + +</item> +</terms> + +</page> diff --git a/tests/scanner/Regress-1.0-Gjs-expected/Regress.TestObj.function_ptr.page b/tests/scanner/Regress-1.0-Gjs-expected/Regress.TestObj.function_ptr.page new file mode 100644 index 00000000..d9f3754c --- /dev/null +++ b/tests/scanner/Regress-1.0-Gjs-expected/Regress.TestObj.function_ptr.page @@ -0,0 +1,19 @@ +<?xml version="1.0"?> +<page id="Regress.TestObj.function_ptr" + type="topic" + style="callback" + xmlns="http://projectmallard.org/1.0/" + xmlns:api="http://projectmallard.org/experimental/api/" + xmlns:ui="http://projectmallard.org/1.0/ui/"> + <info> + <link xref="index" group="callback" type="guide"/> + </info> + <title>Regress.TestObj.function_ptr</title> + <synopsis><code mime="text/x-gjs"> +function onfunction_ptr(): void { +} + </code></synopsis> + + + +</page> diff --git a/tests/scanner/Regress-1.0-Python-expected/Regress.TestObj.function_ptr.page b/tests/scanner/Regress-1.0-Python-expected/Regress.TestObj.function_ptr.page new file mode 100644 index 00000000..caa0c191 --- /dev/null +++ b/tests/scanner/Regress-1.0-Python-expected/Regress.TestObj.function_ptr.page @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<page id="Regress.TestObj.function_ptr" + type="topic" + style="callback" + xmlns="http://projectmallard.org/1.0/" + xmlns:api="http://projectmallard.org/experimental/api/" + xmlns:ui="http://projectmallard.org/1.0/ui/"> + <info> + <link xref="index" group="callback" type="guide"/> + </info> + <title>Regress.TestObj.function_ptr</title> + <synopsis><code mime="text/x-python"> +@returns(none) +def on_function_ptr(): + </code></synopsis> + + +<terms> +</terms> + +</page> diff --git a/tests/scanner/Regress-1.0-expected.gir b/tests/scanner/Regress-1.0-expected.gir index d25e41c8..82c11d32 100644 --- a/tests/scanner/Regress-1.0-expected.gir +++ b/tests/scanner/Regress-1.0-expected.gir @@ -3450,6 +3450,13 @@ raise an error.</doc> <field name="gtype"> <type name="GType" c:type="GType"/> </field> + <field name="function_ptr"> + <callback name="function_ptr"> + <return-value transfer-ownership="none"> + <type name="none" c:type="void"/> + </return-value> + </callback> + </field> <glib:signal name="all" when="first" no-recurse="1" diff --git a/tests/scanner/regress.h b/tests/scanner/regress.h index ad2cb1fb..004ae36e 100644 --- a/tests/scanner/regress.h +++ b/tests/scanner/regress.h @@ -488,6 +488,9 @@ struct _RegressTestObj double some_double; char* string; GType gtype; + + /* < private > */ + void (*function_ptr)(); }; typedef void (*RegressTestExternallyDefinedCallback) (RegressTestObj *obj, int someint); |