diff options
author | Johan Dahlin <johan@gnome.org> | 2008-04-22 22:48:16 +0000 |
---|---|---|
committer | Johan Dahlin <johan@src.gnome.org> | 2008-04-22 22:48:16 +0000 |
commit | 39e94bfbcd3e7df3f74b16174e88eff6a19856e0 (patch) | |
tree | 84d3925cecd0f8bab8a00d3d2d4d4f3df3573547 /tools | |
parent | 59c45cbf14930cf8c57b1f4498be207a3d90f490 (diff) | |
download | gobject-introspection-39e94bfbcd3e7df3f74b16174e88eff6a19856e0.tar.gz |
Revert revisions 157,149-148,136-129 and 120. Move back to using
2008-04-22 Johan Dahlin <johan@gnome.org>
* girepository/ginfo.c (g_info_from_entry), (g_type_info_new),
(g_type_info_is_pointer), (g_type_info_get_tag),
(g_type_info_get_param_type), (g_type_info_get_interface),
(g_type_info_get_array_length), (g_type_info_is_zero_terminated),
(g_type_info_get_n_error_domains), (g_type_info_get_error_domain),
(g_error_domain_info_get_codes), (g_enum_info_get_value),
(g_object_info_get_interface), (g_object_info_get_field),
(g_interface_info_get_prerequisite),
(g_signal_info_get_class_closure), (g_constant_info_get_value):
* girepository/ginvoke.c (get_ffi_type):
* girepository/girepository.h:
* girepository/gmetadata.c (g_metadata_get_dir_entry),
(g_metadata_check_sanity), (validate_header),
(validate_array_type_blob), (validate_iface_type_blob),
(validate_param_type_blob), (validate_error_type_blob),
(validate_type_blob), (validate_constant_blob),
(validate_struct_blob), (validate_enum_blob):
* girepository/gmetadata.h:
* tests/Makefile.am:
* tests/invoke/Makefile.am:
* tests/invoke/invoke.c (main):
* tests/roundtrips.sh:
* tools/Makefile.am:
* tools/compiler.c (format_output), (write_out_metadata), (main):
* tools/generate.c (write_type_name), (write_type_info),
(write_constant_value), (write_enum_info), (load_metadata), (main):
* tools/gidlcompilercontext.c:
* tools/gidlcompilercontext.h:
* tools/gidlcompilerentrynode.c:
* tools/gidlcompilerentrynode.h:
* tools/gidlcompilertypenode.c:
* tools/gidlcompilertypenode.h:
* tools/gidlmodule.c (g_idl_module_build_metadata):
* tools/gidlmodule.h:
* tools/gidlnode.c (init_stats), (dump_stats),
(g_idl_node_get_size), (g_idl_node_get_full_size),
(g_idl_node_cmp), (g_idl_node_can_have_member),
(g_idl_node_add_member), (g_idl_node_param_direction_string),
(parse_int_value), (parse_uint_value), (parse_float_value),
(parse_boolean_value), (find_entry_node), (find_entry),
(serialize_type), (g_idl_node_build_metadata), (write_string):
* tools/gidlnode.h:
* tools/gidlparser.c (parse_type_internal):
* tools/quote-file.sh:
Revert revisions 157,149-148,136-129 and 120.
Move back to using g-idl-generate to generate the metadata and
avoids dependency on a c compiler.
svn path=/trunk/; revision=214
Diffstat (limited to 'tools')
-rw-r--r-- | tools/Makefile.am | 17 | ||||
-rw-r--r-- | tools/compiler.c | 231 | ||||
-rw-r--r-- | tools/generate.c | 55 | ||||
-rw-r--r-- | tools/gidlcompilercontext.c | 668 | ||||
-rw-r--r-- | tools/gidlcompilercontext.h | 131 | ||||
-rw-r--r-- | tools/gidlcompilerentrynode.c | 1266 | ||||
-rw-r--r-- | tools/gidlcompilerentrynode.h | 37 | ||||
-rw-r--r-- | tools/gidlcompilertypenode.c | 430 | ||||
-rw-r--r-- | tools/gidlcompilertypenode.h | 44 | ||||
-rw-r--r-- | tools/gidlmodule.c | 161 | ||||
-rw-r--r-- | tools/gidlmodule.h | 3 | ||||
-rw-r--r-- | tools/gidlnode.c | 1557 | ||||
-rw-r--r-- | tools/gidlnode.h | 15 | ||||
-rw-r--r-- | tools/gidlparser.c | 2 | ||||
-rwxr-xr-x | tools/quote-file.sh | 3 |
15 files changed, 1893 insertions, 2727 deletions
diff --git a/tools/Makefile.am b/tools/Makefile.am index 545050a9..870db837 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -4,32 +4,17 @@ INCLUDES = \ -DGIREPO_DEFAULT_SEARCH_PATH="\"$(libdir)\"" \ -I$(top_srcdir)/girepository \ -I$(top_srcdir)/giscanner -BUILT_SOURCES = gmetadata-header.c - -CLEANFILES = gmetadata-header.c -EXTRA_DIST = quote-file.sh noinst_LTLIBRARIES = libgirepository-parser.la bin_PROGRAMS = g-idl-compiler g-idl-generate g-idl-scanner -gmetadata-header.c: $(top_srcdir)/girepository/gmetadata.h - $(srcdir)/quote-file.sh $^ $@ - libgirepository_parser_la_SOURCES = \ gidlmodule.c \ gidlmodule.h \ gidlnode.c \ gidlnode.h \ gidlparser.c \ - gidlparser.h \ - gidlcompilercontext.c \ - gidlcompilercontext.h \ - gidlcompilerentrynode.c \ - gidlcompilerentrynode.h \ - gidlcompilertypenode.c \ - gidlcompilertypenode.h \ - gmetadata-header.c - + gidlparser.h libgirepository_parser_la_CFLAGS = $(GIREPO_CFLAGS) g_idl_compiler_SOURCES = compiler.c diff --git a/tools/compiler.c b/tools/compiler.c index a73a8516..6ab0fa54 100644 --- a/tools/compiler.c +++ b/tools/compiler.c @@ -28,9 +28,113 @@ #include "gidlnode.h" #include "gidlparser.h" #include "gmetadata.h" -#include "gidlcompilercontext.h" -static GLogLevelFlags logged_levels; +gboolean raw = FALSE; +gboolean no_init = FALSE; +gchar **input = NULL; +gchar *output = NULL; +gchar *mname = NULL; +gchar *shlib = NULL; +gboolean debug = FALSE; +gboolean verbose = FALSE; + +static gchar * +format_output (GMetadata *metadata) +{ + GString *result; + gint i; + + result = g_string_sized_new (6 * metadata->len); + + g_string_append_printf (result, "#include <stdlib.h>\n"); + g_string_append_printf (result, "#include <girepository.h>\n\n"); + + g_string_append_printf (result, "const unsigned char _G_METADATA[] = \n{"); + + for (i = 0; i < metadata->len; i++) + { + if (i > 0) + g_string_append (result, ", "); + + if (i % 10 == 0) + g_string_append (result, "\n\t"); + + g_string_append_printf (result, "0x%.2x", metadata->data[i]); + } + + g_string_append_printf (result, "\n};\n\n"); + g_string_append_printf (result, "const gsize _G_METADATA_SIZE = %u;\n\n", + (guint)metadata->len); + + if (!no_init) + { + g_string_append_printf (result, + "__attribute__((constructor)) void\n" + "register_metadata (void)\n" + "{\n" + "\tGMetadata *metadata;\n" + "\tmetadata = g_metadata_new_from_const_memory (_G_METADATA, _G_METADATA_SIZE);\n" + "\tg_irepository_register (NULL, metadata);\n" + "}\n\n"); + + g_string_append_printf (result, + "__attribute__((destructor)) void\n" + "unregister_metadata (void)\n" + "{\n" + "\tg_irepository_unregister (NULL, \"%s\");\n" + "}\n", + g_metadata_get_namespace (metadata)); + } + + return g_string_free (result, FALSE); +} + +static void +write_out_metadata (gchar *prefix, + GMetadata *metadata) +{ + FILE *file; + + if (output == NULL) + file = stdout; + else + { + gchar *filename; + + if (prefix) + filename = g_strdup_printf ("%s-%s", prefix, output); + else + filename = g_strdup (output); + file = g_fopen (filename, "w"); + + if (file == NULL) + { + g_fprintf (stderr, "failed to open '%s': %s\n", + filename, g_strerror (errno)); + g_free (filename); + + return; + } + + g_free (filename); + } + + if (raw) + fwrite (metadata->data, 1, metadata->len, file); + else + { + gchar *code; + + code = format_output (metadata); + fputs (code, file); + g_free (code); + } + + if (output != NULL) + fclose (file); +} + +GLogLevelFlags logged_levels; static void log_handler (const gchar *log_domain, GLogLevelFlags log_level, @@ -42,43 +146,28 @@ static void log_handler (const gchar *log_domain, g_log_default_handler (log_domain, log_level, message, user_data); } +static GOptionEntry options[] = +{ + { "raw", 0, 0, G_OPTION_ARG_NONE, &raw, "emit raw metadata", NULL }, + { "code", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &raw, "emit C code", NULL }, + { "no-init", 0, 0, G_OPTION_ARG_NONE, &no_init, "do not create _init() function", NULL }, + { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output, "output file", "FILE" }, + { "module", 'm', 0, G_OPTION_ARG_STRING, &mname, "module to compile", "NAME" }, + { "shared-library", 'l', 0, G_OPTION_ARG_FILENAME, &shlib, "shared library", "FILE" }, + { "debug", 0, 0, G_OPTION_ARG_NONE, &debug, "show debug messages", NULL }, + { "verbose", 0, 0, G_OPTION_ARG_NONE, &verbose, "show verbose messages", NULL }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &input, NULL, NULL }, + { NULL, } +}; + int main (int argc, char ** argv) { - gboolean no_init = FALSE; - gchar **input = NULL; - gchar *output = NULL; - gchar *mname = NULL; - gchar *shlib = NULL; - gboolean debug = FALSE; - gboolean verbose = FALSE; - GOptionContext *context; GError *error = NULL; - GList *m, *modules; + GList *c, *m, *modules; gint i; - GList *c; - gint entry_id; - FILE *file; - GIdlCompilerContext *ctx; - GOptionEntry options[] = - { - { "no-init", 0, 0, G_OPTION_ARG_NONE, &no_init, - "do not create _init() function", NULL }, - { "output", 'o', 0, G_OPTION_ARG_FILENAME, &output, - "output file", "FILE" }, - { "module", 'm', 0, G_OPTION_ARG_STRING, &mname, - "module to compile", "NAME" }, - { "shared-library", 'l', 0, G_OPTION_ARG_FILENAME, &shlib, - "shared library", "FILE" }, - { "debug", 0, 0, G_OPTION_ARG_NONE, &debug, - "show debug messages", NULL }, - { "verbose", 0, 0, G_OPTION_ARG_NONE, &verbose, - "show verbose messages", NULL }, - { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &input, - NULL, NULL }, - { NULL, } - }; + g_metadata_check_sanity (); context = g_option_context_new (""); g_option_context_add_main_entries (context, options, NULL); @@ -96,6 +185,7 @@ main (int argc, char ** argv) if (!input) { g_fprintf (stderr, "no input files\n"); + return 1; } @@ -120,8 +210,7 @@ main (int argc, char ** argv) { GIdlModule *module = m->data; gchar *prefix; - GError *err = NULL; - + GMetadata *metadata; if (mname && strcmp (mname, module->name) != 0) continue; @@ -131,71 +220,25 @@ main (int argc, char ** argv) g_free (module->shared_library); module->shared_library = g_strdup (shlib); } - - if (!mname && (m->next || m->prev) && output) - prefix = module->name; - else - prefix = NULL; - - ctx = g_idl_compiler_context_new (module->name, &err); - if (err != NULL) + metadata = g_idl_module_build_metadata (module, modules); + if (metadata == NULL) { - g_fprintf (stderr, "Error creating new compiler context: %s", - err->message); + g_error ("Failed to build metadata for module '%s'\n", module->name); - return 1; + continue; } + if (!g_metadata_validate (metadata, &error)) + g_error ("Invalid metadata for module '%s': %s", + module->name, error->message); - /* This is making sure all the types - * that have local directory entries are already - * in the entries database. - * - * A method of finding out if an external reference is - * needed - */ - for (c = module->entries; c; c = c->next) - { - GIdlNode *node = (GIdlNode*) c->data; - - g_idl_compiler_add_entry (ctx, node); - } - - for (c = module->entries; c; c = c->next) - { - GIdlNode *node = (GIdlNode*) c->data; - - entry_id = g_idl_compiler_get_entry_id (ctx, node->name); - - g_idl_compiler_write_node (node, entry_id, ctx); - } - - if (output == NULL) - file = stdout; + if (!mname && (m->next || m->prev) && output) + prefix = module->name; else - { - gchar *filename; - - if (prefix) - filename = g_strdup_printf ("%s-%s", prefix, output); - else - filename = g_strdup (output); - file = g_fopen (filename, "w"); - - if (file == NULL) - { - g_fprintf (stderr, "failed to open '%s': %s\n", - filename, g_strerror (errno)); - g_free (filename); - - return; - } - - g_free (filename); - } - - g_idl_compiler_context_finalize (ctx, file, module->shared_library, &err); + prefix = NULL; - g_idl_compiler_context_destroy (ctx); + write_out_metadata (prefix, metadata); + g_metadata_free (metadata); + metadata = NULL; /* when writing to stdout, stop after the first module */ if (m->next && !output && !mname) diff --git a/tools/generate.c b/tools/generate.c index f55731ee..8c5c3b3b 100644 --- a/tools/generate.c +++ b/tools/generate.c @@ -38,8 +38,7 @@ write_type_name (const gchar *namespace, GIBaseInfo *info, FILE *file) { - if (g_base_info_get_namespace (info) != 0 && - strcmp (namespace, g_base_info_get_namespace (info)) != 0) + if (strcmp (namespace, g_base_info_get_namespace (info)) != 0) g_fprintf (file, "%s.", g_base_info_get_namespace (info)); g_fprintf (file, "%s", g_base_info_get_name (info)); @@ -79,11 +78,11 @@ write_type_info (const gchar *namespace, tag = g_type_info_get_tag (info); - if (tag < TYPE_TAG_UTF8) + if (tag < 18) g_fprintf (file, "%s%s", basic[tag], g_type_info_is_pointer (info) ? "*" : ""); - else if (tag <= TYPE_TAG_FILENAME) + else if (tag < 20) g_fprintf (file, "%s", basic[tag]); - else if (tag == TYPE_TAG_ARRAY) + else if (tag == 20) { gint length; @@ -102,7 +101,7 @@ write_type_info (const gchar *namespace, g_fprintf (file, "]"); g_base_info_unref ((GIBaseInfo *)type); } - else if (tag == TYPE_TAG_SYMBOL) + else if (tag == 21) { GIBaseInfo *iface = g_type_info_get_interface (info); write_type_name (namespace, iface, file); @@ -110,7 +109,7 @@ write_type_info (const gchar *namespace, g_fprintf (file, "*"); g_base_info_unref (iface); } - else if (tag == TYPE_TAG_LIST) + else if (tag == 22) { type = g_type_info_get_param_type (info, 0); g_fprintf (file, "GList"); @@ -123,7 +122,7 @@ write_type_info (const gchar *namespace, } g_fprintf (file, "*"); } - else if (tag == TYPE_TAG_SLIST) + else if (tag == 23) { type = g_type_info_get_param_type (info, 0); g_fprintf (file, "GSList"); @@ -136,7 +135,7 @@ write_type_info (const gchar *namespace, } g_fprintf (file, "*"); } - else if (tag == TYPE_TAG_HASH) + else if (tag == 24) { type = g_type_info_get_param_type (info, 0); g_fprintf (file, "GHashTable"); @@ -153,7 +152,7 @@ write_type_info (const gchar *namespace, } g_fprintf (file, "*"); } - else if (tag == TYPE_TAG_ERROR) + else if (tag == 25) { gint n; @@ -532,11 +531,8 @@ write_constant_value (const gchar *namespace, case GI_TYPE_TAG_FILENAME: g_fprintf (file, "%s", value->v_string); break; - case GI_TYPE_TAG_SYMBOL: - g_fprintf (file, "%s", value->v_string); - break; default: - g_warning ("Could not get type tag for constant"); + g_assert_not_reached (); } } @@ -574,22 +570,16 @@ write_enum_info (const gchar *namespace, FILE *file) { const gchar *name; - const gchar *type_name = NULL; - const gchar *type_init = NULL; + const gchar *type_name; + const gchar *type_init; gboolean deprecated; gint i; name = g_base_info_get_name ((GIBaseInfo *)info); deprecated = g_base_info_is_deprecated ((GIBaseInfo *)info); - /* Make sure this is a registered enum before filling out the - * GType information - */ - if (g_enum_info_is_registered ((GIEnumInfo *)info)) - { - type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); - type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); - } + type_name = g_registered_type_info_get_type_name ((GIRegisteredTypeInfo*)info); + type_init = g_registered_type_info_get_type_init ((GIRegisteredTypeInfo*)info); if (g_base_info_get_type ((GIBaseInfo *)info) == GI_INFO_TYPE_ENUM) g_fprintf (file, " <enum "); @@ -1108,17 +1098,12 @@ load_metadata (const gchar *filename, GModule **dlhandle, gsize *len) { - gpointer metadata; + guchar *metadata; gsize *metadata_size; GModule *handle; - handle = g_module_open (filename, G_MODULE_BIND_LOCAL|G_MODULE_BIND_LAZY); - if (!handle) - { - g_printerr("Could not load module '%s'\n", filename); - return NULL; - } - if (!g_module_symbol (handle, "_G_METADATA", &metadata)) + handle = g_module_open (filename, G_MODULE_BIND_LOCAL|G_MODULE_BIND_LAZY); + if (!g_module_symbol (handle, "_G_METADATA", (gpointer *) &metadata)) { g_printerr ("Could not load metadata from '%s': %s\n", filename, g_module_error ()); @@ -1137,7 +1122,7 @@ load_metadata (const gchar *filename, if (dlhandle) *dlhandle = handle; - return *((const guchar **) metadata); + return metadata; } int @@ -1160,6 +1145,8 @@ main (int argc, char *argv[]) g_type_init (); + g_metadata_check_sanity (); + context = g_option_context_new (""); g_option_context_add_main_entries (context, options, NULL); g_option_context_parse (context, &argc, &argv, &error); @@ -1174,7 +1161,7 @@ main (int argc, char *argv[]) for (i = 0; input[i]; i++) { GModule *dlhandle = NULL; - const guchar *metadata = NULL; + const guchar *metadata; gsize len; if (raw) diff --git a/tools/gidlcompilercontext.c b/tools/gidlcompilercontext.c deleted file mode 100644 index d11562c6..00000000 --- a/tools/gidlcompilercontext.c +++ /dev/null @@ -1,668 +0,0 @@ -/* GObject introspection: Metadata compiler context - * - * Copyright (C) 2008 Codethink Ltd - * 2008 Johan Dahlin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <stdio.h> -#include <stdarg.h> -#include <string.h> -#include <glib.h> - -#include "gidlcompilercontext.h" -#include "gidlnode.h" -#include "gmetadata.h" - -/* STATIC FUNCTIONS */ -/* ---------------- */ - -/* Functions for writing final 'C' file */ -/* ------------------------------------ */ - -extern char gmetadata_header[]; - -/* Parameters - * -Struct name - * -Number of directory entries - * -Length of strings area. - */ -static const char struct_header[] = - "%s\n" - "{\n" - " Header " SECTION (header) ";\n" - " DirEntry " SECTION (directory) "[%d];\n" - " char " SECTION (strings) "[%d];\n"; - -/* Parameters - * -Namespace name - * -Struct name - */ -static const char declarations[] = - "const unsigned char *_G_METADATA = (unsigned char *) &_METADATA_%s;\n" - "const gsize _G_METADATA_SIZE = sizeof(%s);\n\n"; - -/* Parameters - * -Struct name - * -Namespace name - */ -static const char init_header[] = - "static const %s _METADATA_%s =\n" - "{\n"; - -/* Parameters - * -Namespace name - */ -static const char file_footer[] = - "__attribute__((constructor)) void\n" - "register_metadata (void)\n" - "{\n" - " GMetadata *metadata;\n" - " metadata = g_metadata_new_from_const_memory (_G_METADATA, _G_METADATA_SIZE);\n" - " g_irepository_register (NULL, metadata);\n" - "}\n" - "\n" - "__attribute__((destructor)) void\n" - "unregister_metadata (void)\n" - "{\n" - " g_irepository_unregister (NULL, \"%s\");\n" - "}\n"; - - -typedef struct -{ - guint entry_id; - guint dir_id; -} SymbolEntry; - -typedef struct -{ - GIdlNode *node; - guint entry_id; -} DeferredEntry; - -static void -symbol_entry_free (SymbolEntry *symbol_entry) -{ - g_slice_free (SymbolEntry, symbol_entry); -} - -static void -deferred_entry_free (DeferredEntry *deferred_entry) -{ - g_slice_free (DeferredEntry, deferred_entry); -} - -static void -include_file (const gchar *fname, - FILE *output) -{ - FILE *input; - char c; - - input = fopen (fname, "r"); - - c = fgetc (input); - while (c != EOF) - { - fputc (c, output); - c = fgetc (input); - } - - fclose (input); -} - -static void -write_header (GIdlCompilerContext *ctx, - const gchar *shlib, - FILE *stream) -{ - guint32 n_entries; - guint32 n_local_entries; - const gchar *header_prototype = - " {\n" - /* Magic */ - " \"%s\",\n" - /* Major version */ - " %d,\n" - /* Minor version */ - " %d,\n" - " 0,\n" - /* n_entries */ - " %d,\n" - /* n_local_entries */ - " %d,\n" - /* directory */ - " G_STRUCT_OFFSET(%s, " SECTION (directory) "),\n" - /* n_annotations */ - " %d,\n" - /* annotations */ - " %d,\n" - /* struct_name */ - " sizeof(%s),\n" - /* struct_name, pointer to name string */ - " G_STRUCT_OFFSET(%s, " SECTION (strings) ") + %d,\n"; - - fprintf (stream, header_prototype, - G_IDL_MAGIC_ESCAPED, - 1, - 0, - ctx->directory_entries, - ctx->directory_local_entries, - ctx->struct_name, - 0, - 0, - ctx->struct_name, - ctx->struct_name, - g_idl_compiler_write_string (ctx, ctx->namespace_name)); - - - /* Header */ - if (shlib) - fprintf (stream, STRING_POINTER, - ctx->struct_name, - g_idl_compiler_write_string (ctx, shlib)); - else - fprintf (stream, "0"); - fprintf (stream, ",\n"); - - /* Header sizes */ - fprintf (stream, - " sizeof(DirEntry),\n" - " sizeof(FunctionBlob),\n" - " sizeof(CallbackBlob),\n" - " sizeof(SignalBlob),\n" - " sizeof(VFuncBlob),\n" - " sizeof(ArgBlob),\n" - " sizeof(PropertyBlob),\n" - " sizeof(FieldBlob),\n" - " sizeof(ValueBlob),\n" - " sizeof(AnnotationBlob),\n" - " sizeof(ConstantBlob),\n" - " sizeof(ErrorDomainBlob),\n" - " sizeof(SignatureBlob),\n" - " sizeof(EnumBlob),\n" - " sizeof(StructBlob),\n" - " sizeof(ObjectBlob),\n" - " sizeof(InterfaceBlob),\n" - " sizeof(UnionBlob),\n" - " {0,0,0,0,0,0,0},\n" " },\n\n"); -} - -void -write_compiled (GIdlCompilerContext *ctx, FILE *compiled, - const gchar *shlib, - GError **err) -{ - const char file_header[] = - "#include <stdlib.h>\n" - "#include <glib.h>\n" - "#include <girepository.h>\n"; - - /* Before doing anything need to add the namespace string */ - g_idl_compiler_write_string (ctx, ctx->namespace_name); - - fprintf (compiled, file_header); - fprintf (compiled, gmetadata_header); - - /* write the shlibs string before we write out the whole string length */ - if (shlib) - g_idl_compiler_write_string (ctx, shlib); - - /* +1 is for the null byte right at the end of the strings section */ - fprintf (compiled, struct_header, ctx->struct_name, - ctx->directory_entries, ctx->string_offset + 1); - - /* Include the struct file */ - include_file (ctx->mdata_struct_fn, compiled); - fprintf (compiled, "};\n\n"); - fprintf (compiled, init_header, ctx->struct_name, ctx->namespace_name); - - write_header (ctx, shlib, compiled); - - /* Close all the temporary files */ - fclose (ctx->mdata_init); - fclose (ctx->mdata_string); - fclose (ctx->mdata_directory); - - /* Place directory here */ - fprintf (compiled, " {\n"); - include_file (ctx->mdata_directory_fn, compiled); - fprintf (compiled, " },\n\n"); - - /* Place string data here */ - fprintf (compiled, " {\n"); - include_file (ctx->mdata_string_fn, compiled); - fprintf (compiled, " },\n\n"); - - /* Include the initializer file */ - include_file (ctx->mdata_init_fn, compiled); - - fprintf (compiled, "};\n\n"); - - /* Write out the metadata declarations */ - fprintf (compiled, declarations, ctx->namespace_name, ctx->struct_name); - - fprintf (compiled, file_footer, ctx->namespace_name); - - /* Remove the temporary files */ - g_remove (ctx->mdata_struct_fn); - g_remove (ctx->mdata_init_fn); - g_remove (ctx->mdata_string_fn); - g_remove (ctx->mdata_directory_fn); -} - -/* GLOBAL FUNCTIONS */ -/* ---------------- */ - -GIdlCompilerContext * -g_idl_compiler_context_new (const gchar *namespace, - GError **error) -{ - gint struct_fd, init_fd, string_fd, directory_fd; - GIdlCompilerContext *ctx; - GError *tmp_error = NULL; - - ctx = g_slice_new0 (GIdlCompilerContext); - if (!ctx) - { - /* FIXME Put proper error quark here */ - g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT, - "Could not create output context"); - goto out; - } - ctx->strings = g_hash_table_new (g_str_hash, g_str_equal); - ctx->namespace_name = g_strdup (namespace); - ctx->struct_name = g_strdup_printf ("struct mdata_%s", namespace); - - ctx->entriesdb = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify)g_free, - (GDestroyNotify)symbol_entry_free); - ctx->typesdb = g_hash_table_new (g_str_hash, g_str_equal); - - /* Structure definition file */ - struct_fd = g_file_open_tmp ("gicomp-XXXXXX", &ctx->mdata_struct_fn, - &tmp_error); - if (tmp_error) - goto error4; - - /* Structure initialization file */ - init_fd = g_file_open_tmp ("gicomp-XXXXXX", &ctx->mdata_init_fn, - &tmp_error); - if (tmp_error) - goto error3; - - /* String file */ - string_fd = g_file_open_tmp ("gicomp-XXXXXX", &ctx->mdata_string_fn, - &tmp_error); - if (tmp_error) - goto error2; - - /* Directory file */ - directory_fd = g_file_open_tmp ("gicomp-XXXXXX", &ctx->mdata_directory_fn, - &tmp_error); - if (tmp_error) - goto error1; - - ctx->mdata_struct = fdopen (struct_fd, "w"); - ctx->mdata_init = fdopen (init_fd, "w"); - ctx->mdata_string = fdopen (string_fd, "w"); - ctx->mdata_directory = fdopen (directory_fd, "w"); - - goto out; - - error1: - close (directory_fd); - g_remove (ctx->mdata_directory_fn); - error2: - close (string_fd); - g_remove (ctx->mdata_string_fn); - error3: - close (init_fd); - g_remove (ctx->mdata_init_fn); - error4: - close (struct_fd); - g_remove (ctx->mdata_struct_fn); - error: - g_propagate_error (error, tmp_error); - - g_free (ctx); - ctx = NULL; - out: - return ctx; -} - -void -g_idl_compiler_context_finalize (GIdlCompilerContext *ctx, - FILE *stream, - const gchar *shlib, - GError **error) -{ - fclose (ctx->mdata_struct); - write_compiled (ctx, stream, shlib, error); -} - -void -g_idl_compiler_context_destroy (GIdlCompilerContext *ctx) -{ - g_free (ctx->mdata_struct_fn); - g_free (ctx->mdata_init_fn); - g_free (ctx->mdata_string_fn); - g_free (ctx->mdata_directory_fn); - - g_free (ctx->struct_name); - g_free (ctx->namespace_name); - - g_list_foreach (ctx->dtypelist, (GFunc)deferred_entry_free, NULL); - g_list_free (ctx->dtypelist); - - g_list_foreach (ctx->dconstantlist, (GFunc)deferred_entry_free, NULL); - g_list_free (ctx->dconstantlist); - - g_hash_table_destroy (ctx->entriesdb); - g_hash_table_destroy (ctx->typesdb); - g_hash_table_destroy (ctx->strings); - g_slice_free (GIdlCompilerContext, ctx); -} - - -/** - * g_idl_compiler_write_string: - * @ctx: - * @str: - * String specific functions - * - * If string is already in the pool, return previous location, - * otherwise write string to the metadata at offset, put it - * in the pool and update offset. - */ -guint32 -g_idl_compiler_write_string (GIdlCompilerContext *ctx, - const gchar *str) -{ - gpointer value; - guint32 orig = ctx->string_offset; - - g_return_val_if_fail (str != NULL, 0); - - if (g_hash_table_lookup_extended (ctx->strings, str, NULL, &value)) - return GPOINTER_TO_INT (value); - - g_hash_table_insert (ctx->strings, (gpointer) str, - GINT_TO_POINTER (ctx->string_offset)); - - /* +1 is for the null byte that is added at the end of each string */ - ctx->string_offset += strlen (str) + 1; - - fprintf (ctx->mdata_string, " \"%s\\0\"\n", str); - - return orig; -} - -static guint16 -g_idl_compiler_write_dir_entry (GIdlCompilerContext *ctx, - guint16 blob_type, - const gchar *name, - gint entry_id) -{ - const char *entry_prototype = - " {\n" " %d,\n" - " %d,\n" - " 0,\n" - " " STRING_POINTER ", /* %s */\n" - " " TYPE_POINTER ",\n" - " },\n"; - guint orig = ctx->directory_entries; - - fprintf (ctx->mdata_directory, entry_prototype, - blob_type, - TRUE, - ctx->struct_name, g_idl_compiler_write_string (ctx, name), name, - ctx->struct_name, entry_id); - - ctx->directory_local_entries += 1; - ctx->directory_entries += 1; - return orig; -} - -static guint16 -g_idl_compiler_write_xref_entry (GIdlCompilerContext *ctx, - guint16 blob_type, - const gchar *name, - const gchar *namespace) -{ - const char *entry_prototype = - " {\n" " %d,\n" - " %d,\n" - " 0,\n" - " " STRING_POINTER ", /* %s */\n" - " " STRING_POINTER ", /* %s */\n" - " },\n"; - guint dir_id_res = ctx->directory_entries; - - fprintf (ctx->mdata_directory, entry_prototype, - blob_type, - FALSE, - ctx->struct_name, g_idl_compiler_write_string (ctx, name), name, - ctx->struct_name, g_idl_compiler_write_string (ctx, namespace), name); - - ctx->directory_entries += 1; - return dir_id_res; -} - -/* This is a unique id for each entry in the - * metadata that may need to be referenced elsewhere. - * Essentially anything that has to be given a - * name in the metadata struct. - */ -gint32 -g_idl_compiler_get_unique_id (void) -{ - static gint32 i = 0; - return ++i; -} - -void -g_idl_compiler_add_entry (GIdlCompilerContext *ctx, GIdlNode *node) -{ - guint entry_id; - guint dir_id; - SymbolEntry *entry; - - entry = g_slice_new0 (SymbolEntry); - entry_id = g_idl_compiler_get_unique_id (); - dir_id = g_idl_compiler_write_dir_entry (ctx, node->type, - node->name, entry_id); - - entry->entry_id = entry_id; - /* The directory array is indexed from 1 upwards. Just to confuse us */ - entry->dir_id = dir_id + 1; - - g_hash_table_insert (ctx->entriesdb, g_strdup (node->name), entry); -} - -static guint -g_idl_compiler_add_xref (GIdlCompilerContext *ctx, - const gchar *name) -{ - gint dir_id; - guint n_names; - gchar **names; - gchar *symbol; - gchar *namespace; - SymbolEntry *entry; - - names = g_strsplit (name, ".", 0); - n_names = g_strv_length (names); - - if (n_names < 2) - { - g_warning ("External reference with no namespace"); - symbol = g_strjoinv ("", &names[0]); - namespace = NULL; - } - else - { - symbol = g_strjoinv (".", &names[1]); - namespace = names[0]; - } - - fprintf (ctx->mdata_directory, - " {\n" - " 0,\n" - " 0,\n" - " 0,\n" - " " STRING_POINTER ", /* %s */\n", - ctx->struct_name, - g_idl_compiler_write_string (ctx, symbol), name); - - if (namespace) - fprintf (ctx->mdata_directory, " " STRING_POINTER ", /* %s */\n", - ctx->struct_name, g_idl_compiler_write_string (ctx, namespace), - name); - else - fprintf (ctx->mdata_directory, " 0,\n"); - fprintf (ctx->mdata_directory, " },\n"); - - dir_id = ctx->directory_entries; - ctx->directory_entries += 1; - - /* The Directory array is indexed from 1 upwards. Just to confuse us */ - entry = g_slice_new0 (SymbolEntry); - entry->dir_id = dir_id + 1; - g_hash_table_insert (ctx->entriesdb, g_strdup (name), entry); - - g_free(symbol); - g_strfreev (names); - return dir_id + 1; -} - -guint -g_idl_compiler_get_entry_id (GIdlCompilerContext *ctx, - const gchar *name) -{ - SymbolEntry *entry; - - entry = g_hash_table_lookup (ctx->entriesdb, name); - return entry->entry_id; -} - -guint -g_idl_compiler_get_entry_dirid (GIdlCompilerContext *ctx, - const gchar *name) -{ - SymbolEntry *entry; - - entry = g_hash_table_lookup (ctx->entriesdb, name); - if (entry) - return entry->dir_id; - - /* If no entry found assume its an external reference */ - return g_idl_compiler_add_xref (ctx, name); -} - -void -g_idl_compiler_push_deferred_type_node (GIdlCompilerContext *ctx, - GIdlNode *node, - guint entry_id) -{ - DeferredEntry *entry; - - entry = g_slice_new (DeferredEntry); - entry->node = node; - entry->entry_id = entry_id; - ctx->dtypelist = g_list_prepend (ctx->dtypelist, entry); -} - -GIdlNode * -g_idl_compiler_pop_deferred_type_node (GIdlCompilerContext *ctx, - guint *entry_id) -{ - DeferredEntry *entry; - GIdlNode *node; - - if (!ctx->dtypelist) - return NULL; - - entry = (DeferredEntry *) ctx->dtypelist->data; - ctx->dtypelist = g_list_remove (ctx->dtypelist, (gpointer) entry); - *entry_id = entry->entry_id; - node = entry->node; - deferred_entry_free (entry); - return node; -} - -void -g_idl_compiler_push_deferred_signature_node (GIdlCompilerContext * ctx, - GIdlNode * node, guint entry_id) -{ - DeferredEntry *entry; - - entry = g_slice_new (DeferredEntry); - entry->node = node; - entry->entry_id = entry_id; - ctx->dsignaturelist = g_list_prepend (ctx->dsignaturelist, entry); -} - -GIdlNode* -g_idl_compiler_pop_deferred_signature_node (GIdlCompilerContext *ctx, - guint *entry_id) -{ - DeferredEntry *entry; - GIdlNode *node; - - if (!ctx->dsignaturelist) - return NULL; - - entry = (DeferredEntry *) ctx->dsignaturelist->data; - ctx->dsignaturelist = g_list_remove (ctx->dsignaturelist, entry); - *entry_id = entry->entry_id; - node = entry->node; - deferred_entry_free (entry); - return node; -} - -void -g_idl_compiler_push_deferred_constant (GIdlCompilerContext *ctx, - GIdlNode *node, - guint entry_id) -{ - DeferredEntry *constant; - - constant = g_slice_new (DeferredEntry); - constant->node = node; - constant->entry_id = entry_id; - ctx->dconstantlist = g_list_prepend (ctx->dconstantlist, constant); -} - -GIdlNode * -g_idl_compiler_pop_deferred_constant (GIdlCompilerContext *ctx, - guint *entry_id) -{ - DeferredEntry *deferred_entry; - GIdlNode *node; - - if (!ctx->dconstantlist) - return NULL; - - deferred_entry = (DeferredEntry *) ctx->dconstantlist->data; - ctx->dconstantlist = g_list_remove (ctx->dconstantlist, deferred_entry); - *entry_id = deferred_entry->entry_id; - node = deferred_entry->node; - deferred_entry_free (deferred_entry); - return node; -} diff --git a/tools/gidlcompilercontext.h b/tools/gidlcompilercontext.h deleted file mode 100644 index 5f861a3b..00000000 --- a/tools/gidlcompilercontext.h +++ /dev/null @@ -1,131 +0,0 @@ - -#ifndef __G_IDL_COMPILER_CONTEXT_H__ -#define __G_IDL_COMPILER_CONTEXT_H__ - -#include <stdio.h> -#include <glib.h> - -#include "gidlnode.h" - -typedef struct _GIdlCompilerContext GIdlCompilerContext; - -struct _GIdlCompilerContext -{ - gchar *namespace_name; - gchar *struct_name; - - gchar *mdata_struct_fn; - FILE *mdata_struct; - - gchar *mdata_init_fn; - FILE *mdata_init; - - guint32 string_offset; - gchar *mdata_string_fn; - FILE *mdata_string; - GHashTable *strings; - - guint32 directory_local_entries; - guint32 directory_entries; - gchar *mdata_directory_fn; - FILE *mdata_directory; - - /* The entriesdb contains all the - * types that have a directory entry. - * - * It must be filled in before beginning to write - * out the data. This is because it is used - * to decide whether a type is available or - * needs an external reference - */ - GHashTable *entriesdb; - - /* The typesdb is used to store type names to - * entry ids, so that multiple similar type blobs are - * not written out - */ - GHashTable *typesdb; - - /* Type blobs are accessed in the middle of writing another - * entry. Writing them needs to be deferred until after - * that entry is finished. - */ - GList *dtypelist; - - /* Signature blobs are accessed in the middle of writing - * other entries, and so need to be deferred. - * - * There is no signature node, so the function / callback - * nodes are stored instead. - */ - GList *dsignaturelist; - - /* Constants have values that are of a variable size, - * and have to be written out after the entry has finished, - * so are stored as a variant in this list until the time comes. - */ - GList *dconstantlist; -}; - -GIdlCompilerContext *g_idl_compiler_context_new (const gchar * namespace, - GError ** err); - -void -g_idl_compiler_context_finalize (GIdlCompilerContext *ctx, - FILE *stream, - const gchar *shlib, - GError **err); - -void g_idl_compiler_context_destroy (GIdlCompilerContext * ctx); - -guint32 g_idl_compiler_write_string (GIdlCompilerContext * ctx, - const gchar * str); - -gint32 g_idl_compiler_get_unique_id (void); - -void g_idl_compiler_add_entry (GIdlCompilerContext *ctx, - GIdlNode *node); - -guint g_idl_compiler_get_entry_id (GIdlCompilerContext * ctx, - const gchar * name); - -guint g_idl_compiler_get_entry_dirid (GIdlCompilerContext * ctx, - const gchar * name); - -void g_idl_compiler_push_deferred_type_node (GIdlCompilerContext * ctx, - GIdlNode * node, - guint entry_id); - -GIdlNode *g_idl_compiler_pop_deferred_type_node (GIdlCompilerContext * ctx, - guint * entry_id); - -void g_idl_compiler_push_deferred_signature_node (GIdlCompilerContext * ctx, - GIdlNode * node, - guint entry_id); - -GIdlNode *g_idl_compiler_pop_deferred_signature_node (GIdlCompilerContext * ctx, - guint * entry_id); - -void g_idl_compiler_push_deferred_constant (GIdlCompilerContext * ctx, - GIdlNode * node, - guint entry_id); - -GIdlNode * g_idl_compiler_pop_deferred_constant (GIdlCompilerContext * ctx, - guint * entry_id); - -#define SECTION(sEC) "info_" #sEC -#define ID_TO_ENTRY "entry_%d" - -/* Parameters (To the string) - * Metadata struct name - * Offset into string buffer - Given by g_idl_compiler_write_string() - */ -#define STRING_POINTER "G_STRUCT_OFFSET(%s," SECTION(strings) ") + %d" - -/* Parameters(To the string) - * Metatada struct name - * Type name - */ -#define TYPE_POINTER "G_STRUCT_OFFSET(%s,"ID_TO_ENTRY")" - -#endif /*__G_IDL_COMPILER_CONTEXT_H__*/ diff --git a/tools/gidlcompilerentrynode.c b/tools/gidlcompilerentrynode.c deleted file mode 100644 index f3ea71aa..00000000 --- a/tools/gidlcompilerentrynode.c +++ /dev/null @@ -1,1266 +0,0 @@ -/* GObject introspection: Node compilation - * - * Copyright (C) 2005 Matthias Clasen - * Copyright (C) 2008 Codethink Ltd - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "gmetadata.h" - -#include "gidlnode.h" -#include "gidlmodule.h" -#include "gidlcompilercontext.h" -#include "gidlcompilertypenode.h" - -/* PARAMETER BLOB COMPILATION */ -/*----------------------------*/ -/* Blobs in this section do not get a directory entry. - * They are not types in themselves but are just information - * about types, such as the signals of an object or the fields - * of a struct. - */ - -/*VALUE*/ -/* Used in enums and flags */ -static void -include_value (GIdlNode * node, GIdlCompilerContext * ctx) -{ - GIdlNodeValue *value = (GIdlNodeValue *) node; - const gchar *value_prototype = " {%d, %d, " STRING_POINTER ", %d},\n"; - - fprintf (ctx->mdata_init, value_prototype, - value->deprecated, - 0, - ctx->struct_name, g_idl_compiler_write_string (ctx, node->name), - value->value); -} - -/*PARAM*/ -/* Used in signatures */ -static void -include_param (GIdlNode * node, GIdlCompilerContext * ctx) -{ - GIdlNodeParam *param = (GIdlNodeParam *) node; - - const gchar *param_header = - " {\n" - " "STRING_POINTER",\n" - " %d, %d, %d, %d, %d, %d, %d, %d, 0,\n"; - - fprintf (ctx->mdata_init, param_header, - ctx->struct_name, g_idl_compiler_write_string (ctx, node->name), - param->in, - param->out, - param->dipper, - param->null_ok, - param->optional, - param->transfer, - param->shallow_transfer, - param->retval); - - g_idl_compiler_write_simple_type_blob ((GIdlNode *)param->type, ctx); - - fprintf(ctx->mdata_init, " },\n"); -} - -/*V FUNC*/ -/* Used in objects and interfaces */ -static void -include_vfunc (GIdlNode * node, GIdlCompilerContext * ctx) -{ - guint signature_id; - GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *) node; - const char *vfunc_header = - " {\n" - " "STRING_POINTER",\n" - " %d, %d, %d, %d, 0, %d,\n" - " %d, 0,\n" - " "TYPE_POINTER",\n" - " },\n"; - - signature_id = g_idl_compiler_get_unique_id(); - - g_idl_compiler_push_deferred_signature_node(ctx, node, signature_id); - - fprintf(ctx->mdata_init, vfunc_header, - ctx->struct_name, g_idl_compiler_write_string (ctx, node->name), - 0, /*FIXME*/ - 0, /*FIXME*/ - 0, /*FIXME*/ - 0, /*FIXME*/ - 0, /*FIXME*/ - vfunc->offset, - ctx->struct_name, signature_id); -} - -/*PROPERTY*/ -/* Used in objects and interfaces */ -static void -include_property (GIdlNode * node, GIdlCompilerContext * ctx) -{ - GIdlNodeProperty *property = (GIdlNodeProperty *) node; - - const gchar *property_header = - " {\n" - " "STRING_POINTER", %d, %d, %d, %d, %d, 0,\n"; - - fprintf (ctx->mdata_init, property_header, - ctx->struct_name, g_idl_compiler_write_string (ctx, node->name), - property->deprecated, - property->readable, - property->writable, - property->construct, - property->construct_only); - - /*Insert simple type blob here */ - g_idl_compiler_write_simple_type_blob ((GIdlNode *)property->type, ctx); - - fprintf (ctx->mdata_init, " },\n"); -} - -/*FIELD*/ -/* Used in struct */ -static void -include_field (GIdlNode * node, GIdlCompilerContext * ctx) -{ - GIdlNodeField *field = (GIdlNodeField *) node; - - const gchar *field_header = - " {\n" - " "STRING_POINTER", %d, %d, %d, %d, %d,\n"; - - fprintf (ctx->mdata_init, field_header, - ctx->struct_name, g_idl_compiler_write_string (ctx, node->name), - field->readable, field->writable, 0, 0, field->offset); - - /*Insert simple type blob here */ - g_idl_compiler_write_simple_type_blob ((GIdlNode *)field->type, ctx); - - fprintf (ctx->mdata_init, " },\n"); -} - - /*SIGNAL*/ -/* Used in interface and object */ -static void -include_signal (GIdlNode * node, GIdlCompilerContext * ctx) -{ - guint signature_id; - GIdlNodeSignal *signal = (GIdlNodeSignal *) node; - const char *signal_header = - " {\n" - " %d, %d, %d, %d, %d,\n" - " %d, %d, %d, %d, %d,\n" - " 0,\n" - " %d,\n" - " "STRING_POINTER",\n" - " "TYPE_POINTER",\n" - " },\n"; - - signature_id = g_idl_compiler_get_unique_id(); - - g_idl_compiler_push_deferred_signature_node(ctx, node, signature_id); - - fprintf(ctx->mdata_init, signal_header, - signal->deprecated, - signal->run_first, - signal->run_last, - signal->run_cleanup, - signal->no_recurse, - signal->detailed, - signal->action, - signal->no_hooks, - 0, /*FIXME*/ - 0, /*FIXME*/ - 0, /*FIXME*/ - ctx->struct_name, g_idl_compiler_write_string (ctx, node->name), - ctx->struct_name, signature_id); -} - -/*METHOD*/ -/*Used in struct object interface, uses the FunctionBlob*/ -static void -include_method (GIdlNode * node, - GIdlCompilerContext * ctx) -{ - guint signature_id; - GIdlNodeFunction *function = (GIdlNodeFunction *) node; - const char *function_header = - " {\n" - " %d, %d, %d, %d, %d, %d, 0, %d,\n" - " "STRING_POINTER",\n" - " "STRING_POINTER",\n" - " "TYPE_POINTER",\n" - " },\n"; - - signature_id = g_idl_compiler_get_unique_id(); - - g_idl_compiler_push_deferred_signature_node(ctx, node, signature_id); - - fprintf(ctx->mdata_init, function_header, - BLOB_TYPE_FUNCTION, - function->deprecated, - function->is_setter, - function->is_getter, - function->is_constructor, - function->wraps_vfunc, - 0, /*index??*/ - ctx->struct_name, g_idl_compiler_write_string (ctx, node->name), - ctx->struct_name, g_idl_compiler_write_string (ctx, function->symbol), - ctx->struct_name, signature_id); -} - -/*CONSTANT*/ -static void -include_constant (GIdlNode * node, - GIdlCompilerContext * ctx) -{ - GIdlNodeConstant *constant = (GIdlNodeConstant *)node; - guint entry_id; - const gchar *constant_header = - " {\n" - " %d, %d, 0,\n" /*type/deprecated/reserved */ - " "STRING_POINTER",\n"; /*name */ - - const gchar *constant_footer = - " %d, "TYPE_POINTER"\n" /*size/offset*/ - " },\n"; - - fprintf (ctx->mdata_init, constant_header, - BLOB_TYPE_CONSTANT, - constant->deprecated, - ctx->struct_name, g_idl_compiler_write_string (ctx, node->name)); - - g_idl_compiler_write_simple_type_blob ((GIdlNode *)constant->type, ctx); - - entry_id = g_idl_compiler_get_unique_id(); - - g_idl_compiler_push_deferred_constant(ctx, node, entry_id); - - fprintf (ctx->mdata_init, constant_footer, - 0, /*FIXME I'm excluding the size, where is this used?*/ - ctx->struct_name, entry_id); -} - -/*ENTRY BLOB COMPILATION*/ -/*----------------------*/ -/* Blobs in this section are given a directory entry - * and can be used as a type - */ - -/*ENUM / FLAGS*/ -static void -write_enum (GIdlNode * node, - guint entry_id, - GIdlCompilerContext * ctx) -{ - GIdlNodeEnum *enum_ = (GIdlNodeEnum *) node; - guint16 blob_type; - guint32 gtype_name = 0; - guint32 gtype_init = 0; - guint unregistered; - GList *c; - - const gchar *enum_flags_struct = - " struct\n" - " {\n" - " EnumBlob fixed;\n" - " ValueBlob values[%d];\n" - " } " ID_TO_ENTRY ";\n"; - - const gchar *enum_flags_header = - " {\n" - " {\n" - " %d, %d, %d, %d,\n" /*type/deprecated/unregistered/reserved */ - " " STRING_POINTER ",\n" /*name */ - " " STRING_POINTER ",\n" /*gtype-name */ - " " STRING_POINTER ",\n" /*gtype-init */ - " %d, %d\n" " },\n"; /*n_values/reserved */ - - if (node->type == G_IDL_NODE_ENUM) - blob_type = BLOB_TYPE_ENUM; - else - blob_type = BLOB_TYPE_FLAGS; - - if (enum_->gtype_name) - { - unregistered = FALSE; - gtype_name = g_idl_compiler_write_string (ctx, enum_->gtype_name); - gtype_init = g_idl_compiler_write_string (ctx, enum_->gtype_init); - } - else - { - unregistered = TRUE; - gtype_name = 0; - gtype_init = 0; - } - - fprintf (ctx->mdata_struct, enum_flags_struct, - g_list_length (enum_->values), entry_id); - - fprintf (ctx->mdata_init, enum_flags_header, - blob_type, - enum_->deprecated, - unregistered, - 0, - ctx->struct_name, g_idl_compiler_write_string (ctx, node->name), - ctx->struct_name, gtype_name, - ctx->struct_name, gtype_init, g_list_length (enum_->values), 0); - - /*Insert value initialisers here */ - fprintf (ctx->mdata_init, " {\n"); - for (c = enum_->values; c; c = c->next) - { - include_value (c->data, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - fprintf (ctx->mdata_init, " },\n\n"); -} - -/*FUNCTION*/ -static void -write_function (GIdlNode * node, - guint entry_id, - GIdlCompilerContext * ctx) -{ - const char *function_struct = - " FunctionBlob "ID_TO_ENTRY";\n"; - - fprintf(ctx->mdata_struct, function_struct, entry_id); - - include_method(node, ctx); -} - -/*SIGNATURE*/ -static void -write_signature (GIdlNode * node, - guint entry_id, - GIdlCompilerContext * ctx) -{ - GList *c; - GIdlNodeFunction *function = (GIdlNodeFunction *) node; - GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *) node; - GIdlNodeSignal *signal = (GIdlNodeSignal *) node; - guint n_args; - GIdlNodeType *result_type; - guint null_ok; - guint transfer; - guint shallow_transfer; - GList *param_list; - - const char *signature_struct = - " struct\n" - " {\n" - " SignatureBlob fixed;\n" - " ArgBlob values[%d];\n" - " } " ID_TO_ENTRY ";\n"; - - const char *signature_prototype = - " %d, %d, %d, 0, %d,\n"; - - switch (node->type) - { - case G_IDL_NODE_CALLBACK: - case G_IDL_NODE_FUNCTION: - null_ok = function->result->null_ok, - transfer = function->result->transfer, - shallow_transfer = function->result->shallow_transfer, - param_list = function->parameters; - result_type = function->result->type; - break; - case G_IDL_NODE_VFUNC: - null_ok = vfunc->result->null_ok, - transfer = vfunc->result->transfer, - shallow_transfer = vfunc->result->shallow_transfer, - param_list = vfunc->parameters; - result_type = vfunc->result->type; - break; - case G_IDL_NODE_SIGNAL: - null_ok = signal->result->null_ok, - transfer = signal->result->transfer, - shallow_transfer = signal->result->shallow_transfer, - param_list = signal->parameters; - result_type = signal->result->type; - break; - default: - g_assert_not_reached(); - break; - } - - n_args = g_list_length(param_list); - - fprintf(ctx->mdata_struct, signature_struct, n_args, entry_id); - - fprintf(ctx->mdata_init, " {\n"); - fprintf(ctx->mdata_init, " {\n"); - - g_idl_compiler_write_simple_type_blob ((GIdlNode *)result_type, ctx); - - fprintf(ctx->mdata_init, signature_prototype, - null_ok, - transfer, - shallow_transfer, - n_args); - - fprintf (ctx->mdata_init, " },\n"); - - /*Write out all the args*/ - fprintf (ctx->mdata_init, " {\n"); - for (c = param_list; c; c = c->next) - { - include_param (c->data, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - fprintf(ctx->mdata_init, " },\n\n"); -} - -/*CALLBACK*/ -static void -write_callback (GIdlNode * node, - guint entry_id, - GIdlCompilerContext * ctx) -{ - guint signature_id; - GIdlNodeFunction *function = (GIdlNodeFunction *) node; - - const char *callback_struct = - " CallbackBlob "ID_TO_ENTRY";\n"; - - const char *callback_header = - " {\n" - " %d, %d, 0,\n" - " "STRING_POINTER",\n" - " "TYPE_POINTER",\n" - " },\n"; - - fprintf(ctx->mdata_struct, callback_struct, entry_id); - - signature_id = g_idl_compiler_get_unique_id(); - - g_idl_compiler_push_deferred_signature_node(ctx, node, signature_id); - - fprintf(ctx->mdata_init, callback_header, - BLOB_TYPE_CALLBACK, - function->deprecated, - ctx->struct_name, g_idl_compiler_write_string (ctx, node->name), - ctx->struct_name, signature_id); -} - -/*BOXED*/ -/*TODO merge the boxed and struct functions.*/ -static void -write_boxed (GIdlNode * node, - guint entry_id, - GIdlCompilerContext * ctx) -{ - GIdlNodeBoxed *boxed = (GIdlNodeBoxed *) node; - guint16 n_method = 0; - guint16 n_field = 0; - GList *l; - - const char *struct_struct = - " struct\n" - " {\n" - " StructBlob fixed;\n" - " FieldBlob fields[%d];\n" - " FunctionBlob methods[%d];\n" - " } " ID_TO_ENTRY ";\n"; - - const gchar *struct_header = - " {\n" - " {\n" - " %d, %d, %d, %d,\n" /*type/deprecated/unregistered/reserved */ - " " STRING_POINTER ",\n" /*name */ - " " STRING_POINTER ",\n" /*gtype-name */ - " " STRING_POINTER ",\n" /*gtype-init */ - " %d, %d\n" /*n_fields/n_methods */ - " },\n"; /*n_values/reserved */ - - for (l = boxed->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_FIELD) - { - n_field++; - } - else - { - n_method++; - } - } - - fprintf (ctx->mdata_struct, struct_struct, n_field, n_method, entry_id); - - fprintf (ctx->mdata_init, struct_header, - BLOB_TYPE_STRUCT, - boxed->deprecated, - FALSE, - 0, - ctx->struct_name, g_idl_compiler_write_string (ctx, node->name), - ctx->struct_name, g_idl_compiler_write_string (ctx, boxed->gtype_name), - ctx->struct_name, g_idl_compiler_write_string (ctx, boxed->gtype_init), - n_field, n_method); - - /*Insert field initialisers here */ - fprintf (ctx->mdata_init, " {\n"); - for (l = boxed->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_FIELD) - include_field (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - /*Insert method initialisers here */ - fprintf (ctx->mdata_init, " {\n"); - for (l = boxed->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_FUNCTION) - include_method (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - fprintf (ctx->mdata_init, " },\n\n"); -} - -/*STRUCT*/ -static void -write_struct (GIdlNode * node, - guint entry_id, - GIdlCompilerContext * ctx) -{ - GIdlNodeStruct *struct_ = (GIdlNodeStruct *) node; - guint16 n_method = 0; - guint16 n_field = 0; - GList *l; - - const char *struct_struct = - " struct\n" - " {\n" - " StructBlob fixed;\n" - " FieldBlob fields[%d];\n" - " FunctionBlob methods[%d];\n" - " } " ID_TO_ENTRY ";\n"; - - const gchar *struct_header = - " {\n" - " {\n" - " %d, %d, %d, %d,\n" /*type/deprecated/unregistered/reserved */ - " " STRING_POINTER ",\n" /*name */ - " " STRING_POINTER ",\n" /*gtype-name */ - " " STRING_POINTER ",\n" /*gtype-init */ - " %d, %d\n" /*n_fields/n_methods */ - " },\n"; /*n_values/reserved */ - - for (l = struct_->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_FIELD) - { - n_field++; - } - else - { - n_method++; - } - } - - fprintf (ctx->mdata_struct, struct_struct, n_field, n_method, entry_id); - - fprintf (ctx->mdata_init, struct_header, - BLOB_TYPE_STRUCT, - struct_->deprecated, - TRUE, - 0, - ctx->struct_name, g_idl_compiler_write_string (ctx, node->name), - ctx->struct_name, 0, ctx->struct_name, 0, n_field, n_method); - - /*Insert field initialisers here */ - fprintf (ctx->mdata_init, " {\n"); - for (l = struct_->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_FIELD) - include_field (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - /*Insert method initialisers here */ - fprintf (ctx->mdata_init, " {\n"); - for (l = struct_->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_FUNCTION) - include_method (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - fprintf (ctx->mdata_init, " },\n\n"); -} - -/*UNION*/ -static void -write_union (GIdlNode * node, - guint entry_id, - GIdlCompilerContext * ctx) -{ - GIdlNodeUnion *union_ = (GIdlNodeUnion *)node; - guint16 n_method = 0; - guint16 n_field = 0; - guint16 n_constant = 0; - gboolean discriminated = FALSE; - gboolean unregistered = TRUE; - GList *l; - - const char *union_struct = - " struct\n" - " {\n" - " UnionBlob fixed;\n" - " FieldBlob fields[%d];\n" - " FunctionBlob methods[%d];\n" - " ConstantBlob discriminator_values[%d];\n" - " } " ID_TO_ENTRY ";\n"; - - const gchar *union_header = - " {\n" - " {\n" - " %d, %d, %d, %d, 0,\n" /*type/deprecated/unregistered/descriminated */ - " " STRING_POINTER ",\n" /*name */ - " " STRING_POINTER ",\n" /*gtype-name */ - " " STRING_POINTER ",\n" /*gtype-init */ - " %d, %d,\n" /*n_fields/n_methods */ - " %d,\n"; /*discriminator_offset*/ - - for (l = union_->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_FIELD) - { - n_field++; - } - else - { - n_method++; - } - } - - if (union_->discriminator_type) - { - discriminated = TRUE; - n_constant = g_list_length(union_->discriminators); - } - - if (union_->gtype_name) - { - unregistered = FALSE; - } - - fprintf (ctx->mdata_struct, union_struct, n_field, n_method, n_constant, entry_id); - - fprintf (ctx->mdata_init, union_header, - BLOB_TYPE_UNION, - union_->deprecated, - unregistered, - discriminated, - ctx->struct_name, g_idl_compiler_write_string (ctx, node->name), - ctx->struct_name, g_idl_compiler_write_string (ctx, union_->gtype_name), - ctx->struct_name, g_idl_compiler_write_string (ctx, union_->gtype_init), - n_field, n_method, - union_->discriminator_offset); - - if (discriminated) - { - g_idl_compiler_write_simple_type_blob ((GIdlNode *)union_->discriminator_type, ctx); - } - else - { - fprintf (ctx->mdata_init, " {},\n"); - } - fprintf (ctx->mdata_init, " },\n"); - - /*Insert field initialisers here */ - fprintf (ctx->mdata_init, " {\n"); - for (l = union_->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_FIELD) - include_field (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - /*Insert method initialisers here */ - fprintf (ctx->mdata_init, " {\n"); - for (l = union_->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_FUNCTION) - include_method (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - /*Insert discriminators here*/ - fprintf (ctx->mdata_init, " {\n"); - for (l = union_->discriminators; l; l = l->next) - { - GIdlNode *tnode = l->data; - include_constant (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - fprintf (ctx->mdata_init, " },\n\n"); -} - -/*OBJECT*/ -static void -write_object (GIdlNode * node, - guint entry_id, - GIdlCompilerContext * ctx) -{ - GIdlNodeInterface *object = (GIdlNodeInterface *) node; - guint num_interfaces = 0; - guint num_fields = 0; - guint num_properties = 0; - guint num_methods = 0; - guint num_signals = 0; - guint num_vfuncs = 0; - guint num_constants = 0; - - GList *l; - - const char *object_struct = - " struct\n" - " {\n" - " ObjectBlob fixed;\n" - " guint16 interfaces[%d];\n" - " FieldBlob fields[%d];\n" - " PropertyBlob properties[%d];\n" - " FunctionBlob methods[%d];\n" - " SignalBlob signals[%d];\n" - " VFuncBlob vfuncs[%d];\n" - " ConstantBlob constants[%d];\n" - " } " ID_TO_ENTRY ";\n"; - - const gchar *object_header = - " {\n" - " {\n" - " %d, %d, 0,\n" - " " STRING_POINTER ",\n" - " " STRING_POINTER ",\n" - " " STRING_POINTER ",\n"; - - const gchar *object_footer = - " %d, %d, %d, %d, %d, %d, %d,\n" - " },\n"; - - const gchar *type_entry = - " %d,\n"; - - for (l = object->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - switch (tnode->type) - { - case G_IDL_NODE_FIELD: - num_fields++; - break; - case G_IDL_NODE_PROPERTY: - num_properties++; - break; - case G_IDL_NODE_FUNCTION: - num_methods++; - break; - case G_IDL_NODE_SIGNAL: - num_signals++; - break; - case G_IDL_NODE_VFUNC: - num_vfuncs++; - break; - case G_IDL_NODE_CONSTANT: - num_constants++; - break; - default: - ; - } - } - - num_interfaces = g_list_length(object->interfaces); - - fprintf(ctx->mdata_struct, object_struct, - num_interfaces, - num_fields, - num_properties, - num_methods, - num_signals, - num_vfuncs, - num_constants, - entry_id); - - fprintf (ctx->mdata_init, object_header, - BLOB_TYPE_INTERFACE, - object->deprecated, - ctx->struct_name, g_idl_compiler_write_string (ctx, node->name), - ctx->struct_name, g_idl_compiler_write_string (ctx, object->gtype_name), - ctx->struct_name, g_idl_compiler_write_string (ctx, object->gtype_init)); - - if (object->parent) - { - fprintf(ctx->mdata_init, type_entry, - g_idl_compiler_get_entry_dirid(ctx, object->parent)); - } - else - { - fprintf (ctx->mdata_init, " 0,\n"); - } - - fprintf (ctx->mdata_init, object_footer, - num_interfaces, - num_fields, - num_properties, - num_methods, - num_signals, - num_vfuncs, - num_constants); - - fprintf (ctx->mdata_init, " {\n"); - for (l = object->interfaces; l; l = l->next) - { - gchar *interface = l->data; - fprintf(ctx->mdata_init, type_entry, - g_idl_compiler_get_entry_dirid(ctx, interface)); - } - fprintf (ctx->mdata_init, " },\n"); - - /*Insert fields here*/ - fprintf (ctx->mdata_init, " {\n"); - for (l = object->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_FIELD) - include_field (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - /*Insert properties here*/ - fprintf (ctx->mdata_init, " {\n"); - for (l = object->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_PROPERTY) - include_property (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - /*Insert functions here*/ - fprintf (ctx->mdata_init, " {\n"); - for (l = object->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_FUNCTION) - include_method (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - /*Insert signals here*/ - fprintf (ctx->mdata_init, " {\n"); - for (l = object->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_SIGNAL) - include_signal (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - /*Insert vfuncs here*/ - fprintf (ctx->mdata_init, " {\n"); - for (l = object->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_VFUNC) - include_vfunc (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - /*Insert constants here*/ - fprintf (ctx->mdata_init, " {\n"); - for (l = object->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_CONSTANT) - include_constant (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - fprintf (ctx->mdata_init, " },\n\n"); -} - -/*INTERFACE*/ -static void -write_interface(GIdlNode * node, - guint entry_id, - GIdlCompilerContext * ctx) -{ - GIdlNodeInterface *iface = (GIdlNodeInterface *) node; - guint num_prerequisites = 0; - guint num_properties = 0; - guint num_methods = 0; - guint num_signals = 0; - guint num_vfuncs = 0; - guint num_constants = 0; - - GList *l; - - const char *interface_struct = - " struct\n" - " {\n" - " InterfaceBlob fixed;\n" - " guint16 prerequisites[%d];\n" - " PropertyBlob properties[%d];\n" - " FunctionBlob methods[%d];\n" - " SignalBlob signals[%d];\n" - " VFuncBlob vfuncs[%d];\n" - " ConstantBlob constants[%d];\n" - " } " ID_TO_ENTRY ";\n"; - - const gchar *interface_header = - " {\n" - " {\n" - " %d, %d, 0,\n" - " " STRING_POINTER ",\n" - " " STRING_POINTER ",\n" - " " STRING_POINTER ",\n" - " %d, %d, %d, %d, %d, %d,\n" - " },\n"; - - const gchar *prereq_entry = - " %d,\n"; - - for (l = iface->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - switch (tnode->type) - { - case G_IDL_NODE_PROPERTY: - num_properties++; - break; - case G_IDL_NODE_FUNCTION: - num_methods++; - break; - case G_IDL_NODE_SIGNAL: - num_signals++; - break; - case G_IDL_NODE_VFUNC: - num_vfuncs++; - break; - case G_IDL_NODE_CONSTANT: - num_constants++; - break; - default: - ; - } - } - - num_prerequisites = g_list_length(iface->prerequisites); - - fprintf(ctx->mdata_struct, interface_struct, - num_prerequisites, - num_properties, - num_methods, - num_signals, - num_vfuncs, - num_constants, - entry_id); - - fprintf (ctx->mdata_init, interface_header, - BLOB_TYPE_INTERFACE, - iface->deprecated, - ctx->struct_name, g_idl_compiler_write_string (ctx, node->name), - ctx->struct_name, g_idl_compiler_write_string (ctx, iface->gtype_name), - ctx->struct_name, g_idl_compiler_write_string (ctx, iface->gtype_init), - num_prerequisites, - num_properties, - num_methods, - num_signals, - num_vfuncs, - num_constants); - - fprintf (ctx->mdata_init, " {\n"); - for (l = iface->prerequisites; l; l = l->next) - { - gchar *prereq = l->data; - fprintf(ctx->mdata_init, prereq_entry, - g_idl_compiler_get_entry_dirid(ctx, prereq)); - } - fprintf (ctx->mdata_init, " },\n"); - - /*Insert properties here*/ - fprintf (ctx->mdata_init, " {\n"); - for (l = iface->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_PROPERTY) - include_property (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - /*Insert functions here*/ - fprintf (ctx->mdata_init, " {\n"); - for (l = iface->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_FUNCTION) - include_method (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - /*Insert signals here*/ - fprintf (ctx->mdata_init, " {\n"); - for (l = iface->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_SIGNAL) - include_signal (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - /*Insert vfuncs here*/ - fprintf (ctx->mdata_init, " {\n"); - for (l = iface->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_VFUNC) - include_vfunc (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - /*Insert constants here*/ - fprintf (ctx->mdata_init, " {\n"); - for (l = iface->members; l; l = l->next) - { - GIdlNode *tnode = l->data; - if (tnode->type == G_IDL_NODE_CONSTANT) - include_constant (tnode, ctx); - } - fprintf (ctx->mdata_init, " },\n"); - - fprintf (ctx->mdata_init, " },\n\n"); -} - -/*ERROR DOMAIN*/ -static void -write_error_domain (GIdlNode * node, - guint entry_id, - GIdlCompilerContext * ctx) -{ - GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *) node; - const char *error_domain_struct = - " ErrorDomainBlob " ID_TO_ENTRY ";\n"; - - const gchar *error_domain_header = - " {\n" - " %d, %d, 0,\n" - " " STRING_POINTER ",\n" /*name */ - " " STRING_POINTER ",\n" /*get-quark */ - " " TYPE_POINTER ",\n" /*error-codes*/ - " 0,\n" - " },\n\n"; - - fprintf(ctx->mdata_struct, error_domain_struct, entry_id); - - fprintf(ctx->mdata_init, error_domain_header, - BLOB_TYPE_ERROR_DOMAIN, - domain->deprecated, - ctx->struct_name, g_idl_compiler_write_string (ctx, node->name), - ctx->struct_name, g_idl_compiler_write_string (ctx, domain->getquark), - ctx->struct_name, g_idl_compiler_get_entry_id (ctx, domain->codes)); -} - -/*CONSTANT*/ -static void -write_constant (GIdlNode * node, - guint entry_id, - GIdlCompilerContext * ctx) -{ - const char *constant_struct = - " ConstantBlob " ID_TO_ENTRY ";\n"; - - fprintf(ctx->mdata_struct, constant_struct, entry_id); - - include_constant(node, ctx); -} - -static void -write_deferred_constant_values(GIdlCompilerContext *ctx) -{ - /* TODO there are very few symbols that can be represented - * as a constant, do we check if something is awry here - * to prevent errors at compilation time? - */ - GIdlNodeConstant *constant; - guint entry_id; - gchar *type_string; - - const char *cvalue_struct = - " %s " ID_TO_ENTRY ";\n"; - - const char *cvalue_str_struct = - " gchar *" ID_TO_ENTRY ";\n"; - - constant = (GIdlNodeConstant *) g_idl_compiler_pop_deferred_constant(ctx, &entry_id); - while (constant != NULL) - { - fprintf(ctx->mdata_init, " /*Entry - %d*/\n", - entry_id); - if (constant->type->tag <= TYPE_TAG_DOUBLE) - { - fprintf(ctx->mdata_struct, cvalue_struct, - g_idl_compiler_name_basic_type(constant->type->tag), - entry_id); - fprintf(ctx->mdata_init, " %s,\n", - constant->value); - } - else if (constant->type->tag <= TYPE_TAG_FILENAME) - { - fprintf(ctx->mdata_struct, cvalue_str_struct, - entry_id); - fprintf(ctx->mdata_init, " \"%s\",\n", - constant->value); - } - else if (constant->type->tag <= TYPE_TAG_SYMBOL) - { - GString *str; - gchar *s; - - str = g_string_new (0); - g_idl_compiler_serialize_type (constant->type, str); - s = g_string_free (str, FALSE); - - fprintf(ctx->mdata_struct, cvalue_struct, - s, - entry_id); - fprintf(ctx->mdata_init, " \"%s\",\n", - constant->value); - g_free(s); - } - else - { - g_warning("Cannot write constant value"); - } - constant = (GIdlNodeConstant *) g_idl_compiler_pop_deferred_constant(ctx, &entry_id); - } -} - -static void -write_deferred_signature_nodes(GIdlCompilerContext *ctx) -{ - GIdlNode *node; - guint entry_id; - - node = g_idl_compiler_pop_deferred_signature_node(ctx, &entry_id); - while (node != NULL) - { - fprintf(ctx->mdata_init, " /*Entry - %d*/\n", - entry_id); - write_signature(node, entry_id, ctx); - node = g_idl_compiler_pop_deferred_signature_node(ctx, &entry_id); - } -} - -void -g_idl_compiler_write_node (GIdlNode * node, - guint entry_id, GIdlCompilerContext * ctx) -{ - GList *l; - - fprintf(ctx->mdata_init, " /*Entry - %d*/\n", - entry_id); - - switch (node->type) - { - case G_IDL_NODE_FUNCTION: - { - write_function (node, entry_id, ctx); - } - break; - - case G_IDL_NODE_CALLBACK: - { - write_callback (node, entry_id, ctx); - } - break; - - case G_IDL_NODE_STRUCT: - { - write_struct (node, entry_id, ctx); - } - break; - - case G_IDL_NODE_BOXED: - { - write_boxed (node, entry_id, ctx); - } - break; - - case G_IDL_NODE_UNION: - { - write_union (node, entry_id, ctx); - } - break; - - case G_IDL_NODE_ENUM: - case G_IDL_NODE_FLAGS: - { - write_enum (node, entry_id, ctx); - } - break; - - case G_IDL_NODE_OBJECT: - { - write_object (node, entry_id, ctx); - } - break; - - case G_IDL_NODE_INTERFACE: - { - write_interface (node, entry_id, ctx); - } - break; - - case G_IDL_NODE_ERROR_DOMAIN: - { - write_error_domain (node, entry_id, ctx); - } - break; - - case G_IDL_NODE_CONSTANT: - { - write_constant (node, entry_id, ctx); - } - break; - default: - g_assert_not_reached (); - } - - write_deferred_constant_values(ctx); - write_deferred_signature_nodes(ctx); - g_idl_compiler_write_deferred_type_blobs(ctx); -} diff --git a/tools/gidlcompilerentrynode.h b/tools/gidlcompilerentrynode.h deleted file mode 100644 index da6ac49d..00000000 --- a/tools/gidlcompilerentrynode.h +++ /dev/null @@ -1,37 +0,0 @@ -/* GObject introspection: Parsed IDL - * - * Copyright (C) 2008 Codethink Ltd - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __G_IDL_COMP_ENTRY_N_H__ -#define __G_IDL_COMP_ENTRY_N_H__ - -#include <glib.h> - -#include "gidlnode.h" -#include "gidlcompilercontext.h" - -G_BEGIN_DECLS - -void -g_idl_compiler_write_node (GIdlNode * node, - guint entry_id, - GIdlCompilerContext * ctx); - -G_END_DECLS -#endif /* __G_IDL_COMP_ENTRY_N_H__ */ diff --git a/tools/gidlcompilertypenode.c b/tools/gidlcompilertypenode.c deleted file mode 100644 index ca4e5574..00000000 --- a/tools/gidlcompilertypenode.c +++ /dev/null @@ -1,430 +0,0 @@ -/* GObject introspection: Type node compilation - * - * Copyright (C) 2005 Matthias Clasen - * Copyright (C) 2008 Codethink Ltd - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "gmetadata.h" - -#include "gidlnode.h" -#include "gidlcompilercontext.h" -#include "gidlcompilertypenode.h" - -/*TYPE BLOB COMPILATION*/ -/*---------------------*/ - -const gchar * -g_idl_compiler_name_basic_type(guint type_tag) -{ - const gchar *basic[] = { - "void", - "gboolean", - "gint8", - "guint8", - "gint16", - "guint16", - "gint32", - "guint32", - "gint64", - "guint64", - "gint", - "guint", - "glong", - "gulong", - "gssize", - "gsize", - "gfloat", - "gdouble", - "utf8", - "filename" - }; - - return basic[type_tag]; -} - -void -g_idl_compiler_serialize_type (GIdlNodeType * node, GString * str) -{ - gint i; - - if (TYPE_IS_SIMPLE(node->tag)) - { - g_string_append_printf (str, "%s%s", - g_idl_compiler_name_basic_type(node->tag), - node->is_pointer ? "*" : ""); - } - else if (node->tag == TYPE_TAG_ARRAY) - { - g_idl_compiler_serialize_type (node->parameter_type1, str); - g_string_append (str, "["); - - if (node->has_length) - g_string_append_printf (str, "length=%d", node->length); - - if (node->zero_terminated) - g_string_append_printf (str, "%szero-terminated=1", - node->has_length ? "," : ""); - - g_string_append (str, "]"); - } - else if (node->tag == TYPE_TAG_SYMBOL) - { - g_string_append_printf (str, "%s%s", node->interface, - node->is_pointer ? "*" : ""); - } - else if (node->tag == TYPE_TAG_LIST) - { - g_string_append (str, "GList"); - if (node->parameter_type1) - { - g_string_append (str, "<"); - g_idl_compiler_serialize_type (node->parameter_type1, str); - g_string_append (str, ">"); - } - } - else if (node->tag == TYPE_TAG_SLIST) - { - g_string_append (str, "GSList"); - if (node->parameter_type1) - { - g_string_append (str, "<"); - g_idl_compiler_serialize_type (node->parameter_type1, str); - g_string_append (str, ">"); - } - } - else if (node->tag == TYPE_TAG_HASH) - { - g_string_append (str, "GHashTable<"); - if (node->parameter_type1) - { - g_string_append (str, "<"); - g_idl_compiler_serialize_type (node->parameter_type1, str); - g_string_append (str, ","); - g_idl_compiler_serialize_type (node->parameter_type2, str); - g_string_append (str, ">"); - } - } - else if (node->tag == TYPE_TAG_ERROR) - { - g_string_append (str, "GError"); - if (node->errors) - { - g_string_append (str, "<"); - for (i = 0; node->errors[i]; i++) - { - if (i > 0) - g_string_append (str, ","); - g_string_append (str, node->errors[i]); - } - g_string_append (str, ">"); - } - } -} - -/* Types below somewhat augment a more basic type that has - * an entry in the direcory. An array type is an array of X. - * A list is a list of X. - */ -static void -type_array_write (GIdlNode * node, - guint type_id, GIdlCompilerContext * ctx) -{ - GIdlNodeType *type = (GIdlNodeType *) node; - - const gchar *array_struct = - " ArrayTypeBlob "ID_TO_ENTRY";\n"; - - const gchar *array_initialiser = - " {\n" - " {%d, 0, %d},\n" - " %d, %d, 0, %d,\n"; - - fprintf(ctx->mdata_struct, array_struct, type_id); - - fprintf(ctx->mdata_init, array_initialiser, - 1, - type->tag, - type->zero_terminated, - type->has_length, - type->length); - - g_idl_compiler_write_simple_type_blob ((GIdlNode*)type->parameter_type1, ctx); - - fprintf(ctx->mdata_init, " },\n\n"); -} - -static void -type_list_write (GIdlNode * node, - guint type_id, - GIdlCompilerContext * ctx) -{ - GIdlNodeType *type = (GIdlNodeType *) node; - guint n_types = 1; - - const gchar *array_struct = - " struct {\n" - " ParamTypeBlob fixed;\n" - " SimpleTypeBlob type[%d];\n" - " } "ID_TO_ENTRY";\n"; - - const gchar *array_initialiser = - " {\n" - " {\n" - " {%d, 0, %d},\n" - " 0, %d,\n" - " },\n"; - - fprintf(ctx->mdata_struct, array_struct, n_types, type_id); - - fprintf(ctx->mdata_init, array_initialiser, - 1, - type->tag, - n_types); - - fprintf(ctx->mdata_init, " {\n"); - if (type->parameter_type1) - { - g_idl_compiler_write_simple_type_blob ((GIdlNode*)type->parameter_type1, ctx); - } - fprintf(ctx->mdata_init, " },\n"); - - fprintf(ctx->mdata_init, " },\n\n"); -} - -static void -type_hash_write (GIdlNode * node, - guint type_id, GIdlCompilerContext * ctx) -{ - GIdlNodeType *type = (GIdlNodeType *) node; - guint n_types = 2; - - const gchar *hash_struct = - " struct {\n" - " ParamTypeBlob fixed;\n" - " SimpleTypeBlob type[%d];\n" - " } "ID_TO_ENTRY";\n"; - - const gchar *hash_initialiser = - " {\n" - " {\n" - " {%d, 0, %d},\n" - " 0, %d,\n" - " },\n"; - - fprintf(ctx->mdata_struct, hash_struct, n_types, type_id); - - fprintf(ctx->mdata_init, hash_initialiser, - 1, - type->tag, - n_types); - - fprintf(ctx->mdata_init, " {\n"); - if (type->parameter_type1) - { - g_idl_compiler_write_simple_type_blob ((GIdlNode*)type->parameter_type1, ctx); - } - if (type->parameter_type2) - { - g_idl_compiler_write_simple_type_blob ((GIdlNode*)type->parameter_type2, ctx); - } - fprintf(ctx->mdata_init, " },\n"); - - fprintf(ctx->mdata_init, " },\n\n"); -} - -static void -type_error_write (GIdlNode * node, - guint type_id, GIdlCompilerContext * ctx) -{ - GIdlNodeType *type = (GIdlNodeType *) node; - guint n_domains = 0; - guint i; - - const gchar *error_struct = - " struct {\n" - " ErrorTypeBlob fixed;\n" - " guint16 domains[%d];\n" - " } "ID_TO_ENTRY";\n"; - - const gchar *error_initialiser = - " {\n" - " {\n" - " {%d, 0, %d},\n" - " %d,\n" - " },\n"; - - const gchar *error_domain_entry = - " %d,\n"; - - if (type->errors) - { - n_domains = g_strv_length(type->errors); - } - - fprintf(ctx->mdata_struct, error_struct, n_domains, type_id); - - fprintf(ctx->mdata_init, error_initialiser, - 1, - type->tag, - n_domains); - - fprintf(ctx->mdata_init, " {\n"); - for (i=0; i < n_domains; i++) - { - fprintf(ctx->mdata_init, error_domain_entry, - g_idl_compiler_get_entry_dirid (ctx, type->errors[i])); - } - fprintf(ctx->mdata_init, " },\n"); - - fprintf(ctx->mdata_init, " },\n\n"); -} - -static void -type_complex_write (GIdlNode * node, - guint type_id, GIdlCompilerContext * ctx) -{ - GIdlNodeType *type = (GIdlNodeType *) node; - - switch (type->tag) - { - case TYPE_TAG_ARRAY: - { - type_array_write (node, type_id, ctx); - } - break; - - case TYPE_TAG_LIST: - case TYPE_TAG_SLIST: - { - type_list_write (node, type_id, ctx); - } - break; - - case TYPE_TAG_HASH: - { - type_hash_write (node, type_id, ctx); - } - break; - - case TYPE_TAG_ERROR: - { - type_error_write (node, type_id, ctx); - } - break; - - default: - g_error ("Unknown type tag %d\n", type->tag); - break; - } -} - -/* This is called at the end of any entries that may have - * added complex type blobs to the type list. - * - * These can only be written out to the metadata at the end of a previous - * entry and so are deffered until the entry is finished. - */ -void -g_idl_compiler_write_deferred_type_blobs (GIdlCompilerContext *ctx) -{ - GIdlNodeType *type; - guint entry_id; - type = (GIdlNodeType *) g_idl_compiler_pop_deferred_type_node (ctx, &entry_id); - - while (type) - { - fprintf(ctx->mdata_init, " /*Entry - %d*/\n", - entry_id); - type_complex_write ((GIdlNode *) type, entry_id, ctx); - type = (GIdlNodeType *) g_idl_compiler_pop_deferred_type_node (ctx, &entry_id); - } -} - -/* - * This function writes out a simple type blob initializer. - * Simple type blobs are only included in other entries. - */ -void -g_idl_compiler_write_simple_type_blob (GIdlNode * node, GIdlCompilerContext * ctx) -{ - GIdlNodeType *type = (GIdlNodeType *) node; - - const gchar *simple_initialiser = - " {\n" - " {%d, 0, %d}, 0\n" - " },\n"; - const gchar *symbol_initialiser = - " {\n" - " {%d, 0, %d}, %d,\n" - " },\n"; - const gchar *complex_initialiser = - " {\n" - " {%d, 0, %d}, "TYPE_POINTER",\n" - " },\n"; - - /* If this is a simple type */ - /* Simple types are not given their own entry - * into the global structure. They are a member of - * another entry. - */ - if (TYPE_IS_SIMPLE(type->tag)) - { - fprintf (ctx->mdata_init, simple_initialiser, - type->is_pointer, type->tag); - } - else if (TYPE_IS_SYMBOL(type->tag)) - { - guint dir_id; - - dir_id = g_idl_compiler_get_entry_dirid(ctx, type->interface); - - fprintf (ctx->mdata_init, symbol_initialiser, - type->is_pointer, type->tag, - dir_id); - } - else - { - gpointer type_id; - GString *str; - gchar *s; - - str = g_string_new (0); - g_idl_compiler_serialize_type (type, str); - s = g_string_free (str, FALSE); - - type_id = g_hash_table_lookup (ctx->typesdb, s); - if (type_id) - { - g_free (s); - } - else - { - type_id = GINT_TO_POINTER (g_idl_compiler_get_unique_id ()); - g_hash_table_insert (ctx->typesdb, s, type_id); - g_idl_compiler_push_deferred_type_node (ctx, node, GPOINTER_TO_INT(type_id)); - } - - fprintf (ctx->mdata_init, complex_initialiser, - type->is_pointer, type->tag, - ctx->struct_name, GPOINTER_TO_INT(type_id)); - } -} diff --git a/tools/gidlcompilertypenode.h b/tools/gidlcompilertypenode.h deleted file mode 100644 index ddc332fa..00000000 --- a/tools/gidlcompilertypenode.h +++ /dev/null @@ -1,44 +0,0 @@ -/* GObject introspection: Parsed IDL - * - * Copyright (C) 2008 Codethink Ltd - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __G_IDL_COMP_TYPE_N_H__ -#define __G_IDL_COMP_TYPE_N_H__ - -#include <glib.h> - -#include "gidlnode.h" -#include "gidlcompilercontext.h" - -G_BEGIN_DECLS - -const gchar * -g_idl_compiler_name_basic_type(guint type_tag); - -void -g_idl_compiler_serialize_type (GIdlNodeType * node, GString * str); - -void -g_idl_compiler_write_deferred_type_blobs (GIdlCompilerContext *ctx); - -void -g_idl_compiler_write_simple_type_blob (GIdlNode * node, GIdlCompilerContext * ctx); - -G_END_DECLS -#endif /* __G_IDL_COMP_TYPE_N_H__ */ diff --git a/tools/gidlmodule.c b/tools/gidlmodule.c index c71569fd..d17a249a 100644 --- a/tools/gidlmodule.c +++ b/tools/gidlmodule.c @@ -1,7 +1,6 @@ /* GObject introspection: Metadata creation * * Copyright (C) 2005 Matthias Clasen - * Copyright (C) 2008 Codethink Ltd * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,11 +24,15 @@ #include "gidlmodule.h" #include "gidlnode.h" +#define ALIGN_VALUE(this, boundary) \ + (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) + + GIdlModule * g_idl_module_new (const gchar *name, const gchar *shared_library) { GIdlModule *module; - + module = g_new (GIdlModule, 1); module->name = g_strdup (name); @@ -56,3 +59,157 @@ g_idl_module_free (GIdlModule *module) g_free (module); } + +GMetadata * +g_idl_module_build_metadata (GIdlModule *module, + GList *modules) +{ + guchar *metadata; + gsize length; + gint i; + GList *e; + Header *header; + DirEntry *entry; + guint32 header_size; + guint32 dir_size; + guint32 n_entries; + guint32 n_local_entries; + guint32 size, offset, offset2, old_offset; + GHashTable *strings; + GHashTable *types; + guchar *data; + + header_size = ALIGN_VALUE (sizeof (Header), 4); + n_local_entries = g_list_length (module->entries); + + restart: + init_stats (); + strings = g_hash_table_new (g_str_hash, g_str_equal); + types = g_hash_table_new (g_str_hash, g_str_equal); + n_entries = g_list_length (module->entries); + + g_message ("%d entries (%d local)\n", n_entries, n_local_entries); + + dir_size = n_entries * 12; + size = header_size + dir_size; + + size += ALIGN_VALUE (strlen (module->name) + 1, 4); + + for (e = module->entries; e; e = e->next) + { + GIdlNode *node = e->data; + + size += g_idl_node_get_full_size (node); + } + + g_message ("allocating %d bytes (%d header, %d directory, %d entries)\n", + size, header_size, dir_size, size - header_size - dir_size); + + data = g_malloc0 (size); + + /* fill in header */ + header = (Header *)data; + memcpy (header, G_IDL_MAGIC, 16); + header->major_version = 1; + header->minor_version = 0; + header->reserved = 0; + header->n_entries = n_entries; + header->n_local_entries = n_local_entries; + header->n_annotations = 0; + header->annotations = 0; /* filled in later */ + header->size = 0; /* filled in later */ + header->namespace = write_string (module->name, strings, data, &header_size); + header->shared_library = (module->shared_library? + write_string (module->shared_library, strings, data, &header_size) + : 0); + header->directory = ALIGN_VALUE (header_size, 4); + header->entry_blob_size = 12; + header->function_blob_size = 16; + header->callback_blob_size = 12; + header->signal_blob_size = 12; + header->vfunc_blob_size = 16; + header->arg_blob_size = 12; + header->property_blob_size = 12; + header->field_blob_size = 12; + header->value_blob_size = 12; + header->constant_blob_size = 20; + header->error_domain_blob_size = 16; + header->annotation_blob_size = 12; + header->signature_blob_size = 8; + header->enum_blob_size = 20; + header->struct_blob_size = 20; + header->object_blob_size = 32; + header->interface_blob_size = 28; + header->union_blob_size = 28; + + /* fill in directory and content */ + entry = (DirEntry *)&data[header->directory]; + + offset2 = header->directory + dir_size; + + for (e = module->entries, i = 0; e; e = e->next, i++) + { + GIdlNode *node = e->data; + + if (strchr (node->name, '.')) + { + g_error ("Names may not contain '.'"); + } + + /* we picked up implicit xref nodes, start over */ + if (i == n_entries) + { + g_message ("Found implicit cross references, starting over"); + + g_hash_table_destroy (strings); + g_hash_table_destroy (types); + strings = NULL; + + g_free (data); + data = NULL; + + goto restart; + } + + offset = offset2; + + if (node->type == G_IDL_NODE_XREF) + { + entry->blob_type = 0; + entry->local = FALSE; + entry->offset = write_string (((GIdlNodeXRef*)node)->namespace, strings, data, &offset2); + entry->name = write_string (node->name, strings, data, &offset2); + } + else + { + old_offset = offset; + offset2 = offset + g_idl_node_get_size (node); + + entry->blob_type = node->type; + entry->local = TRUE; + entry->offset = offset; + entry->name = write_string (node->name, strings, data, &offset2); + + g_idl_node_build_metadata (node, module, modules, + strings, types, data, &offset, &offset2); + + if (offset2 > old_offset + g_idl_node_get_full_size (node)) + g_error ("left a hole of %d bytes\n", offset2 - old_offset - g_idl_node_get_full_size (node)); + } + + entry++; + } + + dump_stats (); + g_hash_table_destroy (strings); + g_hash_table_destroy (types); + + header->annotations = offset2; + + g_message ("reallocating to %d bytes", offset2); + + metadata = g_realloc (data, offset2); + length = header->size = offset2; + return g_metadata_new_from_memory (metadata, length); +} + diff --git a/tools/gidlmodule.h b/tools/gidlmodule.h index f5bb069a..3564a75f 100644 --- a/tools/gidlmodule.h +++ b/tools/gidlmodule.h @@ -40,6 +40,9 @@ GIdlModule *g_idl_module_new (const gchar *name, const gchar *module_filename); void g_idl_module_free (GIdlModule *module); +GMetadata * g_idl_module_build_metadata (GIdlModule *module, + GList *modules); + G_END_DECLS #endif /* __G_IDL_MODULE_H__ */ diff --git a/tools/gidlnode.c b/tools/gidlnode.c index f6e5f435..0e240b2b 100644 --- a/tools/gidlnode.c +++ b/tools/gidlnode.c @@ -26,6 +26,36 @@ #include "gidlnode.h" #include "gmetadata.h" +static gulong string_count = 0; +static gulong unique_string_count = 0; +static gulong string_size = 0; +static gulong unique_string_size = 0; +static gulong types_count = 0; +static gulong unique_types_count = 0; + +void +init_stats (void) +{ + string_count = 0; + unique_string_count = 0; + string_size = 0; + unique_string_size = 0; + types_count = 0; + unique_types_count = 0; +} + +void +dump_stats (void) +{ + g_message ("%lu strings (%lu before sharing), %lu bytes (%lu before sharing)", + unique_string_count, string_count, unique_string_size, string_size); + g_message ("%lu types (%lu before sharing)", unique_types_count, types_count); +} + +#define ALIGN_VALUE(this, boundary) \ + (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1))) + + GIdlNode * g_idl_node_new (GIdlNodeTypeId type) { @@ -320,6 +350,420 @@ g_idl_node_free (GIdlNode *node) g_free (node); } +/* returns the fixed size of the blob */ +guint32 +g_idl_node_get_size (GIdlNode *node) +{ + GList *l; + gint size, n; + + switch (node->type) + { + case G_IDL_NODE_CALLBACK: + size = 12; + break; + + case G_IDL_NODE_FUNCTION: + size = 16; + break; + + case G_IDL_NODE_PARAM: + size = 12; + break; + + case G_IDL_NODE_TYPE: + size = 4; + break; + + case G_IDL_NODE_OBJECT: + { + GIdlNodeInterface *iface = (GIdlNodeInterface *)node; + + n = g_list_length (iface->interfaces); + size = 32 + 2 * (n + (n % 2)); + + for (l = iface->members; l; l = l->next) + size += g_idl_node_get_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_INTERFACE: + { + GIdlNodeInterface *iface = (GIdlNodeInterface *)node; + + n = g_list_length (iface->prerequisites); + size = 28 + 2 * (n + (n % 2)); + + for (l = iface->members; l; l = l->next) + size += g_idl_node_get_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_ENUM: + case G_IDL_NODE_FLAGS: + { + GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node; + + size = 20; + for (l = enum_->values; l; l = l->next) + size += g_idl_node_get_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_VALUE: + size = 12; + break; + + case G_IDL_NODE_STRUCT: + { + GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node; + + size = 20; + for (l = struct_->members; l; l = l->next) + size += g_idl_node_get_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_BOXED: + { + GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node; + + size = 20; + for (l = boxed->members; l; l = l->next) + size += g_idl_node_get_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_PROPERTY: + size = 12; + break; + + case G_IDL_NODE_SIGNAL: + size = 12; + break; + + case G_IDL_NODE_VFUNC: + size = 16; + break; + + case G_IDL_NODE_FIELD: + size = 12; + break; + + case G_IDL_NODE_CONSTANT: + size = 20; + break; + + case G_IDL_NODE_ERROR_DOMAIN: + size = 16; + break; + + case G_IDL_NODE_XREF: + size = 0; + break; + + case G_IDL_NODE_UNION: + { + GIdlNodeUnion *union_ = (GIdlNodeUnion *)node; + + size = 28; + for (l = union_->members; l; l = l->next) + size += g_idl_node_get_size ((GIdlNode *)l->data); + for (l = union_->discriminators; l; l = l->next) + size += g_idl_node_get_size ((GIdlNode *)l->data); + } + break; + + default: + g_error ("Unhandled node type %d\n", node->type); + size = 0; + } + + g_debug ("node %p type %d size %d", node, node->type, size); + + return size; +} + +/* returns the full size of the blob including variable-size parts */ +guint32 +g_idl_node_get_full_size (GIdlNode *node) +{ + GList *l; + gint size, n; + + g_assert (node != NULL); + + switch (node->type) + { + case G_IDL_NODE_CALLBACK: + { + GIdlNodeFunction *function = (GIdlNodeFunction *)node; + size = 12; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + for (l = function->parameters; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + size += g_idl_node_get_full_size ((GIdlNode *)function->result); + } + break; + + case G_IDL_NODE_FUNCTION: + { + GIdlNodeFunction *function = (GIdlNodeFunction *)node; + size = 24; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += ALIGN_VALUE (strlen (function->symbol) + 1, 4); + for (l = function->parameters; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + size += g_idl_node_get_full_size ((GIdlNode *)function->result); + } + break; + + case G_IDL_NODE_PARAM: + { + GIdlNodeParam *param = (GIdlNodeParam *)node; + + size = 12; + if (node->name) + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += g_idl_node_get_full_size ((GIdlNode *)param->type); + } + break; + + case G_IDL_NODE_TYPE: + { + GIdlNodeType *type = (GIdlNodeType *)node; + if (type->tag < TYPE_TAG_ARRAY) + size = 4; + else + { + switch (type->tag) + { + case TYPE_TAG_ARRAY: + size = 4 + 4; + if (type->parameter_type1) + size += g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1); + break; + case TYPE_TAG_INTERFACE: + size = 4 + 4; + break; + case TYPE_TAG_LIST: + case TYPE_TAG_SLIST: + size = 4 + 4; + if (type->parameter_type1) + size += g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1); + break; + case TYPE_TAG_HASH: + size = 4 + 4 + 4; + if (type->parameter_type1) + size += g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1); + if (type->parameter_type2) + size += g_idl_node_get_full_size ((GIdlNode *)type->parameter_type2); + break; + case TYPE_TAG_ERROR: + { + gint n; + + if (type->errors) + n = g_strv_length (type->errors); + else + n = 0; + + size = 4 + 4 + 2 * (n + n % 2); + } + break; + default: + g_error ("Unknown type tag %d\n", type->tag); + break; + } + } + } + break; + + case G_IDL_NODE_OBJECT: + { + GIdlNodeInterface *iface = (GIdlNodeInterface *)node; + + n = g_list_length (iface->interfaces); + size = 32; + if (iface->parent) + size += ALIGN_VALUE (strlen (iface->parent) + 1, 4); + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4); + size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4); + size += 2 * (n + (n % 2)); + + for (l = iface->members; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_INTERFACE: + { + GIdlNodeInterface *iface = (GIdlNodeInterface *)node; + + n = g_list_length (iface->prerequisites); + size = 28; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4); + size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4); + size += 2 * (n + (n % 2)); + + for (l = iface->members; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_ENUM: + case G_IDL_NODE_FLAGS: + { + GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node; + + size = 20; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + if (enum_->gtype_name) + { + size += ALIGN_VALUE (strlen (enum_->gtype_name) + 1, 4); + size += ALIGN_VALUE (strlen (enum_->gtype_init) + 1, 4); + } + + for (l = enum_->values; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_VALUE: + { + size = 12; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + } + break; + + case G_IDL_NODE_STRUCT: + { + GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node; + + size = 20; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + for (l = struct_->members; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_BOXED: + { + GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node; + + size = 20; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + if (boxed->gtype_name) + { + size += ALIGN_VALUE (strlen (boxed->gtype_name) + 1, 4); + size += ALIGN_VALUE (strlen (boxed->gtype_init) + 1, 4); + } + for (l = boxed->members; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + } + break; + + case G_IDL_NODE_PROPERTY: + { + GIdlNodeProperty *prop = (GIdlNodeProperty *)node; + + size = 12; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += g_idl_node_get_full_size ((GIdlNode *)prop->type); + } + break; + + case G_IDL_NODE_SIGNAL: + { + GIdlNodeSignal *signal = (GIdlNodeSignal *)node; + + size = 12; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + for (l = signal->parameters; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + size += g_idl_node_get_full_size ((GIdlNode *)signal->result); + } + break; + + case G_IDL_NODE_VFUNC: + { + GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node; + + size = 16; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + for (l = vfunc->parameters; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + size += g_idl_node_get_full_size ((GIdlNode *)vfunc->result); + } + break; + + case G_IDL_NODE_FIELD: + { + GIdlNodeField *field = (GIdlNodeField *)node; + + size = 12; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += g_idl_node_get_full_size ((GIdlNode *)field->type); + } + break; + + case G_IDL_NODE_CONSTANT: + { + GIdlNodeConstant *constant = (GIdlNodeConstant *)node; + + size = 20; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + /* FIXME non-string values */ + size += ALIGN_VALUE (strlen (constant->value) + 1, 4); + size += g_idl_node_get_full_size ((GIdlNode *)constant->type); + } + break; + + case G_IDL_NODE_ERROR_DOMAIN: + { + GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node; + + size = 16; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += ALIGN_VALUE (strlen (domain->getquark) + 1, 4); + } + break; + + case G_IDL_NODE_XREF: + { + GIdlNodeXRef *xref = (GIdlNodeXRef *)node; + + size = 0; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + size += ALIGN_VALUE (strlen (xref->namespace) + 1, 4); + } + break; + + case G_IDL_NODE_UNION: + { + GIdlNodeUnion *union_ = (GIdlNodeUnion *)node; + + size = 28; + size += ALIGN_VALUE (strlen (node->name) + 1, 4); + for (l = union_->members; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + for (l = union_->discriminators; l; l = l->next) + size += g_idl_node_get_full_size ((GIdlNode *)l->data); + } + break; + + default: + g_error ("Unknown type tag %d\n", node->type); + size = 0; + } + + g_debug ("node %p type %d full size %d", node, node->type, size); + + return size; +} + int g_idl_node_cmp (GIdlNode *node, GIdlNode *other) @@ -519,3 +963,1116 @@ find_entry (GIdlModule *module, return idx; } +static void +serialize_type (GIdlModule *module, + GList *modules, + GIdlNodeType *node, + GString *str) +{ + gint i; + const gchar* basic[] = { + "void", + "gboolean", + "gint8", + "guint8", + "gint16", + "guint16", + "gint32", + "guint32", + "gint64", + "guint64", + "gint", + "guint", + "glong", + "gulong", + "gssize", + "gsize", + "gfloat", + "gdouble", + "utf8", + "filename" + }; + + if (node->tag < 20) + { + g_string_append_printf (str, "%s%s", + basic[node->tag], node->is_pointer ? "*" : ""); + } + else if (node->tag == 20) + { + serialize_type (module, modules, node->parameter_type1, str); + g_string_append (str, "["); + + if (node->has_length) + g_string_append_printf (str, "length=%d", node->length); + + if (node->zero_terminated) + g_string_append_printf (str, "%szero-terminated=1", + node->has_length ? "," : ""); + + g_string_append (str, "]"); + } + else if (node->tag == 21) + { + GIdlNode *iface; + gchar *name; + + iface = find_entry_node (module, modules, node->interface, NULL); + if (iface) + name = iface->name; + else + { + g_warning ("Interface for type reference %s not found", node->interface); + name = node->interface; + } + + g_string_append_printf (str, "%s%s", name, node->is_pointer ? "*" : ""); + } + else if (node->tag == 22) + { + g_string_append (str, "GList"); + if (node->parameter_type1) + { + g_string_append (str, "<"); + serialize_type (module, modules, node->parameter_type1, str); + g_string_append (str, ">"); + } + } + else if (node->tag == 23) + { + g_string_append (str, "GSList"); + if (node->parameter_type1) + { + g_string_append (str, "<"); + serialize_type (module, modules, node->parameter_type1, str); + g_string_append (str, ">"); + } + } + else if (node->tag == 24) + { + g_string_append (str, "GHashTable<"); + if (node->parameter_type1) + { + g_string_append (str, "<"); + serialize_type (module, modules, node->parameter_type1, str); + g_string_append (str, ","); + serialize_type (module, modules, node->parameter_type2, str); + g_string_append (str, ">"); + } + } + else if (node->tag == 25) + { + g_string_append (str, "GError"); + if (node->errors) + { + g_string_append (str, "<"); + for (i = 0; node->errors[i]; i++) + { + if (i > 0) + g_string_append (str, ","); + g_string_append (str, node->errors[i]); + } + g_string_append (str, ">"); + } + } +} + +void +g_idl_node_build_metadata (GIdlNode *node, + GIdlModule *module, + GList *modules, + GHashTable *strings, + GHashTable *types, + guchar *data, + guint32 *offset, + guint32 *offset2) +{ + GList *l; + guint32 old_offset = *offset; + guint32 old_offset2 = *offset2; + + switch (node->type) + { + case G_IDL_NODE_TYPE: + { + GIdlNodeType *type = (GIdlNodeType *)node; + SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset]; + + *offset += 4; + + if (type->tag < TYPE_TAG_ARRAY) + { + blob->reserved = 0; + blob->reserved2 = 0; + blob->pointer = type->is_pointer; + blob->reserved3 = 0; + blob->tag = type->tag; + } + else + { + GString *str; + gchar *s; + gpointer value; + + str = g_string_new (0); + serialize_type (module, modules, type, str); + s = g_string_free (str, FALSE); + + types_count += 1; + value = g_hash_table_lookup (types, s); + if (value) + { + blob->offset = GPOINTER_TO_INT (value); + g_free (s); + } + else + { + unique_types_count += 1; + g_hash_table_insert (types, s, GINT_TO_POINTER(*offset2)); + + blob->offset = *offset2; + switch (type->tag) + { + case TYPE_TAG_ARRAY: + { + ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2]; + guint32 pos; + + array->pointer = 1; + array->reserved = 0; + array->tag = type->tag; + array->zero_terminated = type->zero_terminated; + array->has_length = type->has_length; + array->reserved2 = 0; + array->length = type->length; + + pos = *offset2 + 4; + *offset2 += 8; + + g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1, + module, modules, strings, types, + data, &pos, offset2); + } + break; + + case TYPE_TAG_INTERFACE: + { + InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2]; + *offset2 += 4; + + iface->pointer = type->is_pointer; + iface->reserved = 0; + iface->tag = type->tag; + iface->reserved2 = 0; + iface->interface = find_entry (module, modules, type->interface); + + } + break; + + case TYPE_TAG_LIST: + case TYPE_TAG_SLIST: + { + ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2]; + guint32 pos; + + param->pointer = 1; + param->reserved = 0; + param->tag = type->tag; + param->reserved2 = 0; + param->n_types = 1; + + pos = *offset2 + 4; + *offset2 += 8; + + g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1, + module, modules, strings, types, + data, &pos, offset2); + } + break; + + case TYPE_TAG_HASH: + { + ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2]; + guint32 pos; + + param->pointer = 1; + param->reserved = 0; + param->tag = type->tag; + param->reserved2 = 0; + param->n_types = 2; + + pos = *offset2 + 4; + *offset2 += 12; + + g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1, + module, modules, strings, types, + data, &pos, offset2); + g_idl_node_build_metadata ((GIdlNode *)type->parameter_type2, + module, modules, strings, types, + data, &pos, offset2); + } + break; + + case TYPE_TAG_ERROR: + { + ErrorTypeBlob *blob = (ErrorTypeBlob *)&data[*offset2]; + gint i; + + blob->pointer = 1; + blob->reserved = 0; + blob->tag = type->tag; + blob->reserved2 = 0; + if (type->errors) + blob->n_domains = g_strv_length (type->errors); + else + blob->n_domains = 0; + + *offset2 = ALIGN_VALUE (*offset2 + 4 + 2 * blob->n_domains, 4); + for (i = 0; i < blob->n_domains; i++) + blob->domains[i] = find_entry (module, modules, type->errors[i]); + } + break; + + default: + g_error ("Unknown type tag %d\n", type->tag); + break; + } + } + } + } + break; + + case G_IDL_NODE_FIELD: + { + GIdlNodeField *field = (GIdlNodeField *)node; + FieldBlob *blob; + + blob = (FieldBlob *)&data[*offset]; + *offset += 8; + + blob->name = write_string (node->name, strings, data, offset2); + blob->readable = field->readable; + blob->writable = field->writable; + blob->reserved = 0; + blob->bits = 0; + blob->struct_offset = field->offset; + + g_idl_node_build_metadata ((GIdlNode *)field->type, + module, modules, strings, types, + data, offset, offset2); + } + break; + + case G_IDL_NODE_PROPERTY: + { + GIdlNodeProperty *prop = (GIdlNodeProperty *)node; + PropertyBlob *blob = (PropertyBlob *)&data[*offset]; + *offset += 8; + + blob->name = write_string (node->name, strings, data, offset2); + blob->deprecated = prop->deprecated; + blob->readable = prop->readable; + blob->writable = prop->writable; + blob->construct = prop->construct; + blob->construct_only = prop->construct_only; + blob->reserved = 0; + + g_idl_node_build_metadata ((GIdlNode *)prop->type, + module, modules, strings, types, + data, offset, offset2); + } + break; + + case G_IDL_NODE_FUNCTION: + { + FunctionBlob *blob = (FunctionBlob *)&data[*offset]; + SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2]; + GIdlNodeFunction *function = (GIdlNodeFunction *)node; + guint32 signature; + gint n; + + signature = *offset2; + n = g_list_length (function->parameters); + + *offset += 16; + *offset2 += 8 + n * 12; + + blob->blob_type = BLOB_TYPE_FUNCTION; + blob->deprecated = function->deprecated; + blob->setter = function->is_setter; + blob->getter = function->is_getter; + blob->constructor = function->is_constructor; + blob->wraps_vfunc = function->wraps_vfunc; + blob->reserved = 0; + blob->index = 0; + blob->name = write_string (node->name, strings, data, offset2); + blob->symbol = write_string (function->symbol, strings, data, offset2); + blob->signature = signature; + + g_idl_node_build_metadata ((GIdlNode *)function->result->type, + module, modules, strings, types, + data, &signature, offset2); + + blob2->may_return_null = function->result->null_ok; + blob2->caller_owns_return_value = function->result->transfer; + blob2->caller_owns_return_container = function->result->shallow_transfer; + blob2->reserved = 0; + blob2->n_arguments = n; + + signature += 4; + + for (l = function->parameters; l; l = l->next) + { + GIdlNode *param = (GIdlNode *)l->data; + + g_idl_node_build_metadata (param, + module, modules, strings, types, + data, &signature, offset2); + } + } + break; + + case G_IDL_NODE_CALLBACK: + { + CallbackBlob *blob = (CallbackBlob *)&data[*offset]; + SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2]; + GIdlNodeFunction *function = (GIdlNodeFunction *)node; + guint32 signature; + gint n; + + signature = *offset2; + n = g_list_length (function->parameters); + + *offset += 12; + *offset2 += 8 + n * 12; + + blob->blob_type = BLOB_TYPE_CALLBACK; + blob->deprecated = function->deprecated; + blob->reserved = 0; + blob->name = write_string (node->name, strings, data, offset2); + blob->signature = signature; + + g_idl_node_build_metadata ((GIdlNode *)function->result->type, + module, modules, strings, types, + data, &signature, offset2); + + blob2->may_return_null = function->result->null_ok; + blob2->caller_owns_return_value = function->result->transfer; + blob2->caller_owns_return_container = function->result->shallow_transfer; + blob2->reserved = 0; + blob2->n_arguments = n; + + signature += 4; + + for (l = function->parameters; l; l = l->next) + { + GIdlNode *param = (GIdlNode *)l->data; + + g_idl_node_build_metadata (param, + module, modules, strings, types, + data, &signature, offset2); + } + } + break; + + case G_IDL_NODE_SIGNAL: + { + SignalBlob *blob = (SignalBlob *)&data[*offset]; + SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2]; + GIdlNodeSignal *signal = (GIdlNodeSignal *)node; + guint32 signature; + gint n; + + signature = *offset2; + n = g_list_length (signal->parameters); + + *offset += 12; + *offset2 += 8 + n * 12; + + blob->deprecated = signal->deprecated; + blob->run_first = signal->run_first; + blob->run_last = signal->run_last; + blob->run_cleanup = signal->run_cleanup; + blob->no_recurse = signal->no_recurse; + blob->detailed = signal->detailed; + blob->action = signal->action; + blob->no_hooks = signal->no_hooks; + blob->has_class_closure = 0; /* FIXME */ + blob->true_stops_emit = 0; /* FIXME */ + blob->reserved = 0; + blob->class_closure = 0; /* FIXME */ + blob->name = write_string (node->name, strings, data, offset2); + blob->signature = signature; + + g_idl_node_build_metadata ((GIdlNode *)signal->result->type, + module, modules, strings, types, + data, &signature, offset2); + + blob2->may_return_null = signal->result->null_ok; + blob2->caller_owns_return_value = signal->result->transfer; + blob2->caller_owns_return_container = signal->result->shallow_transfer; + blob2->reserved = 0; + blob2->n_arguments = n; + + signature += 4; + + for (l = signal->parameters; l; l = l->next) + { + GIdlNode *param = (GIdlNode *)l->data; + + g_idl_node_build_metadata (param, module, modules, strings, types, + data, &signature, offset2); + } + } + break; + + case G_IDL_NODE_VFUNC: + { + VFuncBlob *blob = (VFuncBlob *)&data[*offset]; + SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2]; + GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node; + guint32 signature; + gint n; + + signature = *offset2; + n = g_list_length (vfunc->parameters); + + *offset += 16; + *offset2 += 8 + n * 12; + + blob->name = write_string (node->name, strings, data, offset2); + blob->must_chain_up = 0; /* FIXME */ + blob->must_be_implemented = 0; /* FIXME */ + blob->must_not_be_implemented = 0; /* FIXME */ + blob->class_closure = 0; /* FIXME */ + blob->reserved = 0; + + blob->struct_offset = vfunc->offset; + blob->reserved2 = 0; + blob->signature = signature; + + g_idl_node_build_metadata ((GIdlNode *)vfunc->result->type, + module, modules, strings, types, + data, &signature, offset2); + + blob2->may_return_null = vfunc->result->null_ok; + blob2->caller_owns_return_value = vfunc->result->transfer; + blob2->caller_owns_return_container = vfunc->result->shallow_transfer; + blob2->reserved = 0; + blob2->n_arguments = n; + + signature += 4; + + for (l = vfunc->parameters; l; l = l->next) + { + GIdlNode *param = (GIdlNode *)l->data; + + g_idl_node_build_metadata (param, module, modules, strings, + types, data, &signature, offset2); + } + } + break; + + case G_IDL_NODE_PARAM: + { + ArgBlob *blob = (ArgBlob *)&data[*offset]; + GIdlNodeParam *param = (GIdlNodeParam *)node; + + *offset += 8; + + blob->name = write_string (node->name, strings, data, offset2); + blob->in = param->in; + blob->out = param->out; + blob->dipper = param->dipper; + blob->null_ok = param->null_ok; + blob->optional = param->optional; + blob->transfer_ownership = param->transfer; + blob->transfer_container_ownership = param->shallow_transfer; + blob->return_value = param->retval; + blob->reserved = 0; + + g_idl_node_build_metadata ((GIdlNode *)param->type, module, modules, + strings, types, data, offset, offset2); + } + break; + + case G_IDL_NODE_STRUCT: + { + StructBlob *blob = (StructBlob *)&data[*offset]; + GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node; + + blob->blob_type = BLOB_TYPE_STRUCT; + blob->deprecated = struct_->deprecated; + blob->unregistered = TRUE; + blob->reserved = 0; + blob->name = write_string (node->name, strings, data, offset2); + blob->gtype_name = 0; + blob->gtype_init = 0; + + blob->n_fields = 0; + blob->n_methods = 0; + + *offset += 20; + for (l = struct_->members; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + if (member->type == G_IDL_NODE_FIELD) + { + blob->n_fields++; + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + for (l = struct_->members; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + if (member->type == G_IDL_NODE_FUNCTION) + { + blob->n_methods++; + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + } + break; + + case G_IDL_NODE_BOXED: + { + StructBlob *blob = (StructBlob *)&data[*offset]; + GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node; + + blob->blob_type = BLOB_TYPE_BOXED; + blob->deprecated = boxed->deprecated; + blob->unregistered = FALSE; + blob->reserved = 0; + blob->name = write_string (node->name, strings, data, offset2); + blob->gtype_name = write_string (boxed->gtype_name, strings, data, offset2); + blob->gtype_init = write_string (boxed->gtype_init, strings, data, offset2); + + blob->n_fields = 0; + blob->n_methods = 0; + + *offset += 20; + for (l = boxed->members; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + if (member->type == G_IDL_NODE_FIELD) + { + blob->n_fields++; + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + for (l = boxed->members; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + if (member->type == G_IDL_NODE_FUNCTION) + { + blob->n_methods++; + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + } + break; + + case G_IDL_NODE_UNION: + { + UnionBlob *blob = (UnionBlob *)&data[*offset]; + GIdlNodeUnion *union_ = (GIdlNodeUnion *)node; + + blob->blob_type = BLOB_TYPE_UNION; + blob->deprecated = union_->deprecated; + blob->reserved = 0; + blob->name = write_string (node->name, strings, data, offset2); + if (union_->gtype_name) + { + blob->unregistered = FALSE; + blob->gtype_name = write_string (union_->gtype_name, strings, data, offset2); + blob->gtype_init = write_string (union_->gtype_init, strings, data, offset2); + } + else + { + blob->unregistered = TRUE; + blob->gtype_name = 0; + blob->gtype_init = 0; + } + + blob->n_fields = 0; + blob->n_functions = 0; + + blob->discriminator_offset = union_->discriminator_offset; + + if (union_->discriminator_type) + { + *offset += 24; + blob->discriminated = TRUE; + g_idl_node_build_metadata ((GIdlNode *)union_->discriminator_type, + module, modules, strings, types, + data, offset, offset2); + } + else + { + *offset += 28; + blob->discriminated = FALSE; + blob->discriminator_type.offset = 0; + } + + + for (l = union_->members; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + if (member->type == G_IDL_NODE_FIELD) + { + blob->n_fields++; + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + for (l = union_->members; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + if (member->type == G_IDL_NODE_FUNCTION) + { + blob->n_functions++; + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + if (union_->discriminator_type) + { + for (l = union_->discriminators; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + } + break; + + case G_IDL_NODE_ENUM: + case G_IDL_NODE_FLAGS: + { + EnumBlob *blob = (EnumBlob *)&data[*offset]; + GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node; + + *offset += 20; + + if (node->type == G_IDL_NODE_ENUM) + blob->blob_type = BLOB_TYPE_ENUM; + else + blob->blob_type = BLOB_TYPE_FLAGS; + + blob->deprecated = enum_->deprecated; + blob->reserved = 0; + blob->name = write_string (node->name, strings, data, offset2); + if (enum_->gtype_name) + { + blob->unregistered = FALSE; + blob->gtype_name = write_string (enum_->gtype_name, strings, data, offset2); + blob->gtype_init = write_string (enum_->gtype_init, strings, data, offset2); + } + else + { + blob->unregistered = TRUE; + blob->gtype_name = 0; + blob->gtype_init = 0; + } + + blob->n_values = 0; + blob->reserved2 = 0; + + for (l = enum_->values; l; l = l->next) + { + GIdlNode *value = (GIdlNode *)l->data; + + blob->n_values++; + g_idl_node_build_metadata (value, module, modules, strings, types, + data, offset, offset2); + } + } + break; + + case G_IDL_NODE_OBJECT: + { + ObjectBlob *blob = (ObjectBlob *)&data[*offset]; + GIdlNodeInterface *object = (GIdlNodeInterface *)node; + + blob->blob_type = BLOB_TYPE_OBJECT; + blob->deprecated = object->deprecated; + blob->reserved = 0; + blob->name = write_string (node->name, strings, data, offset2); + blob->gtype_name = write_string (object->gtype_name, strings, data, offset2); + blob->gtype_init = write_string (object->gtype_init, strings, data, offset2); + if (object->parent) + blob->parent = find_entry (module, modules, object->parent); + else + blob->parent = 0; + + blob->n_interfaces = 0; + blob->n_fields = 0; + blob->n_properties = 0; + blob->n_methods = 0; + blob->n_signals = 0; + blob->n_vfuncs = 0; + blob->n_constants = 0; + + *offset += 32; + for (l = object->interfaces; l; l = l->next) + { + blob->n_interfaces++; + *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data); + *offset += 2; + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = object->members; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + if (member->type == G_IDL_NODE_FIELD) + { + blob->n_fields++; + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = object->members; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + if (member->type == G_IDL_NODE_PROPERTY) + { + blob->n_properties++; + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = object->members; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + if (member->type == G_IDL_NODE_FUNCTION) + { + blob->n_methods++; + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = object->members; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + if (member->type == G_IDL_NODE_SIGNAL) + { + blob->n_signals++; + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = object->members; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + if (member->type == G_IDL_NODE_VFUNC) + { + blob->n_vfuncs++; + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = object->members; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + if (member->type == G_IDL_NODE_CONSTANT) + { + blob->n_constants++; + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + } + break; + + case G_IDL_NODE_INTERFACE: + { + InterfaceBlob *blob = (InterfaceBlob *)&data[*offset]; + GIdlNodeInterface *iface = (GIdlNodeInterface *)node; + + blob->blob_type = BLOB_TYPE_INTERFACE; + blob->deprecated = iface->deprecated; + blob->reserved = 0; + blob->name = write_string (node->name, strings, data, offset2); + blob->gtype_name = write_string (iface->gtype_name, strings, data, offset2); + blob->gtype_init = write_string (iface->gtype_init, strings, data, offset2); + blob->n_prerequisites = 0; + blob->n_properties = 0; + blob->n_methods = 0; + blob->n_signals = 0; + blob->n_vfuncs = 0; + blob->n_constants = 0; + + *offset += 28; + for (l = iface->prerequisites; l; l = l->next) + { + blob->n_prerequisites++; + *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data); + *offset += 2; + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = iface->members; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + if (member->type == G_IDL_NODE_PROPERTY) + { + blob->n_properties++; + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = iface->members; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + if (member->type == G_IDL_NODE_FUNCTION) + { + blob->n_methods++; + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = iface->members; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + if (member->type == G_IDL_NODE_SIGNAL) + { + blob->n_signals++; + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = iface->members; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + if (member->type == G_IDL_NODE_VFUNC) + { + blob->n_vfuncs++; + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + + *offset = ALIGN_VALUE (*offset, 4); + for (l = iface->members; l; l = l->next) + { + GIdlNode *member = (GIdlNode *)l->data; + + if (member->type == G_IDL_NODE_CONSTANT) + { + blob->n_constants++; + g_idl_node_build_metadata (member, module, modules, strings, + types, data, offset, offset2); + } + } + } + break; + + + case G_IDL_NODE_VALUE: + { + GIdlNodeValue *value = (GIdlNodeValue *)node; + ValueBlob *blob = (ValueBlob *)&data[*offset]; + *offset += 12; + + blob->deprecated = value->deprecated; + blob->reserved = 0; + blob->name = write_string (node->name, strings, data, offset2); + blob->value = value->value; + } + break; + + case G_IDL_NODE_ERROR_DOMAIN: + { + GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node; + ErrorDomainBlob *blob = (ErrorDomainBlob *)&data[*offset]; + *offset += 16; + + blob->blob_type = BLOB_TYPE_ERROR_DOMAIN; + blob->deprecated = domain->deprecated; + blob->reserved = 0; + blob->name = write_string (node->name, strings, data, offset2); + blob->get_quark = write_string (domain->getquark, strings, data, offset2); + blob->error_codes = find_entry (module, modules, domain->codes); + blob->reserved2 = 0; + } + break; + + case G_IDL_NODE_CONSTANT: + { + GIdlNodeConstant *constant = (GIdlNodeConstant *)node; + ConstantBlob *blob = (ConstantBlob *)&data[*offset]; + guint32 pos; + + pos = *offset + 8; + *offset += 20; + + blob->blob_type = BLOB_TYPE_CONSTANT; + blob->deprecated = constant->deprecated; + blob->reserved = 0; + blob->name = write_string (node->name, strings, data, offset2); + + blob->offset = *offset2; + switch (constant->type->tag) + { + case TYPE_TAG_BOOLEAN: + blob->size = 4; + *(gboolean*)&data[blob->offset] = parse_boolean_value (constant->value); + break; + case TYPE_TAG_INT8: + blob->size = 1; + *(gint8*)&data[blob->offset] = (gint8) parse_int_value (constant->value); + break; + case TYPE_TAG_UINT8: + blob->size = 1; + *(guint8*)&data[blob->offset] = (guint8) parse_uint_value (constant->value); + break; + case TYPE_TAG_INT16: + blob->size = 2; + *(gint16*)&data[blob->offset] = (gint16) parse_int_value (constant->value); + break; + case TYPE_TAG_UINT16: + blob->size = 2; + *(guint16*)&data[blob->offset] = (guint16) parse_uint_value (constant->value); + break; + case TYPE_TAG_INT32: + blob->size = 4; + *(gint32*)&data[blob->offset] = (gint32) parse_int_value (constant->value); + break; + case TYPE_TAG_UINT32: + blob->size = 4; + *(guint32*)&data[blob->offset] = (guint32) parse_uint_value (constant->value); + break; + case TYPE_TAG_INT64: + blob->size = 8; + *(gint64*)&data[blob->offset] = (gint64) parse_int_value (constant->value); + break; + case TYPE_TAG_UINT64: + blob->size = 8; + *(guint64*)&data[blob->offset] = (guint64) parse_uint_value (constant->value); + break; + case TYPE_TAG_INT: + blob->size = sizeof (gint); + *(gint*)&data[blob->offset] = (gint) parse_int_value (constant->value); + break; + case TYPE_TAG_UINT: + blob->size = sizeof (guint); + *(gint*)&data[blob->offset] = (guint) parse_uint_value (constant->value); + break; + case TYPE_TAG_SSIZE: /* FIXME */ + case TYPE_TAG_LONG: + blob->size = sizeof (glong); + *(glong*)&data[blob->offset] = (glong) parse_int_value (constant->value); + break; + case TYPE_TAG_SIZE: /* FIXME */ + case TYPE_TAG_ULONG: + blob->size = sizeof (gulong); + *(gulong*)&data[blob->offset] = (gulong) parse_uint_value (constant->value); + break; + case TYPE_TAG_FLOAT: + blob->size = sizeof (gfloat); + *(gfloat*)&data[blob->offset] = (gfloat) parse_float_value (constant->value); + break; + case TYPE_TAG_DOUBLE: + blob->size = sizeof (gdouble); + *(gdouble*)&data[blob->offset] = (gdouble) parse_float_value (constant->value); + break; + case TYPE_TAG_UTF8: + case TYPE_TAG_FILENAME: + blob->size = strlen (constant->value) + 1; + memcpy (&data[blob->offset], constant->value, blob->size); + break; + } + *offset2 += ALIGN_VALUE (blob->size, 4); + + g_idl_node_build_metadata ((GIdlNode *)constant->type, module, modules, + strings, types, data, &pos, offset2); + } + break; + default: + g_assert_not_reached (); + } + + g_debug ("node %p type %d, offset %d -> %d, offset2 %d -> %d", + node, node->type, old_offset, *offset, old_offset2, *offset2); + + if (*offset2 - old_offset2 + *offset - old_offset > g_idl_node_get_full_size (node)) + g_error ("exceeding space reservation !!"); +} + +/* if str is already in the pool, return previous location, otherwise write str + * to the metadata at offset, put it in the pool and update offset. If the + * metadata is not large enough to hold the string, reallocate it. + */ +guint32 +write_string (const gchar *str, + GHashTable *strings, + guchar *data, + guint32 *offset) +{ + gpointer value; + guint32 start; + + string_count += 1; + string_size += strlen (str); + + value = g_hash_table_lookup (strings, str); + + if (value) + return GPOINTER_TO_INT (value); + + unique_string_count += 1; + unique_string_size += strlen (str); + + g_hash_table_insert (strings, (gpointer)str, GINT_TO_POINTER (*offset)); + + start = *offset; + *offset = ALIGN_VALUE (start + strlen (str) + 1, 4); + + strcpy ((gchar*)&data[start], str); + + return start; +} + diff --git a/tools/gidlnode.h b/tools/gidlnode.h index 3fd48901..32a9a939 100644 --- a/tools/gidlnode.h +++ b/tools/gidlnode.h @@ -307,12 +307,25 @@ struct _GIdlNodeErrorDomain GIdlNode *g_idl_node_new (GIdlNodeTypeId type); void g_idl_node_free (GIdlNode *node); - +guint32 g_idl_node_get_size (GIdlNode *node); +guint32 g_idl_node_get_full_size (GIdlNode *node); +void g_idl_node_build_metadata (GIdlNode *node, + GIdlModule *module, + GList *modules, + GHashTable *strings, + GHashTable *types, + guchar *data, + guint32 *offset, + guint32 *offset2); int g_idl_node_cmp (GIdlNode *node, GIdlNode *other); gboolean g_idl_node_can_have_member (GIdlNode *node); void g_idl_node_add_member (GIdlNode *node, GIdlNodeFunction *member); +guint32 write_string (const gchar *str, + GHashTable *strings, + guchar *data, + guint32 *offset); const gchar * g_idl_node_param_direction_string (GIdlNodeParam * node); diff --git a/tools/gidlparser.c b/tools/gidlparser.c index deede3c1..6a76b2ca 100644 --- a/tools/gidlparser.c +++ b/tools/gidlparser.c @@ -268,7 +268,7 @@ parse_type_internal (gchar *str, gchar **rest) } else { - type->tag = TYPE_TAG_SYMBOL; + type->tag = TYPE_TAG_INTERFACE; type->is_interface = TRUE; start = *rest; diff --git a/tools/quote-file.sh b/tools/quote-file.sh deleted file mode 100755 index e720c281..00000000 --- a/tools/quote-file.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -cat $1 | sed -e '1 i\const char gmetadata_header[] =\n' -e 's/\\/\\\\/g' -e 's/\"/\\\"/g' -e 's/.*/\"&\\n\"/' -e '$ a\;' > $2 |