diff options
author | Corentin Noël <corentin@elementary.io> | 2019-08-29 15:56:16 +0000 |
---|---|---|
committer | Alberto Fanjul <albertofanjul@gmail.com> | 2019-08-29 15:56:16 +0000 |
commit | 08fe3669ab5fc810c7fc1acff3a0f42d5657dccd (patch) | |
tree | 431204532e2e2056c5c3d81ba2ea049066522df3 | |
parent | 12c3fc1986e9bf6310a080a7ebadab3ebf89f0aa (diff) | |
download | glade-08fe3669ab5fc810c7fc1acff3a0f42d5657dccd.tar.gz |
Make it easier to track GladeXML elements and be GObject Introspection friendly by registering boxed types
-rw-r--r-- | doc/gladeui-sections.txt | 15 | ||||
-rw-r--r-- | gladeui/glade-catalog.c | 6 | ||||
-rw-r--r-- | gladeui/glade-project.c | 5 | ||||
-rw-r--r-- | gladeui/glade-xml-utils.c | 167 | ||||
-rw-r--r-- | gladeui/glade-xml-utils.h | 11 |
5 files changed, 153 insertions, 51 deletions
diff --git a/doc/gladeui-sections.txt b/doc/gladeui-sections.txt index 79baa1e3..a06e8019 100644 --- a/doc/gladeui-sections.txt +++ b/doc/gladeui-sections.txt @@ -1297,25 +1297,28 @@ glade_xml_node_get_children_with_comments glade_xml_node_add_next_sibling glade_xml_node_add_prev_sibling glade_xml_node_prev_with_comments -glade_xml_doc_get_root glade_xml_doc_new glade_xml_doc_new_comment +glade_xml_doc_ref +glade_xml_doc_unref +glade_xml_doc_get_root glade_xml_doc_set_root -glade_xml_doc_free glade_xml_doc_save glade_xml_context_new -glade_xml_context_destroy +glade_xml_context_copy glade_xml_context_free glade_xml_context_new_from_path glade_xml_context_get_doc +GladeXmlContext +GladeXmlNode +GladeXmlDoc <SUBSECTION Standard> +glade_xml_context_get_type +glade_xml_doc_get_type glade_xml_node_get_type GLADE_XML_CONTEXT GLADE_XML_IS_CONTEXT CAST_BAD -GladeXmlContext -GladeXmlNode -GladeXmlDoc GLADE_XML_TAG_PROJECT GLADE_XML_TAG_WIDGET GLADE_XML_TAG_LIBGLADE_PROJECT diff --git a/gladeui/glade-catalog.c b/gladeui/glade-catalog.c index aa3b8925..b10c51e3 100644 --- a/gladeui/glade-catalog.c +++ b/gladeui/glade-catalog.c @@ -162,9 +162,7 @@ catalog_destroy (GladeCatalog *catalog) g_list_free (catalog->widget_groups); } - if (catalog->context) - glade_xml_context_free (catalog->context); - + g_clear_pointer (&catalog->context, glade_xml_context_free); g_slice_free (GladeCatalog, catalog); } @@ -423,7 +421,7 @@ catalog_load (GladeCatalog *catalog) } catalog->widget_groups = g_list_reverse (catalog->widget_groups); - catalog->context = (glade_xml_context_free (catalog->context), NULL); + g_clear_pointer (&catalog->context, glade_xml_context_free); return; } diff --git a/gladeui/glade-project.c b/gladeui/glade-project.c index 25f59871..36d1b81f 100644 --- a/gladeui/glade-project.c +++ b/gladeui/glade-project.c @@ -2805,7 +2805,7 @@ glade_project_autosave (GladeProject *project, GError **error) context = glade_project_write (project); doc = glade_xml_context_get_doc (context); ret = glade_xml_doc_save (doc, autosave_path); - glade_xml_context_destroy (context); + glade_xml_context_free (context); g_free (autosave_path); @@ -2949,7 +2949,7 @@ glade_project_save_verify (GladeProject *project, context = glade_project_write (project); doc = glade_xml_context_get_doc (context); ret = glade_xml_doc_save (doc, path); - glade_xml_context_destroy (context); + glade_xml_context_free (context); canonical_path = glade_util_canonical_path (path); g_assert (canonical_path); @@ -3030,6 +3030,7 @@ glade_project_preview (GladeProject *project, GladeWidget *gwidget) project->priv->writing_preview = FALSE; text = glade_xml_dump_from_context (context); + glade_xml_context_free (context); gwidget = glade_widget_get_toplevel (gwidget); if (!GTK_IS_WIDGET (glade_widget_get_object (gwidget))) diff --git a/gladeui/glade-xml-utils.c b/gladeui/glade-xml-utils.c index e7857a97..c08df9e7 100644 --- a/gladeui/glade-xml-utils.c +++ b/gladeui/glade-xml-utils.c @@ -55,17 +55,21 @@ struct _GladeXmlNode struct _GladeXmlDoc { - xmlDoc doc; + xmlDocPtr doc; + gint reference_count; }; struct _GladeXmlContext { GladeXmlDoc *doc; - gboolean freedoc; xmlNsPtr ns; }; G_DEFINE_BOXED_TYPE(GladeXmlNode, glade_xml_node, glade_xml_node_copy, glade_xml_node_delete); +G_DEFINE_BOXED_TYPE(GladeXmlDoc, glade_xml_doc, glade_xml_doc_ref, glade_xml_doc_unref); +G_DEFINE_BOXED_TYPE(GladeXmlContext, glade_xml_context, glade_xml_context_copy, glade_xml_context_free); + +static GladeXmlDoc *glade_xml_doc_new_from_doc (xmlDocPtr docptr); /* This is used inside for loops so that we skip xml comments * <!-- i am a comment -> @@ -612,40 +616,67 @@ glade_xml_search_child_required (GladeXmlNode *node, const gchar *name) /* --------------------------- Parse Context ----------------------------*/ +/* + * glade_xml_context_new_from_xml_namespace: + * @doc: (transfer full): a #GladeXmlDoc + * @ns: (nullable): a #xmlNs + * + * Returns: (transfer full): a new #GladeXmlContext + */ static GladeXmlContext * -glade_xml_context_new_real (GladeXmlDoc *doc, gboolean freedoc, xmlNsPtr ns) +glade_xml_context_new_from_xml_namespace (GladeXmlDoc *doc, xmlNsPtr ns) { GladeXmlContext *context = g_new0 (GladeXmlContext, 1); context->doc = doc; - context->freedoc = freedoc; context->ns = ns; return context; } +/** + * glade_xml_context_new: + * @doc: (transfer full): a #GladeXmlDoc + * @name_space: (nullable): unused argument + * + * Returns: (transfer full): a new #GladeXmlContext + */ GladeXmlContext * glade_xml_context_new (GladeXmlDoc *doc, const gchar *name_space) { /* We are not using the namespace now */ - return glade_xml_context_new_real (doc, TRUE, NULL); + return glade_xml_context_new_from_xml_namespace (doc, NULL); } -void -glade_xml_context_destroy (GladeXmlContext * context) +/** + * glade_xml_context_copy: + * @context: a #GladeXmlDoc + * + * Returns: (transfer full): a copy of the given #GladeXmlContext + */ +GladeXmlContext * +glade_xml_context_copy (GladeXmlContext *context) { - g_return_if_fail (context != NULL); - if (context->freedoc) - xmlFreeDoc ((xmlDoc *) context->doc); - g_free (context); + return glade_xml_context_new_from_xml_namespace (glade_xml_doc_ref (context->doc), context->ns); } +/** + * glade_xml_context_new_from_path: + * @full_path: the path to the XML file + * @nspace: (nullable): the expected namespace + * @root_name: (nullable): the expected root name + * + * Creates a new #GladeXmlContext from the given path. + * + * Returns: (transfer full) (nullable): a new #GladeXmlContext or %NULL on failure + */ GladeXmlContext * glade_xml_context_new_from_path (const gchar *full_path, const gchar *nspace, const gchar *root_name) { GladeXmlContext *context; + GladeXmlDoc *glade_doc; xmlDocPtr doc; xmlNsPtr name_space; xmlNodePtr root; @@ -688,7 +719,8 @@ glade_xml_context_new_from_path (const gchar *full_path, return NULL; } - context = glade_xml_context_new_real ((GladeXmlDoc *) doc, TRUE, name_space); + glade_doc = glade_xml_doc_new_from_doc (doc); + context = glade_xml_context_new_from_xml_namespace (glade_doc, name_space); return context; } @@ -697,16 +729,15 @@ glade_xml_context_new_from_path (const gchar *full_path, * glade_xml_context_free: * @context: An #GladeXmlContext * - * Similar to glade_xml_context_destroy but it also frees the document set in the context + * Frees the memory allocated by #GladeXmlContext. **/ void glade_xml_context_free (GladeXmlContext *context) { - g_return_if_fail (context != NULL); - if (context->doc) - xmlFreeDoc ((xmlDocPtr) context->doc); - context->doc = NULL; + if (!context) + return; + g_clear_pointer (&context->doc, glade_xml_doc_unref); g_free (context); } @@ -740,7 +771,7 @@ glade_xml_node_new (GladeXmlContext *context, const gchar *name) g_return_val_if_fail (context != NULL, NULL); g_return_val_if_fail (name != NULL, NULL); - return (GladeXmlNode *) xmlNewDocNode ((xmlDocPtr) context->doc, context->ns, + return (GladeXmlNode *) xmlNewDocNode (context->doc->doc, context->ns, BAD_CAST (name), NULL); } @@ -750,7 +781,7 @@ glade_xml_node_new_comment (GladeXmlContext *context, const gchar *comment) g_return_val_if_fail (context != NULL, NULL); g_return_val_if_fail (comment != NULL, NULL); - return (GladeXmlNode *) xmlNewDocComment ((xmlDocPtr) context->doc, + return (GladeXmlNode *) xmlNewDocComment (context->doc->doc, BAD_CAST (comment)); } @@ -772,12 +803,28 @@ glade_xml_node_delete (GladeXmlNode *node) xmlFreeNode ((xmlNodePtr) node); } +/** + * glade_xml_context_get_doc: + * @context: a #GladeXmlContext + * + * Get the #GladeXmlDoc this @context refers to. + * + * Returns: (transfer none): the #GladeXmlDoc that the @context refers to + */ GladeXmlDoc * glade_xml_context_get_doc (GladeXmlContext *context) { return context->doc; } +/** + * glade_xml_dump_from_context: + * @context: a #GladeXmlContext + * + * Dump the XML string from the context. + * + * Returns: the XML string, free the allocated memory with g_free() after use + */ gchar * glade_xml_dump_from_context (GladeXmlContext *context) { @@ -787,7 +834,7 @@ glade_xml_dump_from_context (GladeXmlContext *context) int size; doc = glade_xml_context_get_doc (context); - xmlDocDumpFormatMemory (&(doc->doc), &string, &size, 1); + xmlDocDumpFormatMemory (doc->doc, &string, &size, 1); text = claim_string (string); @@ -874,52 +921,98 @@ glade_xml_node_get_name (GladeXmlNode *node_in) return CAST_BAD (node->name); } +static GladeXmlDoc * +glade_xml_doc_new_from_doc (xmlDocPtr docptr) +{ + GladeXmlDoc *doc = g_new (GladeXmlDoc, 1); + doc->doc = docptr; + doc->reference_count = 1; + + return doc; +} + +/** + * glade_xml_doc_new: + * + * Creates a new #GladeXmlDoc. + * + * Returns: (transfer full): a new #GladeXmlDoc + */ GladeXmlDoc * glade_xml_doc_new (void) { - xmlDocPtr xml_doc = xmlNewDoc (BAD_CAST ("1.0")); + return glade_xml_doc_new_from_doc (xmlNewDoc (BAD_CAST ("1.0"))); +} + +/** + * glade_xml_doc_ref: + * @doc: a #GladeXmlDoc + * + * Increases the reference of the #GladeXmlDoc. + * + * Returns: (transfer full): the given #GladeXmlDoc + */ +GladeXmlDoc * +glade_xml_doc_ref (GladeXmlDoc *doc) +{ + g_return_val_if_fail (doc != NULL, NULL); + + g_atomic_int_inc (&doc->reference_count); + return doc; +} + +/** + * glade_xml_doc_unref: + * @doc: a #GladeXmlDoc + * + * Decreases the reference of the #GladeXmlDoc. + */ +void +glade_xml_doc_unref (GladeXmlDoc *doc) +{ + if (!doc) + return; - return (GladeXmlDoc *) xml_doc; + if (g_atomic_int_dec_and_test (&doc->reference_count)) + { + g_clear_pointer (&doc->doc, xmlFreeDoc); + g_free (doc); + } } void glade_xml_doc_set_root (GladeXmlDoc *doc_in, GladeXmlNode *node_in) { xmlNodePtr node = (xmlNodePtr) node_in; - xmlDocPtr doc = (xmlDocPtr) doc_in; - xmlDocSetRootElement (doc, node); + g_return_if_fail (doc_in != NULL); + + xmlDocSetRootElement (doc_in->doc, node); } gint glade_xml_doc_save (GladeXmlDoc *doc_in, const gchar *full_path) { - xmlDocPtr doc = (xmlDocPtr) doc_in; + g_return_val_if_fail (doc_in != NULL, 0); xmlKeepBlanksDefault (0); - return xmlSaveFormatFileEnc (full_path, doc, "UTF-8", 1); -} - -void -glade_xml_doc_free (GladeXmlDoc *doc_in) -{ - xmlDocPtr doc = (xmlDocPtr) doc_in; - - xmlFreeDoc (doc); + return xmlSaveFormatFileEnc (full_path, doc_in->doc, "UTF-8", 1); } /** * glade_xml_doc_get_root: * @doc: a #GladeXmlDoc * - * Returns: the #GladeXmlNode that is the document root of @doc + * Returns: (transfer none): the #GladeXmlNode that is the document root of @doc */ GladeXmlNode * glade_xml_doc_get_root (GladeXmlDoc *doc) { xmlNodePtr node; - node = xmlDocGetRootElement ((xmlDocPtr) (doc)); + g_return_val_if_fail (doc != NULL, NULL); + + node = xmlDocGetRootElement (doc->doc); return (GladeXmlNode *) node; } @@ -974,7 +1067,7 @@ glade_xml_load_sym_from_node (GladeXmlNode *node_in, GladeXmlNode * glade_xml_doc_new_comment (GladeXmlDoc *doc, const gchar *comment) { - return (GladeXmlNode *) xmlNewDocComment ((xmlDocPtr) (doc), BAD_CAST (comment)); + return (GladeXmlNode *) xmlNewDocComment (doc->doc, BAD_CAST (comment)); } GladeXmlNode * diff --git a/gladeui/glade-xml-utils.h b/gladeui/glade-xml-utils.h index dbe2b1a1..a19a7d1c 100644 --- a/gladeui/glade-xml-utils.h +++ b/gladeui/glade-xml-utils.h @@ -250,19 +250,22 @@ GType glade_xml_node_get_type (void) G_GNUC_CONST; /* Document Operatons */ GladeXmlNode * glade_xml_doc_get_root (GladeXmlDoc *doc); GladeXmlDoc * glade_xml_doc_new (void); +GladeXmlDoc * glade_xml_doc_ref (GladeXmlDoc *doc); +void glade_xml_doc_unref (GladeXmlDoc *doc); void glade_xml_doc_set_root (GladeXmlDoc *doc, GladeXmlNode *node); -void glade_xml_doc_free (GladeXmlDoc *doc_in); gint glade_xml_doc_save (GladeXmlDoc *doc_in, const gchar *full_path); GladeXmlNode * glade_xml_doc_new_comment (GladeXmlDoc *doc, const gchar *comment); +GType glade_xml_doc_get_type (void) G_GNUC_CONST; /* Parse Context */ GladeXmlContext * glade_xml_context_new (GladeXmlDoc *doc, const gchar *name_space); -void glade_xml_context_destroy (GladeXmlContext *context); +GladeXmlContext * glade_xml_context_copy (GladeXmlContext *context); void glade_xml_context_free (GladeXmlContext *context); GladeXmlContext * glade_xml_context_new_from_path (const gchar *full_path, const gchar *nspace, const gchar *root_name); GladeXmlDoc * glade_xml_context_get_doc (GladeXmlContext *context); +GType glade_xml_context_get_type (void) G_GNUC_CONST; /* Dumps an xml string from a context */ gchar * glade_xml_dump_from_context (GladeXmlContext *context); @@ -272,6 +275,10 @@ gboolean glade_xml_load_sym_from_node (GladeXmlNode *node_in, gchar *tagname, gpointer *sym_location); +G_DEFINE_AUTOPTR_CLEANUP_FUNC (GladeXmlDoc, glade_xml_doc_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (GladeXmlContext, glade_xml_context_free) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (GladeXmlNode, glade_xml_node_delete) + G_END_DECLS #endif /* __GLADE_XML_UTILS_H__ */ |