[gnome-builder/wip/slaf/xml-symbol-resolver: 22/25] xml: add a generic parser for xml and html
- From: Sébastien Lafargue <slafargue src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/slaf/xml-symbol-resolver: 22/25] xml: add a generic parser for xml and html
- Date: Wed, 8 Feb 2017 19:25:40 +0000 (UTC)
commit 56a1e248f8353580c63babf6850d14e6e93896de
Author: Sebastien Lafargue <slafargue gnome org>
Date: Tue Feb 7 16:02:07 2017 +0100
xml: add a generic parser for xml and html
data/style-schemes/builder-dark.xml | 13 +-
data/style-schemes/builder.xml | 13 +-
libide/symbols/ide-symbol.h | 3 +-
plugins/symbol-tree/symbol-tree-builder.c | 8 +-
plugins/xml-pack/ide-xml-tree-builder-generic.c | 432 +++++++++++++++++++----
plugins/xml-pack/ide-xml-tree-builder.c | 3 +-
plugins/xml-pack/ide-xml-tree-builder.h | 1 +
7 files changed, 379 insertions(+), 94 deletions(-)
---
diff --git a/data/style-schemes/builder-dark.xml b/data/style-schemes/builder-dark.xml
index 957aa44..e404703 100644
--- a/data/style-schemes/builder-dark.xml
+++ b/data/style-schemes/builder-dark.xml
@@ -177,12 +177,13 @@
<style name="xml:tag-match" background="#rgba(114,159,207,.20)"/>
<!-- Symbol-tree xml-pack coloring -->
- <style name="symboltree::ui-label" foreground="#000000" background="#D5E7FC"/>
- <style name="symboltree::ui-id" foreground="#000000" background="#D9E7BD"/>
- <style name="symboltree::ui-style-class" foreground="#000000" background="#DFCD9B"/>
- <style name="symboltree::ui-type" foreground="#000000" background="#F4DAC3"/>
- <style name="symboltree::ui-parent" foreground="#000000" background="#DEBECF"/>
- <style name="symboltree::ui-class" foreground="#000000" background="#FFEF98"/>
+ <style name="symboltree::label" foreground="#000000" background="#D5E7FC"/>
+ <style name="symboltree::id" foreground="#000000" background="#D9E7BD"/>
+ <style name="symboltree::style-class" foreground="#000000" background="#DFCD9B"/>
+ <style name="symboltree::type" foreground="#000000" background="#F4DAC3"/>
+ <style name="symboltree::parent" foreground="#000000" background="#DEBECF"/>
+ <style name="symboltree::class" foreground="#000000" background="#FFEF98"/>
+ <style name="symboltree::attribute" foreground="#000000" background="#F0E68C"/>
</style-scheme>
diff --git a/data/style-schemes/builder.xml b/data/style-schemes/builder.xml
index d29e847..4f4eead 100644
--- a/data/style-schemes/builder.xml
+++ b/data/style-schemes/builder.xml
@@ -182,11 +182,12 @@
<style name="sh:variable-definition" foreground="chameleon3"/>
<!-- Symbol-tree xml-pack coloring -->
- <style name="symboltree::ui-label" foreground="#000000" background="#D5E7FC"/>
- <style name="symboltree::ui-id" foreground="#000000" background="#D9E7BD"/>
- <style name="symboltree::ui-style-class" foreground="#000000" background="#DFCD9B"/>
- <style name="symboltree::ui-type" foreground="#000000" background="#F4DAC3"/>
- <style name="symboltree::ui-parent" foreground="#000000" background="#DEBECF"/>
- <style name="symboltree::ui-class" foreground="#000000" background="#FFEF98"/>
+ <style name="symboltree::label" foreground="#000000" background="#D5E7FC"/>
+ <style name="symboltree::id" foreground="#000000" background="#D9E7BD"/>
+ <style name="symboltree::style-class" foreground="#000000" background="#DFCD9B"/>
+ <style name="symboltree::type" foreground="#000000" background="#F4DAC3"/>
+ <style name="symboltree::parent" foreground="#000000" background="#DEBECF"/>
+ <style name="symboltree::class" foreground="#000000" background="#FFEF98"/>
+ <style name="symboltree::attribute" foreground="#000000" background="#F0E68C"/>>
</style-scheme>
diff --git a/libide/symbols/ide-symbol.h b/libide/symbols/ide-symbol.h
index be88f06..7e31d92 100644
--- a/libide/symbols/ide-symbol.h
+++ b/libide/symbols/ide-symbol.h
@@ -66,9 +66,10 @@ typedef enum
IDE_SYMBOL_UI_SUBMENU,
IDE_SYMBOL_UI_TEMPLATE,
IDE_SYMBOL_XML_ATTRIBUTE,
- IDE_SYMBOL_XML_CONTENT,
IDE_SYMBOL_XML_DECLARATION,
IDE_SYMBOL_XML_ELEMENT,
+ IDE_SYMBOL_XML_COMMENT,
+ IDE_SYMBOL_XML_CDATA,
} IdeSymbolKind;
typedef enum
diff --git a/plugins/symbol-tree/symbol-tree-builder.c b/plugins/symbol-tree/symbol-tree-builder.c
index bb17498..b33e56d 100644
--- a/plugins/symbol-tree/symbol-tree-builder.c
+++ b/plugins/symbol-tree/symbol-tree-builder.c
@@ -177,8 +177,12 @@ symbol_tree_builder_build_node (IdeTreeBuilder *builder,
icon_name = "xml-attribute-symbolic";
break;
- case IDE_SYMBOL_XML_CONTENT:
- icon_name = "xml-content-symbolic";
+ case IDE_SYMBOL_XML_CDATA:
+ icon_name = "xml-cdata-symbolic";
+ break;
+
+ case IDE_SYMBOL_XML_COMMENT:
+ icon_name = "xml-comment-symbolic";
break;
case IDE_SYMBOL_XML_DECLARATION:
diff --git a/plugins/xml-pack/ide-xml-tree-builder-generic.c b/plugins/xml-pack/ide-xml-tree-builder-generic.c
index 211e3a3..98c291c 100644
--- a/plugins/xml-pack/ide-xml-tree-builder-generic.c
+++ b/plugins/xml-pack/ide-xml-tree-builder-generic.c
@@ -17,23 +17,323 @@
*/
#include "ide-xml-stack.h"
+#include "ide-xml-symbol-node.h"
#include "ide-xml-tree-builder-utils-private.h"
#include "ide-xml-tree-builder-generic.h"
-static IdeXmlSymbolNode *
-create_node_from_reader (XmlReader *reader)
+typedef enum _BuildState
{
- const gchar *name;
- GFile *file = NULL;
- guint line = 0;
- guint line_offset = 0;
+ BUILD_STATE_NORMAL,
+ BUILD_STATE_WAIT_END_ELEMENT,
+ BUILD_STATE_GET_CONTENT,
+} BuildState;
- name = xml_reader_get_name (reader);
+typedef struct _ParserState
+{
+ IdeXmlTreeBuilder *self;
+ IdeXmlSax *parser;
+ IdeXmlStack *stack;
+ GFile *file;
+ IdeXmlAnalysis *analysis;
+ GPtrArray *diagnostics_array;
+ IdeXmlSymbolNode *root_node;
+ IdeXmlSymbolNode *parent_node;
+ IdeXmlSymbolNode *current_node;
+ BuildState build_state;
+ gint current_depth;
+} ParserState;
- return ide_xml_symbol_node_new (name, NULL, NULL,
- IDE_SYMBOL_UI_OBJECT,
- file, line, line_offset);
+static void
+parser_state_free (ParserState *state)
+{
+ g_clear_pointer (&state->analysis, ide_xml_analysis_unref);
+ g_clear_pointer (&state->diagnostics_array, g_ptr_array_unref);
+ g_clear_object (&state->stack);
+ g_clear_object (&state->file);
+ g_clear_object (&state->parser);
+ g_clear_object (&state->root_node);
+}
+
+static void
+state_processing (ParserState *state,
+ const gchar *element_name,
+ IdeXmlSymbolNode *node,
+ IdeXmlSaxCallbackType callback_type,
+ gboolean is_internal)
+{
+ IdeXmlSymbolNode *parent_node;
+ IdeXmlSymbolNode *popped_node G_GNUC_UNUSED;
+ g_autofree gchar *popped_element_name = NULL;
+ gint line;
+ gint line_offset;
+ gint depth;
+
+ g_assert (IDE_IS_XML_SYMBOL_NODE (node) || node == NULL);
+
+ if (callback_type == IDE_XML_SAX_CALLBACK_TYPE_CHAR)
+ {
+ ide_xml_symbol_node_set_value (state->current_node, element_name);
+ return;
+ }
+
+ depth = ide_xml_sax_get_depth (state->parser);
+
+ if (node == NULL)
+ {
+ if (callback_type == IDE_XML_SAX_CALLBACK_TYPE_END_ELEMENT)
+ {
+ /* TODO: compare current with popped */
+ if (ide_xml_stack_is_empty (state->stack))
+ {
+ g_warning ("Xml nodes stack empty\n");
+ return;
+ }
+
+ popped_node = ide_xml_stack_pop (state->stack, &popped_element_name, &parent_node, &depth);
+ state->parent_node = parent_node;
+ g_assert (state->parent_node != NULL);
+ }
+
+ state->current_depth = depth;
+ state->current_node = NULL;
+ return;
+ }
+
+ ide_xml_sax_get_position (state->parser, &line, &line_offset);
+ ide_xml_symbol_node_set_location (node, g_object_ref (state->file), line, line_offset);
+
+ /* TODO: take end elements into account and use:
+ * || ABS (depth - current_depth) > 1
+ */
+ if (depth < 0)
+ {
+ g_warning ("Wrong xml element depth, current:%i new:%i\n", state->current_depth, depth);
+ return;
+ }
+
+ if (callback_type == IDE_XML_SAX_CALLBACK_TYPE_START_ELEMENT)
+ {
+ ide_xml_stack_push (state->stack, element_name, node, state->parent_node, depth);
+ if (is_internal)
+ ide_xml_symbol_node_take_internal_child (state->parent_node, node);
+ else
+ ide_xml_symbol_node_take_child (state->parent_node, node);
+
+ state->parent_node = node;
+ }
+ else if (callback_type == IDE_XML_SAX_CALLBACK_TYPE_END_ELEMENT)
+ {
+ /* TODO: compare current with popped */
+ if (ide_xml_stack_is_empty (state->stack))
+ {
+ g_warning ("Xml nodes stack empty\n");
+ return;
+ }
+
+ popped_node = ide_xml_stack_pop (state->stack, &popped_element_name, &parent_node, &depth);
+ state->parent_node = parent_node;
+ g_assert (state->parent_node != NULL);
+ }
+ else
+ {
+ ide_xml_symbol_node_take_child (state->parent_node, node);
+ }
+
+ state->current_depth = depth;
+ state->current_node = node;
+}
+
+static gchar *
+collect_attributes (IdeXmlTreeBuilder *self,
+ const gchar **attributes)
+{
+ GString *string;
+ gchar *value;
+ const gchar **l = attributes;
+
+ g_assert (IDE_IS_XML_TREE_BUILDER (self));
+
+ if (attributes == NULL)
+ return NULL;
+
+ string = g_string_new (NULL);
+ while (l [0] != NULL)
+ {
+ value = ide_xml_tree_builder_get_color_tag (self, l [0], COLOR_TAG_ATTRIBUTE, TRUE, TRUE, TRUE);
+ g_string_append (string, value);
+ g_free (value);
+ g_string_append (string, l [1]);
+
+ l += 2;
+ }
+
+ return g_string_free (string, FALSE);
+}
+
+static void
+start_element_sax_cb (ParserState *state,
+ const xmlChar *name,
+ const xmlChar **attributes)
+{
+ IdeXmlTreeBuilder *self = (IdeXmlTreeBuilder *)state->self;
+ IdeXmlSymbolNode *node = NULL;
+ g_autofree gchar *attr = NULL;
+ g_autofree gchar *label = NULL;
+
+ g_assert (IDE_IS_XML_TREE_BUILDER (self));
+
+ attr = collect_attributes (self, (const gchar **)attributes);
+ label = g_strconcat ((const gchar *)name, attr, NULL);
+
+ node = ide_xml_symbol_node_new (label, NULL, NULL, IDE_SYMBOL_XML_ELEMENT, NULL, 0, 0);
+ g_object_set (node, "use-markup", TRUE, NULL);
+
+ state_processing (state, (const gchar *)name, node, IDE_XML_SAX_CALLBACK_TYPE_START_ELEMENT, FALSE);
+}
+
+static void
+comment_sax_cb (ParserState *state,
+ const xmlChar *name)
+{
+ IdeXmlSymbolNode *node = NULL;
+ g_autofree gchar *strip_name = NULL;
+
+ strip_name = g_strstrip (g_strdup ((const gchar *)name));
+ node = ide_xml_symbol_node_new (strip_name, NULL, NULL, IDE_SYMBOL_XML_COMMENT, NULL, 0, 0);
+ state_processing (state, "comment", node, IDE_XML_SAX_CALLBACK_TYPE_COMMENT, FALSE);
+}
+
+static void
+cdata_sax_cb (ParserState *state,
+ const xmlChar *value,
+ gint len)
+{
+ IdeXmlSymbolNode *node = NULL;
+
+ node = ide_xml_symbol_node_new ("cdata", NULL, NULL, IDE_SYMBOL_XML_CDATA, NULL, 0, 0);
+ state_processing (state, "cdata", node, IDE_XML_SAX_CALLBACK_TYPE_CDATA, FALSE);
+}
+
+static void
+end_element_sax_cb (ParserState *state,
+ const xmlChar *name)
+{
+ IdeXmlTreeBuilder *self = (IdeXmlTreeBuilder *)state->self;
+
+ g_assert (IDE_IS_XML_TREE_BUILDER (self));
+
+ state_processing (state, (const gchar *)name, NULL, IDE_XML_SAX_CALLBACK_TYPE_END_ELEMENT, FALSE);
+}
+
+static IdeDiagnostic *
+create_diagnostic (ParserState *state,
+ const gchar *msg,
+ IdeDiagnosticSeverity severity)
+{
+ IdeContext *context;
+ IdeDiagnostic *diagnostic;
+ g_autoptr(IdeSourceLocation) loc = NULL;
+ g_autoptr(IdeFile) ifile = NULL;
+ gint line;
+ gint line_offset;
+
+ context = ide_object_get_context (IDE_OBJECT (state->self));
+
+ ide_xml_sax_get_position (state->parser, &line, &line_offset);
+ ifile = ide_file_new (context, state->file);
+ loc = ide_source_location_new (ifile,
+ line - 1,
+ line_offset - 1,
+ 0);
+
+ diagnostic = ide_diagnostic_new (severity, msg, loc);
+
+ return diagnostic;
+}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+
+static void
+warning_sax_cb (ParserState *state,
+ const xmlChar *name,
+ ...)
+{
+ IdeXmlTreeBuilder *self = (IdeXmlTreeBuilder *)state->self;
+ IdeDiagnostic *diagnostic;
+ g_autofree gchar *msg = NULL;
+ va_list var_args;
+
+ g_assert (IDE_IS_XML_TREE_BUILDER (self));
+
+ va_start (var_args, name);
+ msg = g_strdup_vprintf ((const gchar *)name, var_args);
+ va_end (var_args);
+
+ diagnostic = create_diagnostic (state, msg, IDE_DIAGNOSTIC_WARNING);
+ g_ptr_array_add (state->diagnostics_array, diagnostic);
+}
+
+static void
+error_sax_cb (ParserState *state,
+ const xmlChar *name,
+ ...)
+{
+ IdeXmlTreeBuilder *self = (IdeXmlTreeBuilder *)state->self;
+ IdeDiagnostic *diagnostic;
+ g_autofree gchar *msg = NULL;
+ va_list var_args;
+
+ g_assert (IDE_IS_XML_TREE_BUILDER (self));
+
+ va_start (var_args, name);
+ msg = g_strdup_vprintf ((const gchar *)name, var_args);
+ va_end (var_args);
+
+ diagnostic = create_diagnostic (state, msg, IDE_DIAGNOSTIC_ERROR);
+ g_ptr_array_add (state->diagnostics_array, diagnostic);
+}
+
+static void
+fatal_error_sax_cb (ParserState *state,
+ const xmlChar *name,
+ ...)
+{
+ IdeXmlTreeBuilder *self = (IdeXmlTreeBuilder *)state->self;
+ IdeDiagnostic *diagnostic;
+ g_autofree gchar *msg = NULL;
+ va_list var_args;
+
+ g_assert (IDE_IS_XML_TREE_BUILDER (self));
+
+ va_start (var_args, name);
+ msg = g_strdup_vprintf ((const gchar *)name, var_args);
+ va_end (var_args);
+
+ diagnostic = create_diagnostic (state, msg, IDE_DIAGNOSTIC_FATAL);
+ g_ptr_array_add (state->diagnostics_array, diagnostic);
+}
+
+#pragma GCC diagnostic pop
+
+static void
+characters_sax_cb (ParserState *state,
+ const xmlChar *name,
+ gint len)
+{
+ IdeXmlTreeBuilder *self = (IdeXmlTreeBuilder *)state->self;
+ g_autofree gchar *element_value = NULL;
+
+ g_assert (IDE_IS_XML_TREE_BUILDER (self));
+
+ if (state->build_state != BUILD_STATE_GET_CONTENT)
+ return;
+
+ element_value = g_strndup ((gchar *)name, len);
+ state->build_state = BUILD_STATE_NORMAL;
+
+ state_processing (state, element_value, NULL, IDE_XML_SAX_CALLBACK_TYPE_CHAR, FALSE);
}
IdeXmlAnalysis *
@@ -41,75 +341,51 @@ ide_xml_tree_builder_generic_create (IdeXmlTreeBuilder *self,
IdeXmlSax *parser,
GFile *file,
const gchar *data,
- gsize size)
+ gsize length)
{
- IdeXmlStack *stack;
- IdeXmlAnalysis *analysis = NULL;
- IdeXmlSymbolNode *parent_node;
- IdeXmlSymbolNode *current_node;
- IdeXmlSymbolNode *previous_node = NULL;
- xmlReaderTypes type;
- gint depth = 0;
- gint current_depth = 0;
- gboolean is_empty;
-
- /* g_assert (XML_IS_READER (reader)); */
-
- /* stack = stack_new (); */
-
- /* parent_node = root_node = ide_xml_symbol_node_new ("root", IDE_SYMBOL_NONE, */
- /* NULL, 0, 0); */
- /* stack_push (stack, parent_node); */
-
- /* while (xml_reader_read (reader)) */
- /* { */
- /* type = xml_reader_get_node_type (reader); */
- /* if ( type == XML_READER_TYPE_ELEMENT) */
- /* { */
- /* current_node = create_node_from_reader (reader); */
- /* depth = xml_reader_get_depth (reader); */
- /* is_empty = xml_reader_is_empty_element (reader); */
- /* if (depth < 0) */
- /* { */
- /* g_warning ("Wrong xml element depth, current:%i new:%i\n", current_depth, depth); */
- /* break; */
- /* } */
-
- /* if (depth > current_depth) */
- /* { */
- /* ++current_depth; */
- /* stack_push (stack, parent_node); */
-
- /* g_assert (previous_node != NULL); */
- /* parent_node = previous_node; */
- /* ide_xml_symbol_node_take_child (parent_node, current_node); */
- /* } */
- /* else if (depth < current_depth) */
- /* { */
- /* --current_depth; */
- /* parent_node = stack_pop (stack); */
- /* if (parent_node == NULL) */
- /* { */
- /* g_warning ("Xml nodes stack empty\n"); */
- /* break; */
- /* } */
-
- /* g_assert (parent_node != NULL); */
- /* ide_xml_symbol_node_take_child (parent_node, current_node); */
- /* } */
- /* else */
- /* { */
- /* ide_xml_symbol_node_take_child (parent_node, current_node); */
- /* } */
-
- /* previous_node = current_node; */
- /* print_node (current_node, depth); */
- /* } */
- /* } */
-
- /* printf ("stack size:%li\n", stack_get_size (stack)); */
-
- /* stack_destroy (stack); */
+ ParserState *state;
+ IdeXmlAnalysis *analysis;
+ g_autoptr(IdeDiagnostics) diagnostics = NULL;
+ g_autofree gchar *uri = NULL;
+
+ g_return_val_if_fail (IDE_IS_XML_SAX (parser), NULL);
+ g_return_val_if_fail (G_IS_FILE (file), NULL);
+ g_return_val_if_fail (data != NULL, NULL);
+ g_return_val_if_fail (length > 0, NULL);
+
+ state = g_slice_new0 (ParserState);
+ state->self = self;
+ state->parser = g_object_ref (parser);
+ state->stack = ide_xml_stack_new ();
+ state->file = g_object_ref (file);
+ state->diagnostics_array = g_ptr_array_new_with_free_func ((GDestroyNotify)ide_diagnostic_unref);
+ state->build_state = BUILD_STATE_NORMAL;
+
+ ide_xml_sax_clear (parser);
+ ide_xml_sax_set_callback (parser, IDE_XML_SAX_CALLBACK_TYPE_START_ELEMENT, start_element_sax_cb);
+ ide_xml_sax_set_callback (parser, IDE_XML_SAX_CALLBACK_TYPE_END_ELEMENT, end_element_sax_cb);
+ ide_xml_sax_set_callback (parser, IDE_XML_SAX_CALLBACK_TYPE_COMMENT, comment_sax_cb);
+ ide_xml_sax_set_callback (parser, IDE_XML_SAX_CALLBACK_TYPE_CDATA, cdata_sax_cb);
+ ide_xml_sax_set_callback (parser, IDE_XML_SAX_CALLBACK_TYPE_CHAR, characters_sax_cb);
+
+ ide_xml_sax_set_callback (parser, IDE_XML_SAX_CALLBACK_TYPE_WARNING, warning_sax_cb);
+ ide_xml_sax_set_callback (parser, IDE_XML_SAX_CALLBACK_TYPE_ERROR, error_sax_cb);
+ ide_xml_sax_set_callback (parser, IDE_XML_SAX_CALLBACK_TYPE_FATAL_ERROR, fatal_error_sax_cb);
+
+ state->analysis = ide_xml_analysis_new (-1);
+ state->root_node = ide_xml_symbol_node_new ("root", NULL, "root", IDE_SYMBOL_NONE, NULL, 0, 0);
+ ide_xml_analysis_set_root_node (state->analysis, state->root_node);
+
+ state->parent_node = state->root_node;
+ ide_xml_stack_push (state->stack, "root", state->root_node, NULL, 0);
+
+ uri = g_file_get_uri (file);
+ ide_xml_sax_parse (parser, data, length, uri, state);
+
+ analysis = g_steal_pointer (&state->analysis);
+ diagnostics = ide_diagnostics_new (g_steal_pointer (&state->diagnostics_array));
+ ide_xml_analysis_set_diagnostics (analysis, diagnostics);
+ parser_state_free (state);
return analysis;
}
diff --git a/plugins/xml-pack/ide-xml-tree-builder.c b/plugins/xml-pack/ide-xml-tree-builder.c
index 78d90d5..50cd1a8 100644
--- a/plugins/xml-pack/ide-xml-tree-builder.c
+++ b/plugins/xml-pack/ide-xml-tree-builder.c
@@ -52,6 +52,7 @@ static ColorTag default_color_tags [] =
{ "type", "#000000", "#F4DAC3" }, // COLOR_TAG_TYPE
{ "parent", "#000000", "#DEBECF" }, // COLOR_TAG_PARENT
{ "class", "#000000", "#FFEF98" }, // COLOR_TAG_CLASS
+ { "attribute", "#000000", "#F0E68C" }, // COLOR_TAG_ATTRIBUTE
{ NULL },
};
@@ -279,7 +280,7 @@ init_color_tags (IdeXmlTreeBuilder *self)
tag_set = FALSE;
if (scheme != NULL)
{
- tag_name = g_strconcat ("symboltree::ui-", tag_ptr->name, NULL);
+ tag_name = g_strconcat ("symboltree::", tag_ptr->name, NULL);
if (NULL != (style = gtk_source_style_scheme_get_style (scheme, tag_name)))
{
g_object_get (style, "foreground", &foreground, NULL);
diff --git a/plugins/xml-pack/ide-xml-tree-builder.h b/plugins/xml-pack/ide-xml-tree-builder.h
index d903dab..7bc6a33 100644
--- a/plugins/xml-pack/ide-xml-tree-builder.h
+++ b/plugins/xml-pack/ide-xml-tree-builder.h
@@ -39,6 +39,7 @@ typedef enum _ColorTagId
COLOR_TAG_TYPE,
COLOR_TAG_PARENT,
COLOR_TAG_CLASS,
+ COLOR_TAG_ATTRIBUTE,
} ColorTagId;
IdeXmlTreeBuilder *ide_xml_tree_builder_new (void);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]