+++ /dev/null
-/* GObject introspection: scanner
- *
- * Copyright (C) 2007-2008 Jürg Billeter
- * Copyright (C) 2007 Johan Dahlin
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author:
- * Jürg Billeter <j@bitron.ch>
- */
-
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-#include <glib.h>
-#include <glib/gstdio.h>
-#include <glib-object.h>
-#include <sys/wait.h> /* waitpid */
-#include <gmodule.h>
-#include "sourcescanner.h"
-#include "scanner.h"
-#include "girparser.h"
-#include "girmodule.h"
-#include "girnode.h"
-#include "girwriter.h"
-#include "grealpath.h"
-
-typedef GType (*TypeFunction) (void);
-
-static void g_igenerator_parse_macros (GIGenerator * igenerator);
-
-static GIGenerator *
-g_igenerator_new (const gchar *namespace,
- const gchar *shared_library)
-{
- GIGenerator *igenerator = g_new0 (GIGenerator, 1);
- igenerator->namespace = g_strdup (namespace);
- igenerator->shared_library = g_strdup (shared_library);
- igenerator->lower_case_namespace =
- g_ascii_strdown (igenerator->namespace, -1);
- igenerator->module = g_idl_module_new (namespace, shared_library);
-
- igenerator->type_map = g_hash_table_new (g_str_hash, g_str_equal);
- igenerator->type_by_lower_case_prefix =
- g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
- igenerator->symbols = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
- igenerator->scanner = gi_source_scanner_new ();
-
- return igenerator;
-}
-
-static void
-g_igenerator_free (GIGenerator *generator)
-{
- g_free (generator->namespace);
- g_free (generator->shared_library);
- g_free (generator->lower_case_namespace);
-
- g_idl_module_free (generator->module);
-
- g_list_foreach (generator->get_type_symbols, (GFunc)g_free, NULL);
- g_list_free (generator->get_type_symbols);
-
- g_hash_table_destroy (generator->type_by_lower_case_prefix);
-
- g_hash_table_destroy (generator->symbols);
-
- g_free (generator);
-}
-
-static GIrNodeType *
-create_node_from_gtype (GType type_id)
-{
- GIrNodeType *node;
- GType fundamental;
-
- node = (GIrNodeType *) g_idl_node_new (G_IR_NODE_TYPE);
-
- fundamental = g_type_fundamental (type_id);
- switch (fundamental)
- {
- case G_TYPE_STRING:
- node->unparsed = g_strdup ("char*");
- break;
- case G_TYPE_INTERFACE:
- case G_TYPE_BOXED:
- case G_TYPE_OBJECT:
- node->unparsed = g_strdup_printf ("%s*", g_type_name (type_id));
- break;
- case G_TYPE_PARAM:
- node->unparsed = g_strdup ("GParamSpec*");
- break;
- default:
- if (fundamental == G_TYPE_STRV)
- node->unparsed = g_strdup ("char*[]");
- else
- node->unparsed = g_strdup (g_type_name (type_id));
- break;
- }
-
- return node;
-}
-
-static GIrNodeType *
-create_node_from_ctype (GISourceType * ctype)
-{
- GIrNodeType *node;
-
- node = (GIrNodeType *) g_idl_node_new (G_IR_NODE_TYPE);
-
- switch (ctype->type)
- {
- case CTYPE_VOID:
- node->unparsed = g_strdup ("void");
- break;
- case CTYPE_BASIC_TYPE:
- node->unparsed = g_strdup (ctype->name);
- break;
- case CTYPE_TYPEDEF:
- node->unparsed = g_strdup (ctype->name);
- break;
- case CTYPE_STRUCT:
- if (ctype->name == NULL)
- /* anonymous struct */
- node->unparsed = g_strdup ("gpointer");
- else
- node->unparsed = g_strdup_printf ("struct %s", ctype->name);
- break;
- case CTYPE_UNION:
- if (ctype->name == NULL)
- /* anonymous union */
- node->unparsed = g_strdup ("gpointer");
- else
- node->unparsed = g_strdup_printf ("union %s", ctype->name);
- break;
- case CTYPE_ENUM:
- if (ctype->name == NULL)
- /* anonymous enum */
- node->unparsed = g_strdup ("gint");
- else
- node->unparsed = g_strdup_printf ("enum %s", ctype->name);
- break;
- case CTYPE_POINTER:
- if (ctype->base_type->type == CTYPE_FUNCTION)
- /* anonymous function pointer */
- node->unparsed = g_strdup ("GCallback");
- else
- {
- GIrNodeType *gibasetype = create_node_from_ctype (ctype->base_type);
- node->unparsed = g_strdup_printf ("%s*", gibasetype->unparsed);
- }
- break;
- case CTYPE_ARRAY:
- {
- GIrNodeType *gibasetype = create_node_from_ctype (ctype->base_type);
- node->unparsed = g_strdup_printf ("%s[]", gibasetype->unparsed);
- break;
- }
- default:
- node->unparsed = g_strdup ("unknown");
- break;
- }
-
- return node;
-}
-
-static char *
-str_replace (const char *str, const char *needle, const char *replacement)
-{
- char **strings = g_strsplit (str, needle, 0);
- char *result = g_strjoinv (replacement, strings);
- g_strfreev (strings);
- return result;
-}
-
-static void
-g_igenerator_process_properties (GIGenerator * igenerator,
- GIrNodeInterface * node, GType type_id)
-{
- int i;
- guint n_properties;
- GParamSpec **properties;
-
- if (node->node.type == G_IR_NODE_OBJECT)
- {
- GObjectClass *type_class = g_type_class_ref (type_id);
- properties = g_object_class_list_properties (type_class, &n_properties);
- }
- else if (node->node.type == G_IR_NODE_INTERFACE)
- {
- GTypeInterface *iface = g_type_default_interface_ref (type_id);
- properties = g_object_interface_list_properties (iface, &n_properties);
- }
- else
- {
- g_assert_not_reached ();
- }
-
- for (i = 0; i < n_properties; i++)
- {
- GIrNodeProperty *giprop;
-
- /* ignore inherited properties */
- if (properties[i]->owner_type != type_id)
- {
- continue;
- }
- giprop = (GIrNodeProperty *) g_idl_node_new (G_IR_NODE_PROPERTY);
- giprop->node.name = g_strdup (properties[i]->name);
- node->members =
- g_list_insert_sorted (node->members, giprop,
- (GCompareFunc) g_idl_node_cmp);
- giprop->type = create_node_from_gtype (properties[i]->value_type);
- giprop->readable = (properties[i]->flags & G_PARAM_READABLE) != 0;
- giprop->writable = (properties[i]->flags & G_PARAM_WRITABLE) != 0;
- giprop->construct = (properties[i]->flags & G_PARAM_CONSTRUCT) != 0;
- giprop->construct_only =
- (properties[i]->flags & G_PARAM_CONSTRUCT_ONLY) != 0;
- }
-}
-
-static void
-g_igenerator_process_signals (GIGenerator * igenerator,
- GIrNodeInterface * node, GType type_id)
-{
- int i, j;
- guint n_signal_ids;
- guint *signal_ids = g_signal_list_ids (type_id, &n_signal_ids);
-
- for (i = 0; i < n_signal_ids; i++)
- {
- GSignalQuery signal_query;
- GIrNodeSignal *gisig;
- GIrNodeParam *giparam;
-
- g_signal_query (signal_ids[i], &signal_query);
- gisig = (GIrNodeSignal *) g_idl_node_new (G_IR_NODE_SIGNAL);
- gisig->node.name = g_strdup (signal_query.signal_name);
- node->members =
- g_list_insert_sorted (node->members, gisig,
- (GCompareFunc) g_idl_node_cmp);
-
- gisig->run_first =
- (signal_query.signal_flags & G_SIGNAL_RUN_FIRST) != 0;
- gisig->run_last = (signal_query.signal_flags & G_SIGNAL_RUN_LAST) != 0;
- gisig->run_cleanup =
- (signal_query.signal_flags & G_SIGNAL_RUN_CLEANUP) != 0;
-
- /* add sender parameter */
- giparam = (GIrNodeParam *) g_idl_node_new (G_IR_NODE_PARAM);
- gisig->parameters = g_list_append (gisig->parameters, giparam);
- giparam->node.name = g_strdup ("object");
- giparam->type = create_node_from_gtype (type_id);
-
- for (j = 0; j < signal_query.n_params; j++)
- {
- giparam = (GIrNodeParam *) g_idl_node_new (G_IR_NODE_PARAM);
- gisig->parameters = g_list_append (gisig->parameters, giparam);
- giparam->node.name = g_strdup_printf ("p%d", j);
- giparam->type = create_node_from_gtype (signal_query.param_types[j]);
- }
- gisig->result = (GIrNodeParam *) g_idl_node_new (G_IR_NODE_PARAM);
- gisig->result->type = create_node_from_gtype (signal_query.return_type);
- }
-}
-
-static const gchar *
-lookup_symbol (GIGenerator *igenerator, const gchar *typename)
-{
- const gchar *name;
-
- name = g_hash_table_lookup (igenerator->symbols, typename);
- if (!name)
- {
- g_printerr ("Unknown symbol: %s\n", typename);
- return typename;
- }
-
- return name;
-}
-
-static void
-g_igenerator_create_object (GIGenerator *igenerator,
- const char *symbol_name,
- GType type_id,
- char *lower_case_prefix)
-
-{
- char *alt_lower_case_prefix;
- GIrNodeInterface *node;
- guint n_type_interfaces;
- GType *type_interfaces;
- int i;
-
- node = (GIrNodeInterface *) g_idl_node_new (G_IR_NODE_OBJECT);
- node->node.name = g_strdup (g_type_name (type_id));
- igenerator->module->entries =
- g_list_insert_sorted (igenerator->module->entries, node,
- (GCompareFunc) g_idl_node_cmp);
- g_hash_table_insert (igenerator->type_map, node->node.name,
- node);
- g_hash_table_insert (igenerator->type_by_lower_case_prefix,
- lower_case_prefix, node);
- alt_lower_case_prefix = g_ascii_strdown (node->node.name, -1);
-
- if (strcmp (alt_lower_case_prefix, lower_case_prefix) != 0)
- {
- /* alternative prefix sometimes necessary, for example
- * for GdkWindow
- */
- g_hash_table_insert (igenerator->type_by_lower_case_prefix,
- g_strdup (alt_lower_case_prefix),
- node);
- }
-
- g_free (alt_lower_case_prefix);
-
- node->gtype_name = g_strdup (node->node.name);
- node->gtype_init = g_strdup (symbol_name);
- node->parent = g_strdup (lookup_symbol (igenerator,
- g_type_name (g_type_parent (type_id))));
-
- type_interfaces = g_type_interfaces (type_id, &n_type_interfaces);
-
- for (i = 0; i < n_type_interfaces; i++)
- {
- char *iface_name =
- g_strdup (g_type_name (type_interfaces[i]));
- /* workaround for AtkImplementorIface */
- if (g_str_has_suffix (iface_name, "Iface"))
- {
- iface_name[strlen (iface_name) - strlen ("Iface")] =
- '\0';
- }
- node->interfaces =
- g_list_append (node->interfaces, iface_name);
- }
-
- g_hash_table_insert (igenerator->symbols,
- g_strdup (node->gtype_name),
- /* FIXME: Strip igenerator->namespace */
- g_strdup (node->node.name));
-
- g_igenerator_process_properties (igenerator, node, type_id);
- g_igenerator_process_signals (igenerator, node, type_id);
-}
-
-static void
-g_igenerator_create_interface (GIGenerator *igenerator,
- const char *symbol_name,
- GType type_id,
- char *lower_case_prefix)
-
-{
- GIrNodeInterface *node;
- gboolean is_gobject = FALSE;
- guint n_iface_prereqs;
- GType *iface_prereqs;
- int i;
-
- node = (GIrNodeInterface *) g_idl_node_new (G_IR_NODE_INTERFACE);
- node->node.name = g_strdup (g_type_name (type_id));
-
- /* workaround for AtkImplementorIface */
- if (g_str_has_suffix (node->node.name, "Iface"))
- {
- node->node.name[strlen (node->node.name) -
- strlen ("Iface")] = '\0';
- }
- igenerator->module->entries =
- g_list_insert_sorted (igenerator->module->entries, node,
- (GCompareFunc) g_idl_node_cmp);
- g_hash_table_insert (igenerator->type_map, node->node.name,
- node);
- g_hash_table_insert (igenerator->type_by_lower_case_prefix,
- lower_case_prefix, node);
- node->gtype_name = g_strdup (node->node.name);
- node->gtype_init = g_strdup (symbol_name);
-
- iface_prereqs =
- g_type_interface_prerequisites (type_id, &n_iface_prereqs);
-
- for (i = 0; i < n_iface_prereqs; i++)
- {
- if (g_type_fundamental (iface_prereqs[i]) == G_TYPE_OBJECT)
- {
- is_gobject = TRUE;
- }
- node->prerequisites =
- g_list_append (node->prerequisites,
- g_strdup (g_type_name (iface_prereqs[i])));
- }
-
- if (is_gobject)
- g_igenerator_process_properties (igenerator, node, type_id);
- else
- g_type_default_interface_ref (type_id);
-
- g_igenerator_process_signals (igenerator, node, type_id);
-}
-
-static void
-g_igenerator_create_boxed (GIGenerator *igenerator,
- const char *symbol_name,
- GType type_id,
- char *lower_case_prefix)
-{
- GIrNodeBoxed *node =
- (GIrNodeBoxed *) g_idl_node_new (G_IR_NODE_BOXED);
- node->node.name = g_strdup (g_type_name (type_id));
- igenerator->module->entries =
- g_list_insert_sorted (igenerator->module->entries, node,
- (GCompareFunc) g_idl_node_cmp);
- g_hash_table_insert (igenerator->type_map, node->node.name,
- node);
- g_hash_table_insert (igenerator->type_by_lower_case_prefix,
- lower_case_prefix, node);
- node->gtype_name = g_strdup (node->node.name);
- node->gtype_init = g_strdup (symbol_name);
-}
-
-static void
-g_igenerator_create_enum (GIGenerator *igenerator,
- const char *symbol_name,
- GType type_id,
- char *lower_case_prefix)
-{
- GIrNodeEnum *node;
- int i;
- GEnumClass *type_class;
-
- node = (GIrNodeEnum *) g_idl_node_new (G_IR_NODE_ENUM);
- node->node.name = g_strdup (g_type_name (type_id));
- igenerator->module->entries =
- g_list_insert_sorted (igenerator->module->entries, node,
- (GCompareFunc) g_idl_node_cmp);
- g_hash_table_insert (igenerator->type_map, node->node.name,
- node);
- g_hash_table_insert (igenerator->type_by_lower_case_prefix,
- lower_case_prefix, node);
- node->gtype_name = g_strdup (node->node.name);
- node->gtype_init = g_strdup (symbol_name);
-
- type_class = g_type_class_ref (type_id);
-
- for (i = 0; i < type_class->n_values; i++)
- {
- GIrNodeValue *gival =
- (GIrNodeValue *) g_idl_node_new (G_IR_NODE_VALUE);
- node->values = g_list_append (node->values, gival);
- gival->node.name =
- g_strdup (type_class->values[i].value_name);
- gival->value = type_class->values[i].value;
- }
-}
-
-static void
-g_igenerator_create_flags (GIGenerator *igenerator,
- const char *symbol_name,
- GType type_id,
- char *lower_case_prefix)
-{
- GIrNodeEnum *node;
- GFlagsClass *type_class;
- int i;
-
- node = (GIrNodeEnum *) g_idl_node_new (G_IR_NODE_FLAGS);
- node->node.name = g_strdup (g_type_name (type_id));
- igenerator->module->entries =
- g_list_insert_sorted (igenerator->module->entries, node,
- (GCompareFunc) g_idl_node_cmp);
- g_hash_table_insert (igenerator->type_map, node->node.name,
- node);
- g_hash_table_insert (igenerator->type_by_lower_case_prefix,
- lower_case_prefix, node);
- node->gtype_name = g_strdup (node->node.name);
- node->gtype_init = g_strdup (symbol_name);
-
- type_class = g_type_class_ref (type_id);
-
- for (i = 0; i < type_class->n_values; i++)
- {
- GIrNodeValue *gival =
- (GIrNodeValue *) g_idl_node_new (G_IR_NODE_VALUE);
- node->values = g_list_append (node->values, gival);
- gival->node.name =
- g_strdup (type_class->values[i].value_name);
- gival->value = type_class->values[i].value;
- }
-}
-
-static gboolean
-g_igenerator_process_module_symbol (GIGenerator *igenerator,
- GModule *module,
- const gchar *symbol_name)
-{
- TypeFunction type_fun;
- GType type_id;
- GType type_fundamental;
- char *lower_case_prefix;
-
- /* ignore already processed functions */
- if (symbol_name == NULL)
- return FALSE;
-
- if (!g_module_symbol (module,
- symbol_name,
- (gpointer *) & type_fun))
- return FALSE;
-
- if (igenerator->verbose)
- g_print ("DEBUG: calling %s\n", symbol_name);
-
- type_id = type_fun ();
- type_fundamental = g_type_fundamental (type_id);
- lower_case_prefix =
- str_replace (g_strndup
- (symbol_name,
- strlen (symbol_name) - strlen ("_get_type")),
- "_", "");
-
- if (igenerator->verbose)
- g_print ("DEBUG: processing it as a %s\n", g_type_name (type_fundamental));
-
- switch (type_fundamental)
- {
- case G_TYPE_OBJECT:
- g_igenerator_create_object (igenerator, symbol_name, type_id,
- lower_case_prefix);
- break;
- case G_TYPE_INTERFACE:
- g_igenerator_create_interface (igenerator, symbol_name, type_id,
- lower_case_prefix);
- break;
- case G_TYPE_BOXED:
- g_igenerator_create_boxed (igenerator, symbol_name, type_id,
- lower_case_prefix);
- break;
- case G_TYPE_ENUM:
- g_igenerator_create_enum (igenerator, symbol_name, type_id,
- lower_case_prefix);
- break;
- case G_TYPE_FLAGS:
- g_igenerator_create_flags (igenerator, symbol_name, type_id,
- lower_case_prefix);
- break;
- default:
- break;
- }
- return TRUE;
-}
-
-static void
-g_igenerator_process_module (GIGenerator * igenerator,
- const gchar *filename)
-{
- GModule *module;
- GList *l;
-
- module = g_module_open (filename,
- G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
-
- if (module == NULL)
- {
- g_critical ("Couldn't open module: %s", filename);
- return;
- }
-
- if (igenerator->verbose)
- g_print ("DEBUG: opened library %s\n", filename);
-
- for (l = igenerator->get_type_symbols; l != NULL; l = l->next)
- {
- if (g_igenerator_process_module_symbol (igenerator,
- module, (const char *)l->data))
- /* symbol found, ignore in future iterations */
- l->data = NULL;
- }
-}
-
-static void
-g_igenerator_process_function_symbol (GIGenerator * igenerator, GISourceSymbol * sym)
-{
- GIrNodeFunction *func;
- char *last_underscore;
- GList *param_l;
- int i;
- GList *l;
- GSList *j, *directives;
-
- func = (GIrNodeFunction *) g_idl_node_new (G_IR_NODE_FUNCTION);
-
- /* check whether this is a type method */
- last_underscore = strrchr (sym->ident, '_');
-
- while (last_underscore != NULL)
- {
- char *prefix;
- GIrNode *node;
-
- prefix = g_strndup (sym->ident, last_underscore - sym->ident);
- prefix = str_replace (prefix, "_", "");
-
- node = g_hash_table_lookup (igenerator->type_by_lower_case_prefix,
- prefix);
- if (node != NULL )
- {
- func->node.name = g_strdup (last_underscore + 1);
-
- /* ignore get_type functions in registered types */
- if (strcmp (func->node.name, "get_type") == 0)
- return;
-
- if ((node->type == G_IR_NODE_OBJECT ||
- node->type == G_IR_NODE_BOXED) &&
- g_str_has_prefix (func->node.name, "new"))
- func->is_constructor = TRUE;
- else
- func->is_method = TRUE;
- if (g_idl_node_can_have_member (node))
- {
- g_idl_node_add_member (node, func);
- break;
- }
- else
- {
- /* reset function attributes */
- g_free (func->node.name);
- func->node.name = NULL;
- func->is_constructor = FALSE;
- func->is_method = FALSE;
- }
- }
- else if (strcmp (igenerator->lower_case_namespace, prefix) == 0)
- {
- func->node.name = g_strdup (last_underscore + 1);
- igenerator->module->entries =
- g_list_insert_sorted (igenerator->module->entries, func,
- (GCompareFunc) g_idl_node_cmp);
- break;
- }
- last_underscore =
- g_utf8_strrchr (sym->ident, last_underscore - sym->ident, '_');
- }
-
- /* create a namespace function if no prefix matches */
- if (func->node.name == NULL)
- {
- func->node.name = g_strdup (sym->ident);
- func->is_constructor = FALSE;
- func->is_method = FALSE;
- igenerator->module->entries =
- g_list_insert_sorted (igenerator->module->entries, func,
- (GCompareFunc) g_idl_node_cmp);
- }
-
- func->symbol = g_strdup (sym->ident);
- func->result = (GIrNodeParam *) g_idl_node_new (G_IR_NODE_PARAM);
- func->result->type = create_node_from_ctype (sym->base_type->base_type);
-
- directives = g_hash_table_lookup (igenerator->scanner->directives_map, func->symbol);
-
- for (j = directives; j; j = j->next)
- {
- GISourceDirective *directive = j->data;
- if (g_ascii_strncasecmp ("return", directive->name, 6) == 0)
- {
- GSList *options;
- for (options = directive->options; options; options = options->next)
- {
- gchar *stringy_data = options->data;
- if (g_ascii_strcasecmp (stringy_data, "caller-owns") == 0)
- func->result->transfer = TRUE;
- }
- }
- }
-
- for (param_l = sym->base_type->child_list, i = 1; param_l != NULL;
- param_l = param_l->next, i++)
- {
- GISourceSymbol *param_sym = param_l->data;
- GIrNodeParam *param;
-
- param = (GIrNodeParam *) g_idl_node_new (G_IR_NODE_PARAM);
- param->type = create_node_from_ctype (param_sym->base_type);
-
- for (j = directives; j; j = j->next)
- {
- GISourceDirective *directive = j->data;
-
- if (g_ascii_strcasecmp (param_sym->ident, directive->name) == 0)
- {
-
- GSList *options;
-
- for (options = directive->options; options; options = options->next)
- {
- gchar *stringy_data = options->data;
-
- if (g_ascii_strcasecmp (stringy_data, "callee-owns") == 0)
- param->transfer = TRUE;
- if (g_ascii_strcasecmp (stringy_data, "null-ok") == 0)
- param->null_ok = TRUE;
- if (g_ascii_strcasecmp (stringy_data, "inout") == 0) {
- param->in = TRUE;
- param->out = TRUE;
- }
- if (g_ascii_strcasecmp (stringy_data, "in-out") == 0) {
- param->in = TRUE;
- param->out = TRUE;
- }
- if (g_ascii_strcasecmp (stringy_data, "in") == 0)
- param->in = TRUE;
- if (g_ascii_strcasecmp (stringy_data, "out") == 0)
- param->out = TRUE;
- }
- }
- }
-
- if (param_sym->ident == NULL)
- param->node.name = g_strdup_printf ("p%d", i);
- else
- param->node.name = g_strdup (param_sym->ident);
-
- func->parameters = g_list_append (func->parameters, param);
- }
-
- /* By removing it here, we mark it as handled, memory will be freed by
- * the cleanup for sym */
- g_hash_table_remove (igenerator->scanner->directives_map, func->symbol);
-
-}
-
-static void
-g_igenerator_process_unregistered_struct_typedef (GIGenerator * igenerator,
- GISourceSymbol * sym,
- GISourceType * struct_type)
-{
- GIrNodeStruct *node =
- (GIrNodeStruct *) g_idl_node_new (G_IR_NODE_STRUCT);
- GList *member_l;
- char *lower_case_prefix;
-
- node->node.name = g_strdup (sym->ident);
- igenerator->module->entries =
- g_list_insert_sorted (igenerator->module->entries, node,
- (GCompareFunc) g_idl_node_cmp);
- lower_case_prefix = g_ascii_strdown (sym->ident, -1);
- g_hash_table_insert (igenerator->type_map, sym->ident, node);
- g_hash_table_insert (igenerator->type_by_lower_case_prefix,
- lower_case_prefix, node);
-
- for (member_l = struct_type->child_list; member_l != NULL;
- member_l = member_l->next)
- {
- GISourceSymbol *member = member_l->data;
- GIrNodeField *gifield =
- (GIrNodeField *) g_idl_node_new (G_IR_NODE_FIELD);
-
- node->members = g_list_append (node->members, gifield);
- gifield->node.name = g_strdup (member->ident);
- gifield->type = create_node_from_ctype (member->base_type);
- }
-}
-
-static void
-g_igenerator_process_struct_typedef (GIGenerator * igenerator, GISourceSymbol * sym)
-{
- GISourceType *struct_type = sym->base_type;
- gboolean opaque_type = FALSE;
- GIrNode *type;
-
- if (struct_type->child_list == NULL)
- {
- GISourceSymbol *struct_symbol;
- g_assert (struct_type->name != NULL);
- struct_symbol =
- g_hash_table_lookup (igenerator->scanner->struct_or_union_or_enum_table,
- struct_type->name);
- if (struct_symbol != NULL)
- {
- struct_type = struct_symbol->base_type;
- }
- }
-
- if (struct_type->child_list == NULL)
- {
- opaque_type = TRUE;
- }
-
- type = g_hash_table_lookup (igenerator->type_map, sym->ident);
- if (type != NULL)
- {
- /* struct of a GTypeInstance */
- if (!opaque_type
- && (type->type == G_IR_NODE_OBJECT
- || type->type == G_IR_NODE_INTERFACE))
- {
- GIrNodeInterface *node = (GIrNodeInterface *) type;
- GList *member_l;
- /* ignore first field => parent */
- for (member_l = struct_type->child_list->next; member_l != NULL;
- member_l = member_l->next)
- {
- GISourceSymbol *member = member_l->data;
- /* ignore private / reserved members */
- if (member->ident[0] == '_'
- || g_str_has_prefix (member->ident, "priv"))
- {
- continue;
- }
- GIrNodeField *gifield =
- (GIrNodeField *) g_idl_node_new (G_IR_NODE_FIELD);
- node->members = g_list_append (node->members, gifield);
- gifield->node.name = g_strdup (member->ident);
- gifield->type = create_node_from_ctype (member->base_type);
- }
- }
- else if (type->type == G_IR_NODE_BOXED)
- {
- GIrNodeBoxed *node = (GIrNodeBoxed *) type;
- GList *member_l;
- for (member_l = struct_type->child_list; member_l != NULL;
- member_l = member_l->next)
- {
- GISourceSymbol *member = member_l->data;
- GIrNodeField *gifield =
- (GIrNodeField *) g_idl_node_new (G_IR_NODE_FIELD);
- node->members = g_list_append (node->members, gifield);
- gifield->node.name = g_strdup (member->ident);
- gifield->type = create_node_from_ctype (member->base_type);
- }
- }
- }
- else if (!opaque_type
- && (g_str_has_suffix (sym->ident, "Class")
- || g_str_has_suffix (sym->ident, "Iface")
- || g_str_has_suffix (sym->ident, "Interface")))
- {
- char *base_name;
- GList *member_l;
- GIrNodeInterface *node;
-
- if (g_str_has_suffix (sym->ident, "Interface"))
- {
- base_name =
- g_strndup (sym->ident,
- strlen (sym->ident) - strlen ("Interface"));
- }
- else
- {
- base_name =
- g_strndup (sym->ident, strlen (sym->ident) - strlen ("Class"));
- }
- type = g_hash_table_lookup (igenerator->type_map, base_name);
- if (type == NULL
- || (type->type != G_IR_NODE_OBJECT
- && type->type != G_IR_NODE_INTERFACE))
- {
- g_igenerator_process_unregistered_struct_typedef (igenerator, sym,
- struct_type);
- return;
- }
- node = (GIrNodeInterface *) type;
-
- /* ignore first field => parent */
- for (member_l = struct_type->child_list->next; member_l != NULL;
- member_l = member_l->next)
- {
- GISourceSymbol *member = member_l->data;
- /* ignore private / reserved members */
- if (member->ident[0] == '_')
- {
- continue;
- }
- if (member->base_type->type == CTYPE_POINTER
- && member->base_type->base_type->type == CTYPE_FUNCTION)
- {
- /* ignore default handlers of signals */
- gboolean found_signal = FALSE;
- GList *type_member_l;
- GList *param_l;
- int i;
- GIrNodeVFunc *givfunc;
-
- for (type_member_l = node->members; type_member_l != NULL;
- type_member_l = type_member_l->next)
- {
- GIrNode *type_member = type_member_l->data;
- char *normalized_name =
- str_replace (type_member->name, "-", "_");
- if (type_member->type == G_IR_NODE_SIGNAL
- && strcmp (normalized_name, member->ident) == 0)
- {
- GList *vfunc_param_l;
- GList *sig_param_l;
- GIrNodeSignal *sig = (GIrNodeSignal *) type_member;
- found_signal = TRUE;
- /* set signal parameter names */
- for (vfunc_param_l =
- member->base_type->base_type->child_list,
- sig_param_l = sig->parameters;
- vfunc_param_l != NULL && sig_param_l != NULL;
- vfunc_param_l = vfunc_param_l->next, sig_param_l =
- sig_param_l->next)
- {
- GISourceSymbol *vfunc_param = vfunc_param_l->data;
- GIrNodeParam *sig_param = sig_param_l->data;
- if (vfunc_param->ident != NULL)
- {
- g_free (sig_param->node.name);
- sig_param->node.name =
- g_strdup (vfunc_param->ident);
- }
- }
- break;
- }
- }
- if (found_signal)
- {
- continue;
- }
-
- givfunc = (GIrNodeVFunc *) g_idl_node_new (G_IR_NODE_VFUNC);
- givfunc->node.name = g_strdup (member->ident);
- node->members =
- g_list_insert_sorted (node->members, givfunc,
- (GCompareFunc) g_idl_node_cmp);
- givfunc->result =
- (GIrNodeParam *) g_idl_node_new (G_IR_NODE_PARAM);
- givfunc->result->type =
- create_node_from_ctype (member->base_type->base_type->base_type);
- for (param_l = member->base_type->base_type->child_list, i = 1;
- param_l != NULL; param_l = param_l->next, i++)
- {
- GISourceSymbol *param_sym = param_l->data;
- GIrNodeParam *param =
- (GIrNodeParam *) g_idl_node_new (G_IR_NODE_PARAM);
- if (param_sym->ident == NULL)
- {
- param->node.name = g_strdup_printf ("p%d", i);
- }
- else
- {
- param->node.name = g_strdup (param_sym->ident);
- }
- param->type = create_node_from_ctype (param_sym->base_type);
- givfunc->parameters =
- g_list_append (givfunc->parameters, param);
- }
- }
- }
- }
- else if (g_str_has_suffix (sym->ident, "Private"))
- {
- /* ignore private structs */
- }
- else
- {
- g_igenerator_process_unregistered_struct_typedef (igenerator, sym,
- struct_type);
- }
-}
-
-static void
-g_igenerator_process_union_typedef (GIGenerator * igenerator, GISourceSymbol * sym)
-{
- GISourceType *union_type = sym->base_type;
- gboolean opaque_type = FALSE;
- GIrNode *type;
-
- if (union_type->child_list == NULL)
- {
- g_assert (union_type->name != NULL);
- GISourceSymbol *union_symbol =
- g_hash_table_lookup (igenerator->scanner->struct_or_union_or_enum_table,
- union_type->name);
- if (union_symbol != NULL)
- {
- union_type = union_symbol->base_type;
- }
- }
- if (union_type->child_list == NULL)
- {
- opaque_type = TRUE;
- }
-
- type = g_hash_table_lookup (igenerator->type_map, sym->ident);
- if (type != NULL)
- {
- g_assert (type->type == G_IR_NODE_BOXED);
- GIrNodeBoxed *node = (GIrNodeBoxed *) type;
- GList *member_l;
- for (member_l = union_type->child_list; member_l != NULL;
- member_l = member_l->next)
- {
- GISourceSymbol *member = member_l->data;
- GIrNodeField *gifield =
- (GIrNodeField *) g_idl_node_new (G_IR_NODE_FIELD);
- node->members = g_list_append (node->members, gifield);
- gifield->node.name = g_strdup (member->ident);
- gifield->type = create_node_from_ctype (member->base_type);
- }
- }
- else
- {
- GIrNodeUnion *node =
- (GIrNodeUnion *) g_idl_node_new (G_IR_NODE_UNION);
- char *lower_case_prefix;
- GList *member_l;
-
- node->node.name = g_strdup (sym->ident);
- igenerator->module->entries =
- g_list_insert_sorted (igenerator->module->entries, node,
- (GCompareFunc) g_idl_node_cmp);
- lower_case_prefix = g_ascii_strdown (sym->ident, -1);
- g_hash_table_insert (igenerator->type_map, sym->ident, node);
- g_hash_table_insert (igenerator->type_by_lower_case_prefix,
- lower_case_prefix, node);
-
- node->node.name = g_strdup (sym->ident);
- for (member_l = union_type->child_list; member_l != NULL;
- member_l = member_l->next)
- {
- GISourceSymbol *member = member_l->data;
- GIrNodeField *gifield =
- (GIrNodeField *) g_idl_node_new (G_IR_NODE_FIELD);
- node->members = g_list_append (node->members, gifield);
- gifield->node.name = g_strdup (member->ident);
- gifield->type = create_node_from_ctype (member->base_type);
- }
- }
-}
-
-static void
-g_igenerator_process_enum_typedef (GIGenerator * igenerator, GISourceSymbol * sym)
-{
- GISourceType *enum_type;
- GList *member_l;
- GIrNodeEnum *node;
- GISourceSymbol *enum_symbol;
-
- enum_type = sym->base_type;
- if (enum_type->child_list == NULL)
- {
- g_assert (enum_type->name != NULL);
- enum_symbol =
- g_hash_table_lookup (igenerator->scanner->struct_or_union_or_enum_table,
- enum_type->name);
- if (enum_symbol != NULL)
- {
- enum_type = enum_symbol->base_type;
- }
- }
- if (enum_type->child_list == NULL)
- {
- /* opaque type */
- return;
- }
-
- node = g_hash_table_lookup (igenerator->type_map, sym->ident);
- if (node != NULL)
- {
- return;
- }
-
- node = (GIrNodeEnum *) g_idl_node_new (G_IR_NODE_ENUM);
- node->node.name = g_strdup (sym->ident);
- igenerator->module->entries =
- g_list_insert_sorted (igenerator->module->entries, node,
- (GCompareFunc) g_idl_node_cmp);
-
- for (member_l = enum_type->child_list; member_l != NULL;
- member_l = member_l->next)
- {
- GISourceSymbol *member = member_l->data;
- GIrNodeValue *gival =
- (GIrNodeValue *) g_idl_node_new (G_IR_NODE_VALUE);
- node->values = g_list_append (node->values, gival);
- gival->node.name = g_strdup (member->ident);
- gival->value = member->const_int;
- }
-}
-
-static void
-g_igenerator_process_function_typedef (GIGenerator * igenerator,
- GISourceSymbol * sym)
-{
- GList *param_l;
- int i;
-
- /* handle callback types */
- GIrNodeFunction *gifunc =
- (GIrNodeFunction *) g_idl_node_new (G_IR_NODE_CALLBACK);
-
- gifunc->node.name = g_strdup (sym->ident);
- igenerator->module->entries =
- g_list_insert_sorted (igenerator->module->entries, gifunc,
- (GCompareFunc) g_idl_node_cmp);
-
- gifunc->symbol = g_strdup (sym->ident);
- gifunc->result = (GIrNodeParam *) g_idl_node_new (G_IR_NODE_PARAM);
- gifunc->result->type =
- create_node_from_ctype (sym->base_type->base_type->base_type);
-
- for (param_l = sym->base_type->base_type->child_list, i = 1;
- param_l != NULL; param_l = param_l->next, i++)
- {
- GISourceSymbol *param_sym = param_l->data;
- GIrNodeParam *param =
- (GIrNodeParam *) g_idl_node_new (G_IR_NODE_PARAM);
- if (param_sym->ident == NULL)
- {
- param->node.name = g_strdup_printf ("p%d", i);
- }
- else
- {
- param->node.name = g_strdup (param_sym->ident);
- }
- param->type = create_node_from_ctype (param_sym->base_type);
- gifunc->parameters = g_list_append (gifunc->parameters, param);
- }
-}
-
-static void
-g_igenerator_process_constant (GIGenerator * igenerator, GISourceSymbol * sym)
-{
- GIrNodeConstant *giconst =
- (GIrNodeConstant *) g_idl_node_new (G_IR_NODE_CONSTANT);
- giconst->node.name = g_strdup (sym->ident);
- igenerator->module->entries =
- g_list_insert_sorted (igenerator->module->entries, giconst,
- (GCompareFunc) g_idl_node_cmp);
-
- giconst->type = (GIrNodeType *) g_idl_node_new (G_IR_NODE_TYPE);
- if (sym->const_int_set)
- {
- giconst->type->unparsed = g_strdup ("int");
- giconst->value = g_strdup_printf ("%d", sym->const_int);
- }
- else if (sym->const_string != NULL)
- {
- giconst->type->unparsed = g_strdup ("char*");
- giconst->value = sym->const_string;
- }
-}
-
-static void
-g_igenerator_process_symbols (GIGenerator * igenerator)
-{
- GSList *l;
- /* process type symbols first to ensure complete type hashtables */
- /* type symbols */
- for (l = igenerator->scanner->symbols; l != NULL; l = l->next)
- {
- GISourceSymbol *sym = l->data;
- if (sym->ident[0] == '_')
- {
- /* ignore private / reserved symbols */
- continue;
- }
- if (sym->type == CSYMBOL_TYPE_TYPEDEF)
- {
- if (sym->base_type->type == CTYPE_STRUCT)
- {
- g_igenerator_process_struct_typedef (igenerator, sym);
- }
- else if (sym->base_type->type == CTYPE_UNION)
- {
- g_igenerator_process_union_typedef (igenerator, sym);
- }
- else if (sym->base_type->type == CTYPE_ENUM)
- {
- g_igenerator_process_enum_typedef (igenerator, sym);
- }
- else if (sym->base_type->type == CTYPE_POINTER
- && sym->base_type->base_type->type == CTYPE_FUNCTION)
- {
- g_igenerator_process_function_typedef (igenerator, sym);
- }
- else
- {
- GIrNodeStruct *node =
- (GIrNodeStruct *) g_idl_node_new (G_IR_NODE_STRUCT);
- char *lower_case_prefix;
-
- node->node.name = g_strdup (sym->ident);
- igenerator->module->entries =
- g_list_insert_sorted (igenerator->module->entries, node,
- (GCompareFunc) g_idl_node_cmp);
- lower_case_prefix = g_ascii_strdown (sym->ident, -1);
- g_hash_table_insert (igenerator->type_map, sym->ident, node);
- g_hash_table_insert (igenerator->type_by_lower_case_prefix,
- lower_case_prefix, node);
- }
- }
- }
- /* other symbols */
- for (l = igenerator->scanner->symbols; l != NULL; l = l->next)
- {
- GISourceSymbol *sym = l->data;
- if (sym->ident[0] == '_')
- {
- /* ignore private / reserved symbols */
- continue;
- }
- if (sym->type == CSYMBOL_TYPE_FUNCTION)
- {
- g_igenerator_process_function_symbol (igenerator, sym);
- }
- else if (sym->type == CSYMBOL_TYPE_CONST)
- {
- g_igenerator_process_constant (igenerator, sym);
- }
- }
-}
-
-void
-g_igenerator_generate (GIGenerator * igenerator,
- const gchar * filename,
- GList *libraries)
-{
- GSList *l;
- GList *k;
-
- for (l = igenerator->scanner->symbols; l != NULL; l = l->next)
- {
- GISourceSymbol *sym = l->data;
- if (sym->type == CSYMBOL_TYPE_FUNCTION
- && g_str_has_suffix (sym->ident, "_get_type"))
- {
- if (sym->base_type->child_list == NULL)
- {
- // ignore get_type functions with parameters
- igenerator->get_type_symbols =
- g_list_prepend (igenerator->get_type_symbols, g_strdup (sym->ident));
- }
- }
- }
-
- /* ensure to initialize GObject */
- g_type_class_ref (G_TYPE_OBJECT);
-
- for (k = libraries; k; k = k->next)
- g_igenerator_process_module (igenerator, (const gchar*)k->data);
-
- g_igenerator_process_symbols (igenerator);
-
- g_idl_writer_save_file (igenerator->module, filename);
-}
-
-static int
-eat_hspace (FILE * f)
-{
- int c;
- do
- {
- c = fgetc (f);
- }
- while (c == ' ' || c == '\t');
- return c;
-}
-
-static int
-eat_line (FILE * f, int c)
-{
- while (c != EOF && c != '\n')
- {
- c = fgetc (f);
- }
- if (c == '\n')
- {
- c = fgetc (f);
- if (c == ' ' || c == '\t')
- {
- c = eat_hspace (f);
- }
- }
- return c;
-}
-
-static int
-read_identifier (FILE * f, int c, char **identifier)
-{
- GString *id = g_string_new ("");
- while (isalnum (c) || c == '_')
- {
- g_string_append_c (id, c);
- c = fgetc (f);
- }
- *identifier = g_string_free (id, FALSE);
- return c;
-}
-
-static void
-g_igenerator_parse_macros (GIGenerator * igenerator)
-{
- GError *error = NULL;
- char *tmp_name = NULL;
- FILE *fmacros;
- GSList *k, *symbols;
- GList *l;
-
- fmacros = fdopen (g_file_open_tmp ("gen-introspect-XXXXXX.h", &tmp_name, &error),
- "w+");
- g_unlink (tmp_name);
-
- for (l = igenerator->scanner->filenames; l != NULL; l = l->next)
- {
- FILE *f = fopen (l->data, "r");
- int line = 1;
-
- GString *define_line;
- char *str;
- gboolean error_line = FALSE;
- int c = eat_hspace (f);
- while (c != EOF)
- {
- if (c != '#')
- {
- /* ignore line */
- c = eat_line (f, c);
- line++;
- continue;
- }
-
- /* print current location */
- str = g_strescape (l->data, "");
- fprintf (fmacros, "# %d \"%s\"\n", line, str);
- g_free (str);
-
- c = eat_hspace (f);
- c = read_identifier (f, c, &str);
- if (strcmp (str, "define") != 0 || (c != ' ' && c != '\t'))
- {
- g_free (str);
- /* ignore line */
- c = eat_line (f, c);
- line++;
- continue;
- }
- g_free (str);
- c = eat_hspace (f);
- c = read_identifier (f, c, &str);
- if (strlen (str) == 0 || (c != ' ' && c != '\t' && c != '('))
- {
- g_free (str);
- /* ignore line */
- c = eat_line (f, c);
- line++;
- continue;
- }
- define_line = g_string_new ("#define ");
- g_string_append (define_line, str);
- g_free (str);
- if (c == '(')
- {
- while (c != ')')
- {
- g_string_append_c (define_line, c);
- c = fgetc (f);
- if (c == EOF || c == '\n')
- {
- error_line = TRUE;
- break;
- }
- }
- if (error_line)
- {
- g_string_free (define_line, TRUE);
- /* ignore line */
- c = eat_line (f, c);
- line++;
- continue;
- }
-
- g_assert (c == ')');
- g_string_append_c (define_line, c);
- c = fgetc (f);
-
- /* found function-like macro */
- fprintf (fmacros, "%s\n", define_line->str);
-
- g_string_free (define_line, TRUE);
- /* ignore rest of line */
- c = eat_line (f, c);
- line++;
- continue;
- }
- if (c != ' ' && c != '\t')
- {
- g_string_free (define_line, TRUE);
- /* ignore line */
- c = eat_line (f, c);
- line++;
- continue;
- }
- while (c != EOF && c != '\n')
- {
- g_string_append_c (define_line, c);
- c = fgetc (f);
- if (c == '\\')
- {
- c = fgetc (f);
- if (c == '\n')
- {
- /* fold lines when seeing backslash new-line sequence */
- c = fgetc (f);
- }
- else
- {
- g_string_append_c (define_line, '\\');
- }
- }
- }
-
- /* found object-like macro */
- fprintf (fmacros, "%s\n", define_line->str);
-
- c = eat_line (f, c);
- line++;
- }
-
- fclose (f);
- }
-
- igenerator->scanner->macro_scan = TRUE;
- rewind (fmacros);
-
- gi_source_scanner_parse_file (igenerator->scanner, fmacros);
- fclose (fmacros);
-
- igenerator->scanner->macro_scan = FALSE;
-}
-
-static void
-g_igenerator_add_module (GIGenerator *igenerator,
- GIrModule *module)
-{
- GList *l;
-
- for (l = module->entries; l; l = l->next)
- {
- GIrNode *node = (GIrNode*)l->data;
-
- if (node->type == G_IR_NODE_OBJECT)
- {
- GIrNodeInterface *object = (GIrNodeInterface*)node;
- gchar *name;
- if (strcmp(module->name, igenerator->namespace) == 0)
- name = g_strdup (node->name);
- else
- name = g_strdup_printf ("%s.%s", module->name, node->name);
- g_hash_table_insert (igenerator->symbols,
- g_strdup (object->gtype_name),
- name);
- }
- }
-}
-
-static void
-g_igenerator_add_include_idl (GIGenerator *igenerator,
- const gchar *filename)
-{
- GList *l;
- GList *modules;
-
- GError *error = NULL;
-
- modules = g_idl_parse_file (filename, &error);
- if (error)
- {
- g_printerr ("An error occured while parsing %s: %s\n",
- filename, error->message);
- return;
- }
-
- for (l = modules; l; l = l->next)
- {
- GIrModule *module = (GIrModule*)l->data;
- g_igenerator_add_module (igenerator, module);
- }
-}
-
-static FILE *
-g_igenerator_start_preprocessor (GIGenerator *igenerator,
- GList *cpp_options)
-{
- int cpp_out = -1, cpp_in = -1;
- int cpp_argc = 0;
- char **cpp_argv;
- GList *l;
- GError *error = NULL;
- FILE *f, *out;
- GPid pid;
- int status = 0;
- int read_bytes;
- int i;
- char **buffer;
- int tmp;
- char *tmpname;
-
- cpp_argv = g_new0 (char *, g_list_length (cpp_options) + 4);
- cpp_argv[cpp_argc++] = "cpp";
- cpp_argv[cpp_argc++] = "-C";
-
- /* Disable GCC extensions as we cannot parse them yet */
- cpp_argv[cpp_argc++] = "-U__GNUC__";
-
- for (l = cpp_options; l; l = l->next)
- cpp_argv[cpp_argc++] = (char*)l->data;
-
- cpp_argv[cpp_argc++] = NULL;
-
- if (igenerator->verbose)
- {
- GString *args = g_string_new ("");
-
- for (i = 0; i < cpp_argc - 1; i++)
- {
- g_string_append (args, cpp_argv[i]);
- if (i < cpp_argc - 2)
- g_string_append_c (args, ' ');
- }
-
- g_printf ("Executing '%s'\n", args->str);
- g_string_free (args, FALSE);
- }
- g_spawn_async_with_pipes (NULL, cpp_argv, NULL,
- G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
- NULL, NULL, &pid, &cpp_in, &cpp_out, NULL, &error);
-
- g_free (cpp_argv);
- if (error != NULL)
- {
- g_error ("%s", error->message);
- return NULL;
- }
-
- f = fdopen (cpp_in, "w");
-
- for (l = igenerator->scanner->filenames; l != NULL; l = l->next)
- {
- if (igenerator->verbose)
- g_printf ("DEBUG: Pre-processing %s\n", (char*)l->data);
-
- fprintf (f, "#include <%s>\n", (char *) l->data);
-
- }
-
- fclose (f);
- close (cpp_in);
-
- tmp = g_file_open_tmp (NULL, &tmpname, &error);
- if (error != NULL)
- {
- g_error (error->message);
- return NULL;
- }
-
- buffer = g_malloc0 (4096 * sizeof (char));
-
- while (1)
- {
- read_bytes = read (cpp_out, buffer, 4096);
- if (read_bytes == 0)
- break;
- write (tmp, buffer, read_bytes);
- }
-
- g_free (buffer);
-
- close (cpp_out);
-
- if (waitpid (pid, &status, 0) > 0)
- {
- if (status != 0)
- {
- g_spawn_close_pid (pid);
- kill (pid, SIGKILL);
-
- g_error ("cpp returned error code: %d\n", status);
- unlink (tmpname);
- g_free (tmpname);
- return NULL;
- }
- }
-
- f = fdopen (tmp, "r");
- if (!f)
- {
- g_error (strerror (errno));
- unlink (tmpname);
- g_free (tmpname);
- return NULL;
- }
- rewind (f);
- unlink (tmpname);
- g_free (tmpname);
-
- return f;
-}
-
-
-void
-g_igenerator_set_verbose (GIGenerator *igenerator,
- gboolean verbose)
-{
- igenerator->verbose = verbose;
-}
-
-int
-main (int argc, char **argv)
-{
- GOptionContext *ctx;
- gchar *namespace = NULL;
- gchar *shared_library = NULL;
- gchar **include_idls = NULL;
- gchar *output = NULL;
- gboolean verbose = FALSE;
-
- GIGenerator *igenerator;
- int gopt_argc, i;
- char **gopt_argv;
- GList *filenames = NULL;
- GList *sources = NULL;
- GError *error = NULL;
- GList *l, *libraries = NULL;
- GList *cpp_options = NULL;
- GSList *k, *symbols;
- char *buffer;
- size_t size;
- FILE *tmp;
- GOptionEntry entries[] =
- {
- { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
- "Be verbose" },
- { "output", 'o', 0, G_OPTION_ARG_STRING, &output,
- "write output here instead of stdout", "FILE" },
- { "namespace", 'n', 0, G_OPTION_ARG_STRING, &namespace,
- "Namespace of the module, like 'Gtk'", "NAMESPACE" },
- { "shared-library", 0, 0, G_OPTION_ARG_FILENAME, &shared_library,
- "Shared library which contains the symbols", "FILE" },
- { "include-idl", 0, 0, G_OPTION_ARG_STRING_ARRAY, &include_idls,
- "Other gidls to include", "IDL" },
- { NULL }
- };
-
- gopt_argc = 1;
- gopt_argv = (char**)g_malloc (argc * sizeof (char*));
- gopt_argv[0] = argv[0];
-
- for (i = 1; i < argc; i++)
- {
- if (argv[i][0] == '-')
- {
- switch (argv[i][1])
- {
- case 'I':
- case 'D':
- case 'U':
- cpp_options = g_list_prepend (cpp_options, g_strdup (argv[i]));
- break;
- case 'p':
- /*ignore -pthread*/
- if (0==strcmp("-pthread", argv[i]))
- break;
- default:
- gopt_argv[gopt_argc++] = argv[i];
- break;
- }
- }
- else if (g_str_has_suffix (argv[i], ".h") ||
- g_str_has_suffix (argv[i], ".c"))
- {
- gchar* filename;
-
- if (!g_path_is_absolute (argv[i]))
- {
- gchar *dir = g_get_current_dir ();
- filename = g_strdup_printf ("%s/%s", dir,
- argv[i]);
- g_free (dir);
- }
- else
- filename = g_strdup (argv[i]);
-
- if (g_str_has_suffix (argv[i], ".h"))
- filenames = g_list_append (filenames, g_realpath (filename));
- else if(g_str_has_suffix (argv[i], ".c"))
- sources = g_list_append (sources, g_realpath (filename));
- g_free(filename);
- }
- else if (g_str_has_suffix (argv[i], ".la") ||
- g_str_has_suffix (argv[i], ".so") ||
- g_str_has_suffix (argv[i], ".dll"))
- {
- libraries = g_list_prepend (libraries, g_strdup (argv[i]));
- }
- else
- {
- gopt_argv[gopt_argc++] = argv[i];
- }
- }
-
- ctx = g_option_context_new ("");
- g_option_context_add_main_entries (ctx, entries, NULL);
-
- if (!g_option_context_parse (ctx, &gopt_argc, &gopt_argv, &error))
- {
- g_printerr ("Parsing error: %s\n", error->message);
- g_option_context_free (ctx);
- return 1;
- }
-
- g_free (gopt_argv);
- g_option_context_free (ctx);
-
- if (!namespace)
- {
- g_printerr ("ERROR: namespace must be specified\n");
- return 1;
- }
-
- g_type_init ();
-
- /* initialize threading as this may be required by libraries that we'll use
- * libsoup-2.2 is an example of that.
- */
- g_thread_init (NULL);
-
- igenerator = g_igenerator_new (namespace, shared_library);
-
- if (verbose)
- g_igenerator_set_verbose (igenerator, TRUE);
-
- if (!filenames)
- {
- g_printerr ("ERROR: Need at least one header file.\n");
- g_igenerator_free (igenerator);
- return 0;
- }
- igenerator->scanner->filenames = filenames;
- cpp_options = g_list_reverse (cpp_options);
- libraries = g_list_reverse (libraries);
-
- if (include_idls)
- {
- for (i = 0; i < g_strv_length (include_idls); i++)
- g_igenerator_add_include_idl (igenerator, include_idls[i]);
- }
-
- for (l = sources; l; l = l->next)
- gi_source_scanner_lex_filename (igenerator->scanner, l->data);
-
- g_list_foreach (sources, (GFunc)g_free, NULL);
- g_list_free (sources);
-
- tmp = g_igenerator_start_preprocessor (igenerator, cpp_options);
- if (!tmp)
- {
- g_error ("ERROR in pre-processor.\n");
- g_igenerator_free (igenerator);
- return 1;
- }
-
- if (!gi_source_scanner_parse_file (igenerator->scanner, tmp))
- {
- fclose (tmp);
- g_igenerator_free (igenerator);
- return 1;
- }
-
- g_igenerator_parse_macros (igenerator);
-
- g_igenerator_generate (igenerator, output, libraries);
-
- fclose (tmp);
-#if 0
- g_igenerator_free (igenerator);
-#endif
-
- return 0;
-}
-