[gobject-introspection/ebassi/split-disguised: 2/2] Use the pointer attribute in libgirepository




commit cf7cdfe366aeb4e9f4d7a50eb3ada4368decda4a
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Wed Jul 13 13:26:44 2022 +0100

    Use the pointer attribute in libgirepository
    
    The "disguised" attribute is there only for backward compatibility; we
    use the "pointer" attribute as the authoritative way to indicate a
    typedef to a struct pointer.

 girepository/girmodule.c | 14 ++++++++++
 girepository/girmodule.h |  9 +++++--
 girepository/girnode.h   |  2 ++
 girepository/girparser.c | 68 +++++++++++++++++++++++++++++++++++++++++-------
 4 files changed, 82 insertions(+), 11 deletions(-)
---
diff --git a/girepository/girmodule.c b/girepository/girmodule.c
index 66b33fa1..943db971 100644
--- a/girepository/girmodule.c
+++ b/girepository/girmodule.c
@@ -74,6 +74,7 @@ _g_ir_module_free (GIrModule *module)
   g_list_free (module->include_modules);
 
   g_hash_table_destroy (module->aliases);
+  g_hash_table_destroy (module->pointer_structures);
   g_hash_table_destroy (module->disguised_structures);
 
   g_slice_free (GIrModule, module);
@@ -141,6 +142,16 @@ add_alias_foreach (gpointer key,
   g_hash_table_replace (module->aliases, g_strdup (key), g_strdup (value));
 }
 
+static void
+add_pointer_structure_foreach (gpointer key,
+                               gpointer value,
+                               gpointer data)
+{
+  GIrModule *module = data;
+
+  g_hash_table_replace (module->pointer_structures, g_strdup (key), value);
+}
+
 static void
 add_disguised_structure_foreach (gpointer key,
                                 gpointer value,
@@ -162,6 +173,9 @@ _g_ir_module_add_include_module (GIrModule  *module,
                        add_alias_foreach,
                        module);
 
+  g_hash_table_foreach (include_module->pointer_structures,
+                       add_pointer_structure_foreach,
+                       module);
   g_hash_table_foreach (include_module->disguised_structures,
                        add_disguised_structure_foreach,
                        module);
diff --git a/girepository/girmodule.h b/girepository/girmodule.h
index 7837f2cf..fca7ebbf 100644
--- a/girepository/girmodule.h
+++ b/girepository/girmodule.h
@@ -55,8 +55,13 @@ struct _GIrModule
   /* Aliases defined in the module or in included modules */
   GHashTable *aliases;
 
-  /* Structures with the 'disguised' flag (typedef struct _X *X)
-  * in the module or in included modules */
+  /* Structures with the 'pointer' flag (typedef struct _X *X)
+   * in the module or in included modules
+   */
+  GHashTable *pointer_structures;
+  /* Same as 'pointer' structures, but with the deprecated
+   * 'disguised' flag
+   */
   GHashTable *disguised_structures;
 };
 
diff --git a/girepository/girnode.h b/girepository/girnode.h
index 7b8c97f6..2017d069 100644
--- a/girepository/girnode.h
+++ b/girepository/girnode.h
@@ -322,6 +322,8 @@ struct _GIrNodeStruct
 
   gboolean deprecated;
   gboolean disguised;
+  gboolean opaque;
+  gboolean pointer;
   gboolean is_gtype_struct;
   gboolean foreign;
 
diff --git a/girepository/girparser.c b/girepository/girparser.c
index e5878b43..73d82d27 100644
--- a/girepository/girparser.c
+++ b/girepository/girparser.c
@@ -114,6 +114,7 @@ struct _ParseContext
   GList *dependencies;
   GHashTable *aliases;
   GHashTable *disguised_structures;
+  GHashTable *pointer_structures;
 
   const char *file_path;
   const char *namespace;
