From 6651e80d358a8d7c6beacbbf0e23e3f9a4aa7c80 Mon Sep 17 00:00:00 2001 From: David King Date: Fri, 23 Nov 2012 18:47:03 +0000 Subject: docs: Add simple GMarkup parser example Based on an initial parser by Luc Pionchon. Tweaked to update to the latest coding standards by Philip Withnall. Fixes: #95 --- glib/gmarkup.c | 5 ++ glib/tests/markup-example.c | 168 ++++++++++++++++++++++++++++++++++++++++++++ glib/tests/meson.build | 1 + 3 files changed, 174 insertions(+) create mode 100644 glib/tests/markup-example.c diff --git a/glib/gmarkup.c b/glib/gmarkup.c index 0c2a9bece..9422abde4 100644 --- a/glib/gmarkup.c +++ b/glib/gmarkup.c @@ -85,6 +85,11 @@ * - Character references * * - Sections marked as CDATA + + * ## An example parser # {#example} + * + * Here is an example for a markup parser: + * [markup-example.c](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/glib/tests/markup-example.c) */ G_DEFINE_QUARK (g-markup-error-quark, g_markup_error) diff --git a/glib/tests/markup-example.c b/glib/tests/markup-example.c new file mode 100644 index 000000000..63e1a481c --- /dev/null +++ b/glib/tests/markup-example.c @@ -0,0 +1,168 @@ +/* Copyright (C) 2008 Luc Pionchon + * Copyright (C) 2012 David King + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * + * 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.1 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, see . + */ + +#include + +static void foo_parser_start_element (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error); +static void foo_parser_end_element (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error); +static void foo_parser_characters (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error); +static void foo_parser_passthrough (GMarkupParseContext *context, + const gchar *passthrough_text, + gsize text_len, + gpointer user_data, + GError **error); +static void foo_parser_error (GMarkupParseContext *context, + GError *error, + gpointer user_data); + +/* + * Parser + */ +static const GMarkupParser foo_xml_parser = { + foo_parser_start_element, + foo_parser_end_element, + foo_parser_characters, + foo_parser_passthrough, + foo_parser_error +}; + +/* + * Called for opening tags like + */ +static void +foo_parser_start_element (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + g_print ("element: <%s>\n", element_name); + + for (gsize i = 0; attribute_names[i]; i++) + { + g_print ("attribute: %s = \"%s\"\n", attribute_names[i], + attribute_values[i]); + } +} + +/* + * Called for closing tags like + */ +static void +foo_parser_end_element (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + g_print ("element: \n", element_name); +} + +/* + * Called for character data. Text is not nul-terminated + */ +static void +foo_parser_characters (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error) +{ + g_print ("text: [%s]\n", text); +} + +/* + * Called for strings that should be re-saved verbatim in this same + * position, but are not otherwise interpretable. At the moment this + * includes comments and processing instructions. Text is not + * nul-terminated. + */ +static void +foo_parser_passthrough (GMarkupParseContext *context, + const gchar *passthrough_text, + gsize text_len, + gpointer user_data, + GError **error) +{ + g_print ("passthrough: %s\n", passthrough_text); +} + +/* + * Called when any parsing method encounters an error. The GError should not be + * freed. + */ +static void +foo_parser_error (GMarkupParseContext *context, + GError *error, + gpointer user_data) +{ + g_printerr ("ERROR: %s\n", error->message); +} + +int +main (void) +{ + GMarkupParseContext *context; + gboolean success = FALSE; + glong len; + + /* + * Example XML for the parser. + */ + const gchar foo_xml_example[] = + "" + " bar text 1 " + " bar text 2 " + " foo text " + " " + " "; + + len = g_utf8_strlen (foo_xml_example, -1); + g_print ("Parsing: %s\n", foo_xml_example); + g_print ("(%ld UTF-8 characters)\n", len); + + context = g_markup_parse_context_new (&foo_xml_parser, G_MARKUP_DEFAULT_FLAGS, NULL, NULL); + + success = g_markup_parse_context_parse (context, foo_xml_example, len, NULL); + + g_markup_parse_context_free (context); + + if (success) + { + g_print ("DONE\n"); + return 0; + } + else + { + g_printerr ("ERROR\n"); + return 1; + } +} diff --git a/glib/tests/meson.build b/glib/tests/meson.build index a90051076..72a6ff92b 100644 --- a/glib/tests/meson.build +++ b/glib/tests/meson.build @@ -281,6 +281,7 @@ endif test_extra_programs = { 'assert-msg-test' : {}, + 'markup-example' : {'install' : false}, 'spawn-path-search-helper' : {}, 'spawn-test-helper' : {}, 'testing-helper' : {}, -- cgit v1.2.1