summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorentin Noël <corentin@elementary.io>2019-08-29 15:56:16 +0000
committerAlberto Fanjul <albertofanjul@gmail.com>2019-08-29 15:56:16 +0000
commit08fe3669ab5fc810c7fc1acff3a0f42d5657dccd (patch)
tree431204532e2e2056c5c3d81ba2ea049066522df3
parent12c3fc1986e9bf6310a080a7ebadab3ebf89f0aa (diff)
downloadglade-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.txt15
-rw-r--r--gladeui/glade-catalog.c6
-rw-r--r--gladeui/glade-project.c5
-rw-r--r--gladeui/glade-xml-utils.c167
-rw-r--r--gladeui/glade-xml-utils.h11
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__ */