summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2010-06-16 20:34:18 -0400
committerColin Walters <walters@verbum.org>2010-06-17 13:05:59 -0400
commit5a4fa2bf5648d60d9fc0feb69080c9153b2abe02 (patch)
tree0a1f1f2c42740f4a812bfd39e32afb9d6a733c74
parent929892fa9447d2abace21d02c86bb888fc6fd3df (diff)
downloadgobject-introspection-5a4fa2bf5648d60d9fc0feb69080c9153b2abe02.tar.gz
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
-rw-r--r--docs/g-ir-scanner.16
-rw-r--r--gir/Makefile.am2
-rw-r--r--girepository/girparser.c1481
-rw-r--r--girepository/girparser.h1
-rw-r--r--giscanner/ast.py14
-rw-r--r--giscanner/girwriter.py33
-rw-r--r--giscanner/glibtransformer.py210
-rw-r--r--giscanner/scannermain.py13
-rw-r--r--giscanner/sourcescanner.py4
-rw-r--r--giscanner/transformer.py73
-rw-r--r--tests/scanner/Makefile.am2
-rw-r--r--tests/scanner/foo-1.0-expected.gir47
12 files changed, 1008 insertions, 878 deletions
diff --git a/docs/g-ir-scanner.1 b/docs/g-ir-scanner.1
index f5224bb8..5089e6b5 100644
--- a/docs/g-ir-scanner.1
+++ b/docs/g-ir-scanner.1
@@ -18,6 +18,12 @@ header file (.h). Currently only C based libraries are supported by the scanner.
.B \--help
Show help options
.TP
+.B \--warn-all
+Display warnings for public API which is not introspectable.
+.TP
+.B \--warn-error
+Make warnings be fatal errors.
+.TP
.B \--format=FORMAT
This parameters decides which the resulting format will be used.
The default value is gir.
diff --git a/gir/Makefile.am b/gir/Makefile.am
index 1d88accd..c07a239e 100644
--- a/gir/Makefile.am
+++ b/gir/Makefile.am
@@ -118,7 +118,7 @@ endif
Gio-2.0.gir: GObject-2.0.gir
Gio_2_0_gir_LIBS = $(GIO_LIBRARY)
-Gio_2_0_gir_SCANNERFLAGS = --noclosure --strip-prefix=g --c-include="gio/gio.h" --add-include-path=.
+Gio_2_0_gir_SCANNERFLAGS = --warn-all --strip-prefix=g --c-include="gio/gio.h" --add-include-path=.
Gio_2_0_gir_PACKAGES = gio-2.0 $(GIO_UNIX_PACKAGES)
Gio_2_0_gir_INCLUDES = GObject-2.0
Gio_2_0_gir_CFLAGS = \
diff --git a/girepository/girparser.c b/girepository/girparser.c
index f9c1fb66..1badfd7e 100644
--- a/girepository/girparser.c
+++ b/girepository/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 <execinfo.h>
@@ -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);
}
@@ -635,6 +636,32 @@ parse_type (ParseContext *ctx, const gchar *type)
}
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,
const gchar **attribute_names,
@@ -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;
+ const gchar *name;
+ const gchar *typename;
+ const gchar *typeinit;
+ const gchar *deprecated;
+ GIrNodeEnum *enum_;
- 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 (!((strcmp (element_name, "enumeration") == 0 && ctx->state == STATE_NAMESPACE) ||
+ (strcmp (element_name, "bitfield") == 0 && ctx->state == STATE_NAMESPACE)))
+ return FALSE;
- if (name == NULL)
- MISSING_ATTRIBUTE (context, error, element_name, "name");
- else
- {
- GIrNodeEnum *enum_;
+ if (!introspectable_prelude (context, attribute_names, attribute_values, 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;
+ 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);
- push_node (ctx, (GIrNode *) enum_);
- ctx->current_module->entries =
- g_list_append (ctx->current_module->entries, enum_);
+ if (name == NULL)
+ {
+ MISSING_ATTRIBUTE (context, error, element_name, "name");
+ return FALSE;
+ }
- state_switch (ctx, STATE_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;
- return TRUE;
- }
- return 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))
- {
- const gchar *name;
- const gchar *readable;
- const gchar *writable;
- const gchar *construct;
- const gchar *construct_only;
- const gchar *transfer;
+ 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;
- 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 (!(strcmp (element_name, "property") == 0 &&
+ (ctx->state == STATE_CLASS ||
+ ctx->state == STATE_INTERFACE)))
+ return FALSE;
- if (name == NULL)
- MISSING_ATTRIBUTE (context, error, element_name, "name");
- else
- {
- GIrNodeProperty *property;
- GIrNodeInterface *iface;
+ 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 ();
- property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY);
- ctx->current_typed = (GIrNode*) property;
+ if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, target_state))
+ return TRUE;
- ((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;
+ 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);
- parse_property_transfer (property, transfer, ctx);
+ if (name == NULL)
+ {
+ MISSING_ATTRIBUTE (context, error, element_name, "name");
+ return FALSE;
+ }
- iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
- iface->members = g_list_append (iface->members, property);
+ property = (GIrNodeProperty *) g_ir_node_new (G_IR_NODE_PROPERTY);
+ ctx->current_typed = (GIrNode*) 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 ();
- }
+ ((GIrNode *)property)->name = g_strdup (name);
- return TRUE;
- }
- return FALSE;
+ /* 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;
+ const gchar *name;
+ const gchar *value;
+ const gchar *deprecated;
+ GIrNodeEnum *enum_;
+ GIrNodeValue *value_;
- 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 (!(strcmp (element_name, "member") == 0 &&
+ ctx->state == STATE_ENUM))
+ return FALSE;
- if (name == NULL)
- MISSING_ATTRIBUTE (context, error, element_name, "name");
- else
- {
- GIrNodeEnum *enum_;
- GIrNodeValue *value_;
+ 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;
+ }
- value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE);
+ value_ = (GIrNodeValue *) g_ir_node_new (G_IR_NODE_VALUE);
- ((GIrNode *)value_)->name = g_strdup (name);
+ ((GIrNode *)value_)->name = g_strdup (name);
- value_->value = parse_value (value);
+ value_->value = parse_value (value);
- if (deprecated)
- value_->deprecated = TRUE;
- else
- value_->deprecated = FALSE;
+ if (deprecated)
+ value_->deprecated = TRUE;
+ else
+ value_->deprecated = FALSE;
- enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx);
- enum_->values = g_list_append (enum_->values, value_);
- }
+ enum_ = (GIrNodeEnum *)CURRENT_NODE (ctx);
+ enum_->values = g_list_append (enum_->values, value_);
- return TRUE;
- }
- return FALSE;
+ 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;
+ 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 ();
+ }
- name = find_attribute ("name", attribute_names, attribute_values);
- value = find_attribute ("value", attribute_names, attribute_values);
- deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
+ prev_state = ctx->state;
- if (name == NULL)
- MISSING_ATTRIBUTE (context, error, element_name, "name");
- else if (value == NULL)
- MISSING_ATTRIBUTE (context, error, element_name, "value");
- else
- {
- GIrNodeConstant *constant;
+ if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, target_state))
+ return TRUE;
- constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
+ name = find_attribute ("name", attribute_names, attribute_values);
+ value = find_attribute ("value", attribute_names, attribute_values);
+ deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
- ((GIrNode *)constant)->name = g_strdup (name);
- constant->value = g_strdup (value);
+ 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;
+ }
- ctx->current_typed = (GIrNode*) constant;
+ constant = (GIrNodeConstant *) g_ir_node_new (G_IR_NODE_CONSTANT);
- if (deprecated)
- constant->deprecated = TRUE;
- else
- constant->deprecated = FALSE;
+ ((GIrNode *)constant)->name = g_strdup (name);
+ constant->value = g_strdup (value);
- 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;
+ ctx->current_typed = (GIrNode*) constant;
- iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
- iface->members = g_list_append (iface->members, constant);
- }
+ if (deprecated)
+ constant->deprecated = TRUE;
+ else
+ constant->deprecated = FALSE;
- 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;
- }
- }
+ 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;
- return TRUE;
+ iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
+ iface->members = g_list_append (iface->members, constant);
}
- return FALSE;
+
+ 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;
+ const gchar *name;
+ const gchar *getquark;
+ const gchar *codes;
+ const gchar *deprecated;
+ GIrNodeErrorDomain *domain;
- 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 (!(strcmp (element_name, "errordomain") == 0 &&
+ ctx->state == STATE_NAMESPACE))
+ return FALSE;
- 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;
+ if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_ERRORDOMAIN))
+ return TRUE;
- 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);
+ 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 (deprecated)
- domain->deprecated = TRUE;
- else
- domain->deprecated = FALSE;
+ 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;
+ }
- push_node (ctx, (GIrNode *) domain);
- ctx->current_module->entries =
- g_list_append (ctx->current_module->entries, domain);
+ domain = (GIrNodeErrorDomain *) g_ir_node_new (G_IR_NODE_ERROR_DOMAIN);
- state_switch (ctx, STATE_ERRORDOMAIN);
- }
+ ((GIrNode *)domain)->name = g_strdup (name);
+ domain->getquark = g_strdup (getquark);
+ domain->codes = g_strdup (codes);
- return TRUE;
- }
- return FALSE;
+ 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;
+ const gchar *name;
+ const gchar *typename;
+ const gchar *typeinit;
+ const gchar *deprecated;
+ const gchar *glib_type_struct;
+ GIrNodeInterface *iface;
- 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 (!(strcmp (element_name, "interface") == 0 &&
+ ctx->state == STATE_NAMESPACE))
+ return FALSE;
- 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;
+ if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_INTERFACE))
+ 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;
+ 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");
+ 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;
+ }
- state_switch (ctx, STATE_INTERFACE);
+ 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;
- }
- return FALSE;
+ 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;
+ 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;
- 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 (!(strcmp (element_name, "class") == 0 &&
+ ctx->state == STATE_NAMESPACE))
+ return FALSE;
- 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;
+ if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_CLASS))
+ return TRUE;
- 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;
+ 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);
- iface->abstract = abstract && strcmp (abstract, "1") == 0;
+ if (name == NULL)
+ {
+ 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 && strcmp (typename, "GObject"))
+ {
+ MISSING_ATTRIBUTE (context, error, element_name, "glib:get-type");
+ return FALSE;
+ }
- push_node (ctx, (GIrNode *) iface);
- ctx->current_module->entries =
- g_list_append (ctx->current_module->entries, 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;
- state_switch (ctx, STATE_CLASS);
- }
+ iface->abstract = abstract && strcmp (abstract, "1") == 0;
- return TRUE;
- }
- return FALSE;
+ 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;
+ GIrNodeParam *param;
+ const gchar *transfer;
- param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
- param->in = FALSE;
- param->out = FALSE;
- param->retval = TRUE;
+ if (!(strcmp (element_name, "return-value") == 0 &&
+ ctx->state == STATE_FUNCTION))
+ return FALSE;
- ctx->current_typed = (GIrNode*) param;
+ param = (GIrNodeParam *)g_ir_node_new (G_IR_NODE_PARAM);
+ param->in = FALSE;
+ param->out = FALSE;
+ param->retval = TRUE;
- state_switch (ctx, STATE_FUNCTION_RETURN);
+ ctx->current_typed = (GIrNode*) param;
- transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
- parse_param_transfer (param, transfer, NULL);
+ state_switch (ctx, STATE_FUNCTION_RETURN);
- 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 ();
- }
+ transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
+ parse_param_transfer (param, transfer, NULL);
- return TRUE;
+ 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 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;
+ 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;
- 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 (!(strcmp (element_name, "glib:signal") == 0 &&
+ (ctx->state == STATE_CLASS ||
+ ctx->state == STATE_INTERFACE)))
+ return FALSE;
- if (name == NULL)
- MISSING_ATTRIBUTE (context, error, element_name, "name");
- else
- {
- GIrNodeInterface *iface;
- GIrNodeSignal *signal;
+ if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION))
+ return TRUE;
- signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL);
+ 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);
- ((GIrNode *)signal)->name = g_strdup (name);
+ if (name == NULL)
+ {
+ MISSING_ATTRIBUTE (context, error, element_name, "name");
+ return FALSE;
+ }
+ signal = (GIrNodeSignal *)g_ir_node_new (G_IR_NODE_SIGNAL);
- 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;
+ ((GIrNode *)signal)->name = g_strdup (name);
- 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;
+ 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;
- iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
- iface->members = g_list_append (iface->members, signal);
+ 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;
- push_node (ctx, (GIrNode *)signal);
- state_switch (ctx, STATE_FUNCTION);
- }
+ iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
+ iface->members = g_list_append (iface->members, signal);
- return TRUE;
- }
- return FALSE;
+ 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;
+ 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;
- 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 (!(strcmp (element_name, "virtual-method") == 0 &&
+ (ctx->state == STATE_CLASS ||
+ ctx->state == STATE_INTERFACE)))
+ return FALSE;
- if (name == NULL)
- MISSING_ATTRIBUTE (context, error, element_name, "name");
- else
- {
- GIrNodeInterface *iface;
- GIrNodeVFunc *vfunc;
+ if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_FUNCTION))
+ return TRUE;
- vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC);
+ 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);
- ((GIrNode *)vfunc)->name = g_strdup (name);
+ if (name == NULL)
+ {
+ MISSING_ATTRIBUTE (context, error, element_name, "name");
+ return FALSE;
+ }
- if (must_chain_up && strcmp (must_chain_up, "1") == 0)
- vfunc->must_chain_up = TRUE;
- else
- vfunc->must_chain_up = FALSE;
+ vfunc = (GIrNodeVFunc *)g_ir_node_new (G_IR_NODE_VFUNC);
- 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;
- }
+ ((GIrNode *)vfunc)->name = g_strdup (name);
- if (is_class_closure && strcmp (is_class_closure, "1") == 0)
- vfunc->is_class_closure = TRUE;
- else
- vfunc->is_class_closure = FALSE;
+ if (must_chain_up && strcmp (must_chain_up, "1") == 0)
+ vfunc->must_chain_up = TRUE;
+ else
+ vfunc->must_chain_up = FALSE;
- if (offset)
- vfunc->offset = atoi (offset);
- else
- vfunc->offset = 0;
+ 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;
+ }
- vfunc->invoker = g_strdup (invoker);
+ if (is_class_closure && strcmp (is_class_closure, "1") == 0)
+ vfunc->is_class_closure = TRUE;
+ else
+ vfunc->is_class_closure = FALSE;
- iface = (GIrNodeInterface *)CURRENT_NODE (ctx);
- iface->members = g_list_append (iface->members, vfunc);
+ if (offset)
+ vfunc->offset = atoi (offset);
+ else
+ vfunc->offset = 0;
- push_node (ctx, (GIrNode *)vfunc);
- state_switch (ctx, STATE_FUNCTION);
- }
+ vfunc->invoker = g_strdup (invoker);
- return TRUE;
- }
- return FALSE;
-}
+ 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,75 +2280,74 @@ 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_;
+ 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;
- 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 (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_STRUCT))
+ return TRUE;
- 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;
- }
+ 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);
- struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT);
+ 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;
+ }
- ((GIrNode *)struct_)->name = g_strdup (name ? name : "");
- if (deprecated)
- struct_->deprecated = TRUE;
- else
- struct_->deprecated = FALSE;
+ struct_ = (GIrNodeStruct *) g_ir_node_new (G_IR_NODE_STRUCT);
- if (disguised && strcmp (disguised, "1") == 0)
- struct_->disguised = TRUE;
+ ((GIrNode *)struct_)->name = g_strdup (name ? name : "");
+ if (deprecated)
+ struct_->deprecated = TRUE;
+ else
+ struct_->deprecated = FALSE;
- struct_->is_gtype_struct = gtype_struct != NULL;
+ if (disguised && strcmp (disguised, "1") == 0)
+ struct_->disguised = TRUE;
- struct_->gtype_name = g_strdup (gtype_name);
- struct_->gtype_init = g_strdup (gtype_init);
+ struct_->is_gtype_struct = gtype_struct != NULL;
- struct_->foreign = (g_strcmp0 (foreign, "1") == 0);
+ struct_->gtype_name = g_strdup (gtype_name);
+ struct_->gtype_init = g_strdup (gtype_init);
- if (ctx->node_stack == NULL)
- ctx->current_module->entries =
- g_list_append (ctx->current_module->entries, struct_);
- push_node (ctx, (GIrNode *)struct_);
+ struct_->foreign = (g_strcmp0 (foreign, "1") == 0);
- state_switch (ctx, STATE_STRUCT);
- return TRUE;
- }
- return FALSE;
+ 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,
const gchar *element_name,
@@ -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;
+ const gchar *name;
+ const gchar *deprecated;
+ const gchar *typename;
+ const gchar *typeinit;
+ GIrNodeUnion *union_;
- 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 (!(strcmp (element_name, "union") == 0 &&
+ (ctx->state == STATE_NAMESPACE ||
+ ctx->state == STATE_UNION ||
+ ctx->state == STATE_STRUCT ||
+ ctx->state == STATE_CLASS)))
+ return FALSE;
- if (name == NULL && ctx->node_stack == NULL)
- MISSING_ATTRIBUTE (context, error, element_name, "name");
- else
- {
- GIrNodeUnion *union_;
+ if (!introspectable_prelude (context, attribute_names, attribute_values, ctx, STATE_UNION))
+ return TRUE;
- union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION);
+ 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);
- ((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 (name == NULL && ctx->node_stack == NULL)
+ {
+ MISSING_ATTRIBUTE (context, error, element_name, "name");
+ return FALSE;
+ }
- if (ctx->node_stack == NULL)
- ctx->current_module->entries =
- g_list_append (ctx->current_module->entries, union_);
- push_node (ctx, (GIrNode *)union_);
+ union_ = (GIrNodeUnion *) g_ir_node_new (G_IR_NODE_UNION);
- state_switch (ctx, STATE_UNION);
- }
- return TRUE;
- }
- return FALSE;
+ ((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;
-
- 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);
- }
+ const gchar *type;
+ const gchar *offset;
+ if (!(strcmp (element_name, "discriminator") == 0 &&
+ ctx->state == STATE_UNION))
+ return FALSE;
- return TRUE;
+ 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;
}
- 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;
}
- g_free (girpath);
- modules = g_ir_parser_parse_string (ctx->parser, name, buffer, length, error);
- success = error != NULL;
+ 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);
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/girepository/girparser.h b/girepository/girparser.h
index ac0d216b..6fca1b3d 100644
--- a/girepository/girparser.h
+++ b/girepository/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);
diff --git a/giscanner/ast.py b/giscanner/ast.py
index 0e9f112d..a70f2d8b 100644
--- a/giscanner/ast.py
+++ b/giscanner/ast.py
@@ -173,12 +173,14 @@ class Node(object):
def __init__(self, name=None):
self.name = name
- self.attributes = [] # (key, value)*
self.skip = False
+ self.introspectable = True
+ self.attributes = [] # (key, value)*
self.deprecated = None
self.deprecated_version = None
self.version = None
self.foreign = False
+ self.file_positions = set()
def __cmp__(self, other):
return cmp(self.name, other.name)
@@ -189,6 +191,16 @@ class Node(object):
def remove_matching_children(self, pred):
pass
+ def inherit_file_positions(self, node):
+ self.file_positions.update(node.file_positions)
+
+ def add_file_position(self, filename, line, column):
+ self.file_positions.add((filename, line, column))
+
+ def add_symbol_reference(self, symbol):
+ if symbol.source_filename:
+ self.add_file_position(symbol.source_filename, symbol.line, -1)
+
class Namespace(Node):
def __init__(self, name, version):
diff --git a/giscanner/girwriter.py b/giscanner/girwriter.py
index 11f9dbe9..9b48d4ef 100644
--- a/giscanner/girwriter.py
+++ b/giscanner/girwriter.py
@@ -31,7 +31,7 @@ from .xmlwriter import XMLWriter
# Bump this for *incompatible* changes to the .gir.
# Compatible changes we just make inline
-COMPATIBLE_GIR_VERSION = '1.0'
+COMPATIBLE_GIR_VERSION = '1.1'
class GIRWriter(XMLWriter):
@@ -99,8 +99,7 @@ and/or use gtk-doc annotations. ''')
else:
return cmp(a, b)
for node in sorted(namespace.nodes, cmp=nscmp):
- if not node.skip:
- self._write_node(node)
+ self._write_node(node)
def _write_node(self, node):
if isinstance(node, Function):
@@ -137,7 +136,9 @@ and/or use gtk-doc annotations. ''')
for key, value in node.attributes:
self.write_tag('attribute', [('name', key), ('value', value)])
- def _append_deprecated(self, node, attrs):
+ def _append_node_generic(self, node, attrs):
+ if node.skip or not node.introspectable:
+ attrs.append(('introspectable', '0'))
if node.deprecated:
attrs.append(('deprecated', node.deprecated))
if node.deprecated_version:
@@ -155,14 +156,12 @@ and/or use gtk-doc annotations. ''')
self.write_tag('alias', attrs)
def _write_callable(self, callable, tag_name, extra_attrs):
- if callable.skip:
- return
attrs = [('name', callable.name)]
attrs.extend(extra_attrs)
if callable.doc:
attrs.append(('doc', callable.doc))
self._append_version(callable, attrs)
- self._append_deprecated(callable, attrs)
+ self._append_node_generic(callable, attrs)
self._append_throws(callable, attrs)
with self.tagcontext(tag_name, attrs):
self._write_attributes(callable)
@@ -282,7 +281,7 @@ and/or use gtk-doc annotations. ''')
if enum.doc:
attrs.append(('doc', enum.doc))
self._append_version(enum, attrs)
- self._append_deprecated(enum, attrs)
+ self._append_node_generic(enum, attrs)
if isinstance(enum, GLibEnum):
attrs.extend([('glib:type-name', enum.type_name),
('glib:get-type', enum.get_type),
@@ -302,7 +301,7 @@ and/or use gtk-doc annotations. ''')
if bitfield.doc:
attrs.append(('doc', bitfield.doc))
self._append_version(bitfield, attrs)
- self._append_deprecated(bitfield, attrs)
+ self._append_node_generic(bitfield, attrs)
if isinstance(bitfield, GLibFlags):
attrs.extend([('glib:type-name', bitfield.type_name),
('glib:get-type', bitfield.get_type),
@@ -315,8 +314,6 @@ and/or use gtk-doc annotations. ''')
self._write_member(member)
def _write_member(self, member):
- if member.skip:
- return
attrs = [('name', member.name),
('value', str(member.value)),
('c:identifier', member.symbol)]
@@ -336,7 +333,7 @@ and/or use gtk-doc annotations. ''')
if node.doc:
attrs.append(('doc', node.doc))
self._append_version(node, attrs)
- self._append_deprecated(node, attrs)
+ self._append_node_generic(node, attrs)
if isinstance(node, Class):
tag_name = 'class'
if node.parent is not None:
@@ -389,11 +386,9 @@ and/or use gtk-doc annotations. ''')
self._write_method(method)
def _write_property(self, prop):
- if prop.skip:
- return
attrs = [('name', prop.name)]
self._append_version(prop, attrs)
- self._append_deprecated(prop, attrs)
+ self._append_node_generic(prop, attrs)
# Properties are assumed to be readable (see also generate.c)
if not prop.readable:
attrs.append(('readable', '0'))
@@ -443,7 +438,7 @@ and/or use gtk-doc annotations. ''')
if record.doc:
attrs.append(('doc', record.doc))
self._append_version(record, attrs)
- self._append_deprecated(record, attrs)
+ self._append_node_generic(record, attrs)
if isinstance(record, GLibBoxed):
attrs.extend(self._boxed_attrs(record))
with self.tagcontext('record', attrs):
@@ -465,7 +460,7 @@ and/or use gtk-doc annotations. ''')
if union.doc:
attrs.append(('doc', union.doc))
self._append_version(union, attrs)
- self._append_deprecated(union, attrs)
+ self._append_node_generic(union, attrs)
if isinstance(union, GLibBoxed):
attrs.extend(self._boxed_attrs(union))
with self.tagcontext('union', attrs):
@@ -511,13 +506,11 @@ and/or use gtk-doc annotations. ''')
self._write_type(field.type)
def _write_signal(self, signal):
- if signal.skip:
- return
attrs = [('name', signal.name)]
if signal.doc:
attrs.append(('doc', signal.doc))
self._append_version(signal, attrs)
- self._append_deprecated(signal, attrs)
+ self._append_node_generic(signal, attrs)
with self.tagcontext('glib:signal', attrs):
self._write_attributes(signal)
self._write_return_type(signal.retval)
diff --git a/giscanner/glibtransformer.py b/giscanner/glibtransformer.py
index 42488251..7035eb3f 100644
--- a/giscanner/glibtransformer.py
+++ b/giscanner/glibtransformer.py
@@ -25,10 +25,12 @@ import tempfile
import shutil
import subprocess
-from .ast import (Alias, Bitfield, Callback, Constant, Enum, Function, Member,
- Namespace, Parameter, Property, Record, Return, Type, Union,
- Field, VFunction, type_name_from_ctype,
- default_array_types, TYPE_UINT8, PARAM_TRANSFER_FULL, Array)
+from .ast import (Alias, Bitfield, Callable, Callback, Class, Constant, Enum,
+ Function, Interface, Member, Namespace, Node, Parameter,
+ Property, Record, Return, Type, TypeContainer, Union,
+ Field, VFunction, type_name_from_ctype, default_array_types,
+ TYPE_UINT8, PARAM_TRANSFER_FULL, Array, List,
+ Map, Varargs)
from .transformer import Names
from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember, GLibFlags,
GLibInterface, GLibObject, GLibSignal, GLibBoxedStruct,
@@ -112,18 +114,6 @@ class GLibTransformer(object):
# Public API
- def _print_statistics(self):
- nodes = list(self._names.names.itervalues())
-
- def count_type(otype):
- return len([x for x in nodes
- if isinstance(x[1], otype)])
- objectcount = count_type(GLibObject)
- ifacecount = count_type(GLibInterface)
- enumcount = count_type(GLibEnum)
- print " %d nodes; %d objects, %d interfaces, %d enums" \
- % (len(nodes), objectcount, ifacecount, enumcount)
-
def init_parse(self):
"""Do parsing steps that don't involve the introspection binary
@@ -170,7 +160,8 @@ class GLibTransformer(object):
try:
self._resolve_node(node)
except KeyError, e:
- #print "WARNING: DELETING node %s: %s" % (node.name, e)
+ self._transformer.log_node_warning(node,
+"""Unresolvable entry %r""" % (e, ))
self._remove_attribute(node.name)
# Another pass, since we need to have the methods parsed
# in order to correctly modify them after class/record
@@ -181,12 +172,11 @@ class GLibTransformer(object):
self._pair_class_record(node)
for (ns, alias) in self._names.aliases.itervalues():
self._resolve_alias(alias)
+
self._resolve_quarks()
- # Fourth pass: ensure all types are known
- if not self._noclosure:
- self._resolve_types(nodes)
- #self._validate(nodes)
+ # Our final pass replacing types
+ self._resolve_types(nodes)
# Create a new namespace with what we found
namespace = Namespace(self._namespace_name, self._namespace_version)
@@ -272,9 +262,8 @@ class GLibTransformer(object):
if enum is not None:
enum.error_quark = node.symbol
else:
- print "WARNING: " + \
- "Couldn't find corresponding enumeration for %s" % \
- (node.symbol, )
+ self._transformer.log_node_warning(node,
+"""Couldn't find corresponding enumeration""")
# Helper functions
@@ -425,7 +414,7 @@ class GLibTransformer(object):
'GType',
'GObject.Type',
'Gtk.Type']:
- print ("Warning: *_get_type function returns '%r'"
+ self._transformer.log_("Warning: *_get_type function returns '%r'"
", not GObject.Type") % (func.retval.type.name, )
return False
@@ -668,6 +657,7 @@ class GLibTransformer(object):
if matched_signal:
continue
vfunc = VFunction.from_callback(field)
+ vfunc.inherit_file_positions(field)
pair_class.virtual_methods.append(vfunc)
# Take the set of virtual methods we found, and try
@@ -685,6 +675,7 @@ class GLibTransformer(object):
self._remove_attribute(class_struct.name)
self._add_attribute(gclass_struct, True)
pair_class.glib_type_struct = gclass_struct
+ pair_class.inherit_file_positions(class_struct)
gclass_struct.is_gtype_struct_for = name
# Introspection
@@ -829,6 +820,90 @@ class GLibTransformer(object):
# (see also _pair_class_record and transformer.py)
field.writable = False
+ def _pair_boxed_type(self, boxed):
+ name = self._transformer.remove_prefix(boxed.type_name)
+ pair_node = self._get_attribute(name)
+ if not pair_node:
+ boxed_item = GLibBoxedOther(name, boxed.type_name,
+ boxed.get_type)
+ elif isinstance(pair_node, Record):
+ boxed_item = GLibBoxedStruct(pair_node.name, boxed.type_name,
+ boxed.get_type)
+ boxed_item.inherit_file_positions(pair_node)
+ boxed_item.fields = pair_node.fields
+ elif isinstance(pair_node, Union):
+ boxed_item = GLibBoxedUnion(pair_node.name, boxed.type_name,
+ boxed.get_type)
+ boxed_item.inherit_file_positions(pair_node)
+ boxed_item.fields = pair_node.fields
+ else:
+ return False
+ self._add_attribute(boxed_item, replace=True)
+
+ # Node walking
+
+ def _walk(self, node, callback, chain):
+ if not isinstance(node, Node):
+ return
+ if not callback(node, chain):
+ return
+ chain.append(node)
+ def _subwalk(subnode):
+ self._walk(subnode, callback, chain)
+ if isinstance(node, (Callback, Callable)):
+ _subwalk(node.retval)
+ for parameter in node.parameters:
+ _subwalk(parameter)
+ elif isinstance(node, (Array, List)):
+ _subwalk(node.element_type)
+ elif isinstance(node, Map):
+ _subwalk(node.key_type)
+ _subwalk(node.value_type)
+ elif isinstance(node, Bitfield):
+ pass
+ elif isinstance(node, Record):
+ for ctor in node.constructors:
+ _subwalk(ctor)
+ for func in node.methods:
+ _subwalk(func)
+ elif isinstance(node, Field):
+ _subwalk(node.type)
+ elif isinstance(node, Class):
+ for meth in node.methods:
+ _subwalk(meth)
+ for meth in node.virtual_methods:
+ _subwalk(meth)
+ for meth in node.static_methods:
+ _subwalk(meth)
+ for ctor in node.constructors:
+ _subwalk(ctor)
+ for prop in node.properties:
+ _subwalk(prop)
+ for field in node.fields:
+ _subwalk(field)
+ elif isinstance(node, Interface):
+ for meth in node.methods:
+ _subwalk(meth)
+ for meth in node.virtual_methods:
+ _subwalk(meth)
+ for prop in node.properties:
+ _subwalk(prop)
+ for field in node.fields:
+ _subwalk(field)
+ elif isinstance(node, Constant):
+ _subwalk(node.type)
+ elif isinstance(node, Union):
+ for ctor in node.constructors:
+ _subwalk(ctor)
+ for meth in node.methods:
+ _subwalk(meth)
+
+ if isinstance(node, (GLibObject, GLibInterface)):
+ for sig in node.signals:
+ _subwalk(sig)
+
+ chain.pop()
+
# Resolver
def _resolve_type_name(self, type_name, ctype=None):
@@ -879,24 +954,6 @@ class GLibTransformer(object):
return
self._resolve_function(func)
- def _pair_boxed_type(self, boxed):
- name = self._transformer.remove_prefix(boxed.type_name)
- pair_node = self._get_attribute(name)
- if not pair_node:
- boxed_item = GLibBoxedOther(name, boxed.type_name,
- boxed.get_type)
- elif isinstance(pair_node, Record):
- boxed_item = GLibBoxedStruct(pair_node.name, boxed.type_name,
- boxed.get_type)
- boxed_item.fields = pair_node.fields
- elif isinstance(pair_node, Union):
- boxed_item = GLibBoxedUnion(pair_node.name, boxed.type_name,
- boxed.get_type)
- boxed_item.fields = pair_node.fields
- else:
- return False
- self._add_attribute(boxed_item, replace=True)
-
def _resolve_record(self, node):
for field in node.fields:
self._resolve_field(field)
@@ -914,8 +971,8 @@ class GLibTransformer(object):
self._names)
except KeyError, e:
if allow_unknown:
- print "WARNING: Skipping unknown interface %s" % \
- (item.target, )
+ self._transformer.log_warning(
+"""Skipping unknown interface %s""" % (item.target, ))
return None
else:
raise
@@ -1028,7 +1085,6 @@ class GLibTransformer(object):
while True:
initlen = len(nodes)
- #print "Type resolution; pass=%d" % (i, )
nodes = list(self._names.names.itervalues())
for node in nodes:
try:
@@ -1039,20 +1095,62 @@ class GLibTransformer(object):
if len(nodes) == initlen:
break
i += 1
- self._print_statistics()
self._validating = False
# Validation
- def _validate_interface(self, iface):
- for vfunc in iface.virtual_methods:
- if not vfunc.invoker:
- print ("warning: Interface %r virtual function %r " + \
- "has no known invoker") % (iface.name, vfunc.name)
+ def _interface_vfunc_check(self, node, stack):
+ if isinstance(node, GLibInterface):
+ for vfunc in node.virtual_methods:
+ if not vfunc.invoker:
+ self._transformer.log_node_warning(vfunc,
+"""Virtual function %r has no known invoker""" % (vfunc.name, ),
+ context=node)
+
+ def _introspectable_analysis(self, node, stack):
+ if isinstance(node, TypeContainer):
+ parent = stack[-1]
+ if isinstance(node.type, Varargs):
+ parent.introspectable = False
+ elif not isinstance(node.type, List) and \
+ (node.type.name == 'GLib.List' or
+ (self._transformer._namespace.name == 'GLib'
+ and node.type.name == 'List')):
+ if isinstance(node, Parameter):
+ self._transformer.log_node_warning(parent,
+"""Missing (element-type) annotation on argument %r""" % (node.name, ),
+ context=parent)
+ else:
+ self._transformer.log_node_warning(parent,
+"""Missing (element-type) annotation on return value""", context=parent)
+ parent.introspectable = False
+
+ def _analyze_node(self, node, stack):
+ if node.skip:
+ return False
+ # Combine one-pass checks here
+ self._interface_vfunc_check(node, stack)
+ # Our first pass for scriptability
+ self._introspectable_analysis(node, stack)
+ return True
+
+ def _introspectable_pass2(self, node, stack):
+ if node.skip:
+ return False
+ # In the second introspectable pass, we propagate introspectablity;
+ # for example, a varargs callback as an argument to a function
+ # makes the whole function unintrospectable
+ if isinstance(node, TypeContainer):
+ parent = stack[-1]
+ target = self._lookup_node(node.type.name)
+ if target and not target.introspectable:
+ parent.introspectable = False
+ return True
# This function is called at the very end, before we hand back the
# completed namespace to the writer. Add static analysis checks here.
- def _validate(self, nodes):
- for (name, node) in nodes:
- if isinstance(node, GLibInterface):
- self._validate_interface(node)
+ def final_analyze(self):
+ for (ns, node) in self._names.names.itervalues():
+ self._walk(node, self._analyze_node, [])
+ for (ns, node) in self._names.names.itervalues():
+ self._walk(node, self._introspectable_pass2, [])
diff --git a/giscanner/scannermain.py b/giscanner/scannermain.py
index 44c0287d..be590f1a 100644
--- a/giscanner/scannermain.py
+++ b/giscanner/scannermain.py
@@ -87,6 +87,12 @@ def _get_option_parser():
parser.add_option("", "--pkg-export",
action="append", dest="packages_export", default=[],
help="Associated pkg-config packages for this library")
+ parser.add_option('', "--warn-all",
+ action="store_true", dest="warn_all", default=False,
+ help="If true, enable all warnings for introspection")
+ parser.add_option('', "--warn-error",
+ action="store_true", dest="warn_fatal",
+ help="Turn warnings into fatal errors")
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose",
help="be verbose")
@@ -271,6 +277,8 @@ def scanner_main(args):
transformer.set_strip_prefix(options.strip_prefix)
else:
transformer.set_strip_prefix(options.namespace_name)
+ if options.warn_all:
+ transformer.enable_warnings(True)
transformer.set_include_paths(options.include_paths)
shown_include_warning = False
for include in options.includes:
@@ -328,6 +336,11 @@ def scanner_main(args):
except InvalidAnnotationError, e:
raise SystemExit("ERROR in annotation: %s" % (str(e), ))
+ glibtransformer.final_analyze()
+
+ if options.warn_fatal and transformer.did_warn():
+ return 1
+
# Write out AST
if options.packages_export:
exported_packages = options.packages_export
diff --git a/giscanner/sourcescanner.py b/giscanner/sourcescanner.py
index 7b06478d..acfc0485 100644
--- a/giscanner/sourcescanner.py
+++ b/giscanner/sourcescanner.py
@@ -188,6 +188,10 @@ class SourceSymbol(object):
def source_filename(self):
return self._symbol.source_filename
+ @property
+ def line(self):
+ return self._symbol.line
+
class SourceScanner(object):
diff --git a/giscanner/transformer.py b/giscanner/transformer.py
index fbc38d5b..319e43cb 100644
--- a/giscanner/transformer.py
+++ b/giscanner/transformer.py
@@ -65,6 +65,7 @@ class Names(object):
class Transformer(object):
def __init__(self, cachestore, namespace_name, namespace_version):
+ self._cwd = os.getcwd() + os.sep
self._cachestore = cachestore
self.generator = None
self._namespace = Namespace(namespace_name, namespace_version)
@@ -72,6 +73,8 @@ class Transformer(object):
self._pkg_config_packages = set()
self._typedefs_ns = {}
self._strip_prefix = ''
+ self._enable_warnings = False
+ self._warned = False
self._includes = set()
self._includepaths = []
@@ -87,6 +90,12 @@ class Transformer(object):
def get_strip_prefix(self):
return self._strip_prefix
+ def enable_warnings(self, enable):
+ self._enable_warnings = enable
+
+ def did_warn(self):
+ return self._warned
+
def get_pkgconfig_packages(self):
return self._pkg_config_packages
@@ -115,6 +124,58 @@ class Transformer(object):
# Private
+ def log_warning(self, text, file_positions=None, prefix=None):
+ """Log a warning, using optional file positioning information.
+If the warning is related to a Node type, see log_node_warning()."""
+ if not self._enable_warnings:
+ return
+
+ if file_positions is None or len(file_positions) == 0:
+ target_file_positions = [('<unknown>', -1, -1)]
+ else:
+ target_file_positions = file_positions
+
+ for (filename, line, column) in target_file_positions:
+ if filename.startswith(self._cwd):
+ filename = filename[len(self._cwd):]
+ if column != -1:
+ position = '%s:%d:%d' % (filename, line, column)
+ elif line != -1:
+ position = '%s:%d' % (filename, line, )
+ else:
+ position = '%s:' % (filename, )
+
+ if prefix:
+ print >>sys.stderr, \
+'''%s: warning: ns=%r %s: %s''' % (position, self._namespace.name,
+ prefix, text)
+ else:
+ print >>sys.stderr, \
+'''%s: warning: ns=%r: %s''' % (position, self._namespace.name, text)
+
+ def log_symbol_warning(self, symbol, text):
+ """Log a warning in the context of the given symbol."""
+ file_positions = [(symbol.source_filename, symbol.line, -1)]
+ prefix = "symbol=%r" % (symbol.ident, )
+ self.log_warning(text, file_positions, prefix=prefix)
+
+ def log_node_warning(self, node, text, context=None):
+ """Log a warning, using information about file positions from
+the given node. The optional context argument, if given, should be
+another Node type which will also be displayed. If no file position
+information is available from the node, the position data from the
+context will be used."""
+ if len(node.file_positions) == 0 and \
+ (context is not None) and len(context.file_positions) > 0:
+ file_positions = context.file_positions
+ else:
+ file_positions = node.file_positions
+
+ if context:
+ text = "context=%r %s" % (context.name, text)
+
+ self.log_warning(text, file_positions)
+
def _find_include(self, include):
searchdirs = self._includepaths[:]
for path in _xdg_data_dirs:
@@ -261,12 +322,15 @@ class Transformer(object):
else:
klass = Enum
node = klass(enum_name, symbol.ident, members)
+ node.add_symbol_reference(symbol)
self._names.type_names[symbol.ident] = (None, node)
return node
def _create_object(self, symbol):
- return Member(symbol.ident, symbol.base_type.name,
+ node = Member(symbol.ident, symbol.base_type.name,
symbol.ident)
+ node.add_symbol_reference(symbol)
+ return node
def _type_is_callback(self, type):
if isinstance(type, Callback):
@@ -327,6 +391,7 @@ class Transformer(object):
self._augment_callback_params(parameters)
name = self._strip_namespace_func(symbol.ident)
func = Function(name, return_, parameters, symbol.ident)
+ func.add_symbol_reference(symbol)
return func
def _create_source_type(self, source_type):
@@ -386,6 +451,7 @@ class Transformer(object):
# (except for Objects, see also glibtransformer.py)
node = Field(symbol.ident, ftype, ftype.name,
readable=True, writable=True, bits=symbol.const_int)
+ node.add_symbol_reference(symbol)
return node
def _create_typedef(self, symbol):
@@ -523,11 +589,13 @@ class Transformer(object):
raise AssertionError()
const = Constant(name, type_name, value)
+ const.add_symbol_reference(symbol)
return const
def _create_typedef_struct(self, symbol, disguised=False):
name = self.remove_prefix(symbol.ident)
struct = Struct(name, symbol.ident, disguised)
+ struct.add_symbol_reference(symbol)
self._typedefs_ns[symbol.ident] = struct
self._create_struct(symbol)
return struct
@@ -535,6 +603,7 @@ class Transformer(object):
def _create_typedef_union(self, symbol):
name = self.remove_prefix(symbol.ident)
union = Union(name, symbol.ident)
+ union.add_symbol_reference(symbol)
self._typedefs_ns[symbol.ident] = union
self._create_union(symbol)
return union
@@ -570,6 +639,7 @@ class Transformer(object):
if field:
compound.fields.append(field)
+ compound.add_symbol_reference(symbol)
return compound
def _create_struct(self, symbol, anonymous=False):
@@ -593,6 +663,7 @@ class Transformer(object):
else:
name = self.remove_prefix(symbol.ident)
callback = Callback(name, retval, parameters, symbol.ident)
+ callback.add_symbol_reference(symbol)
return callback
diff --git a/tests/scanner/Makefile.am b/tests/scanner/Makefile.am
index 483e5417..522f8a56 100644
--- a/tests/scanner/Makefile.am
+++ b/tests/scanner/Makefile.am
@@ -1,6 +1,8 @@
include $(top_srcdir)/common.mk
include $(top_srcdir)/Makefile.introspection
+INTROSPECTION_SCANNER_ARGS += --warn-all --warn-error
+
# We need to build a shared library, which can be dlopened
# it does not work with noinst_LTLIBRARIES
testlib_LTLIBRARIES = \
diff --git a/tests/scanner/foo-1.0-expected.gir b/tests/scanner/foo-1.0-expected.gir
index 07a2efe5..68896c11 100644
--- a/tests/scanner/foo-1.0-expected.gir
+++ b/tests/scanner/foo-1.0-expected.gir
@@ -360,7 +360,9 @@ uses a C sugar return type.">
</parameter>
</parameters>
</method>
- <method name="take_all" c:identifier="foo_object_take_all">
+ <method name="take_all"
+ c:identifier="foo_object_take_all"
+ introspectable="0">
<return-value transfer-ownership="none">
<type name="none" c:type="void"/>
</return-value>
@@ -449,6 +451,14 @@ uses a C sugar return type.">
</parameter>
</parameters>
</method>
+ <method name="skipped_method"
+ c:identifier="foo_object_skipped_method"
+ doc="This is only useful from C."
+ introspectable="0">
+ <return-value transfer-ownership="none">
+ <type name="none" c:type="void"/>
+ </return-value>
+ </method>
<property name="string"
writable="1"
construct="1"
@@ -569,6 +579,14 @@ uses a C sugar return type.">
<constant name="SUCCESS_INT" value="4408">
<type name="int"/>
</constant>
+ <enumeration name="Skippable"
+ doc="Some type that is only interesting from C and should not be
+exposed to language bindings."
+ introspectable="0"
+ c:type="FooSkippable">
+ <member name="one" value="0" c:identifier="FOO_SKIPPABLE_ONE"/>
+ <member name="two" value="1" c:identifier="FOO_SKIPPABLE_TWO"/>
+ </enumeration>
<enumeration name="StackLayer" c:type="FooStackLayer">
<member name="desktop" value="0" c:identifier="FOO_LAYER_DESKTOP"/>
<member name="bottom" value="1" c:identifier="FOO_LAYER_BOTTOM"/>
@@ -697,7 +715,9 @@ uses a C sugar return type.">
<type name="utility.Struct" c:type="UtilityStruct"/>
</field>
</record>
- <callback name="VarargsCallback" c:type="FooVarargsCallback">
+ <callback name="VarargsCallback"
+ c:type="FooVarargsCallback"
+ introspectable="0">
<return-value transfer-ownership="none">
<type name="none" c:type="void"/>
</return-value>
@@ -797,6 +817,20 @@ uses a C sugar return type.">
</parameter>
</parameters>
</function>
+ <function name="skip_me"
+ c:identifier="foo_skip_me"
+ doc="Does something that&apos;s only interesting from C and should not be
+exposed to language bindings."
+ introspectable="0">
+ <return-value transfer-ownership="none">
+ <type name="none" c:type="void"/>
+ </return-value>
+ <parameters>
+ <parameter name="fs" transfer-ownership="none">
+ <type name="Skippable" c:type="FooSkippable"/>
+ </parameter>
+ </parameters>
+ </function>
<function name="test_array" c:identifier="foo_test_array">
<return-value transfer-ownership="container">
<array name="GLib.Array" c:type="GArray*">
@@ -885,7 +919,8 @@ uses a C sugar return type.">
</parameters>
</function>
<function name="test_varargs_callback"
- c:identifier="foo_test_varargs_callback">
+ c:identifier="foo_test_varargs_callback"
+ introspectable="0">
<return-value transfer-ownership="none">
<type name="none" c:type="void"/>
</return-value>
@@ -899,7 +934,8 @@ uses a C sugar return type.">
</parameters>
</function>
<function name="test_varargs_callback2"
- c:identifier="foo_test_varargs_callback2">
+ c:identifier="foo_test_varargs_callback2"
+ introspectable="0">
<return-value transfer-ownership="none">
<type name="none" c:type="void"/>
</return-value>
@@ -910,7 +946,8 @@ uses a C sugar return type.">
</parameters>
</function>
<function name="test_varargs_callback3"
- c:identifier="foo_test_varargs_callback3">
+ c:identifier="foo_test_varargs_callback3"
+ introspectable="0">
<return-value transfer-ownership="none">
<type name="none" c:type="void"/>
</return-value>