@@ -235,11 +236,20 @@ firstpass_start_element_handler (GMarkupParseContext *context,
     {
       const gchar *name;
       const gchar *disguised;
+      const gchar *pointer;
 
       name = find_attribute ("name", attribute_names, attribute_values);
       disguised = find_attribute ("disguised", attribute_names, attribute_values);
+      pointer = find_attribute ("pointer", attribute_names, attribute_values);
 
-      if (disguised && strcmp (disguised, "1") == 0)
+      if (g_strcmp0 (pointer, "1") == 0)
+        {
+          char *key;
+
+          key = g_strdup_printf ("%s.%s", ctx->namespace, name);
+         g_hash_table_replace (ctx->pointer_structures, key, GINT_TO_POINTER (1));
+        }
+      else if (g_strcmp0 (disguised, "1") == 0)
        {
          char *key;
 
@@ -658,6 +668,32 @@ resolve_aliases (ParseContext *ctx, const gchar *type)
   return lookup;
 }
 
+static gboolean
+is_pointer_structure (ParseContext *ctx, const gchar *type)
+{
+  const gchar *lookup;
+  gchar *prefixed;
+  gboolean result;
+
+  if (strchr (type, '.') == NULL)
+    {
+      prefixed = g_strdup_printf ("%s.%s", ctx->namespace, type);
+      lookup = prefixed;
+    }
+  else
+    {
+      lookup = type;
+      prefixed = NULL;
+    }
+
+  result = g_hash_table_lookup (ctx->current_module->pointer_structures,
+                               lookup) != NULL;
+
+  g_free (prefixed);
+
+  return result;
+}
+
 static gboolean
 is_disguised_structure (ParseContext *ctx, const gchar *type)
 {
@@ -2094,11 +2130,13 @@ start_type (GMarkupParseContext *context,
 
       typenode = parse_type (ctx, name);
 
-      /* A 'disguised' structure is one where the c:type is a typedef that
-       * doesn't look like a pointer, but is internally.
+      /* A "pointer" structure is one where the c:type is a typedef that
+       * to a pointer to a structure; we used to call them "disguised"
+       * structures as well.
        */
       if (typenode->tag == GI_TYPE_TAG_INTERFACE &&
-         is_disguised_structure (ctx, typenode->giinterface))
+          (is_pointer_structure (ctx, typenode->giinterface) ||
+          is_disguised_structure (ctx, typenode->giinterface)))
        pointer_depth++;
 
       if (pointer_depth > 0)
@@ -2556,6 +2594,8 @@ start_struct (GMarkupParseContext *context,
   const gchar *name;
   const gchar *deprecated;
   const gchar *disguised;
+  const gchar *opaque;
+  const gchar *pointer;
   const gchar *gtype_name;
   const gchar *gtype_init;
   const gchar *gtype_struct;
@@ -2575,6 +2615,8 @@ start_struct (GMarkupParseContext *context,
   name = find_attribute ("name", attribute_names, attribute_values);
   deprecated = find_attribute ("deprecated", attribute_names, attribute_values);
   disguised = find_attribute ("disguised", attribute_names, attribute_values);
+  pointer = find_attribute ("pointer", attribute_names, attribute_values);
+  opaque = find_attribute ("opaque", attribute_names, attribute_values);
   gtype_name = find_attribute ("glib:type-name", attribute_names, attribute_values);
   gtype_init = find_attribute ("glib:get-type", attribute_names, attribute_values);
   gtype_struct = find_attribute ("glib:is-gtype-struct-for", attribute_names, attribute_values);
@@ -2605,9 +2647,15 @@ start_struct (GMarkupParseContext *context,
   else
     struct_->deprecated = FALSE;
 
-  if (disguised && strcmp (disguised, "1") == 0)
+  if (g_strcmp0 (disguised, "1") == 0)
     struct_->disguised = TRUE;
 
+  if (g_strcmp0 (pointer, "1") == 0)
+    struct_->pointer = TRUE;
+
+  if (g_strcmp0 (opaque, "1") == 0)
+    struct_->opaque = TRUE;
+
   struct_->is_gtype_struct = gtype_struct != NULL;
 
   struct_->gtype_name = g_strdup (gtype_name);
@@ -3018,7 +3066,9 @@ start_element_handler (GMarkupParseContext *context,
              ctx->current_module->aliases = ctx->aliases;
              ctx->aliases = NULL;
              ctx->current_module->disguised_structures = ctx->disguised_structures;
+             ctx->current_module->pointer_structures = ctx->pointer_structures;
              ctx->disguised_structures = NULL;
+             ctx->pointer_structures = NULL;
 
              for (l = ctx->include_modules; l; l = l->next)
                _g_ir_module_add_include_module (ctx->current_module, l->data);
@@ -3607,6 +3657,7 @@ _g_ir_parser_parse_string (GIrParser           *parser,
   ctx.include_modules = NULL;
   ctx.aliases = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
   ctx.disguised_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+  ctx.pointer_structures = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
   ctx.type_depth = 0;
   ctx.dependencies = NULL;
   ctx.current_module = NULL;
@@ -3639,10 +3690,9 @@ _g_ir_parser_parse_string (GIrParser           *parser,
       /* An error occurred before we created a module, so we haven't
        * transferred ownership of these hash tables to the module.
        */
-      if (ctx.aliases != NULL)
-       g_hash_table_destroy (ctx.aliases);
-      if (ctx.disguised_structures != NULL)
-       g_hash_table_destroy (ctx.disguised_structures);
+      g_clear_pointer (&ctx.aliases, g_hash_table_unref);
+      g_clear_pointer (&ctx.disguised_structures, g_hash_table_unref);
+      g_clear_pointer (&ctx.pointer_structures, g_hash_table_unref);
       g_list_free (ctx.include_modules);
     }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]