From 9bf7be140528c7899071ea85ad09f3f225fcd582 Mon Sep 17 00:00:00 2001 From: Miguel de Icaza Date: Thu, 31 Aug 2006 04:23:17 +0000 Subject: [PATCH] Commit non-working, work-in-progress svn path=/trunk/mono/; revision=64592 --- eglib/TODO | 1 - eglib/src/glib.h | 50 ++++++++++++++++++ eglib/src/gmarkup.c | 125 ++++++++++++++++++++++++++++++++++++++++++++ eglib/test/markup.c | 45 ++++++++++++++++ 4 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 eglib/src/gmarkup.c create mode 100644 eglib/test/markup.c diff --git a/eglib/TODO b/eglib/TODO index 334e507f93b7d..41e775c45ec3f 100644 --- a/eglib/TODO +++ b/eglib/TODO @@ -59,7 +59,6 @@ Important Groups: * Miscelaneous 5 g_newa 3 g_spaced_primes_closest - 2 g_set_prgname 2 g_printerr 1 g_mem_set_vtable 1 g_log_set_handler diff --git a/eglib/src/glib.h b/eglib/src/glib.h index 287e16ac0045a..ef6cfa537b864 100644 --- a/eglib/src/glib.h +++ b/eglib/src/glib.h @@ -543,5 +543,55 @@ GDir *g_dir_open (const gchar *path, guint flags, GError **error); const gchar *g_dir_read_name (GDir *dir); void g_dir_rewind (GDir *dir); void g_dir_close (GDir *dir); + +/* + * GMarkup + */ +typedef struct _GMarkupParseContext GMarkupParseContext; + +typedef enum +{ + G_MARKUP_DO_NOT_USE_THIS_UNSUPPORTED_FLAG = 1 << 0, + G_MARKUP_TREAT_CDATA_AS_TEXT = 1 << 1 +} GMarkupParseFlags; + +typedef struct { + void (*start_element) (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error); + + void (*end_element) (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error); + + void (*text) (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error); + + void (*passthrough) (GMarkupParseContext *context, + const gchar *passthrough_text, + gsize text_len, + gpointer user_data, + GError **error); + void (*error) (GMarkupParseContext *context, + GError *error, + gpointer user_data); +} GMarkupParser; + +GMarkupParseContext *g_markup_parse_context_new (const GMarkupParser *parser, + GMarkupParseFlags flags, + gpointer user_data, + GDestroyNotify user_data_dnotify); +void g_markup_parse_context_free (GMarkupParseContext *context); +gboolean g_markup_parse_context_parse (GMarkupParseContext *context, + const gchar *text, gssize text_len, + GError **error); + #endif diff --git a/eglib/src/gmarkup.c b/eglib/src/gmarkup.c new file mode 100644 index 0000000000000..a7b03d0237bdd --- /dev/null +++ b/eglib/src/gmarkup.c @@ -0,0 +1,125 @@ +/* + * gmakrup.c: Minimal XML markup reader. + * + * Unlike the GLib one, this can not be restarted with more text + * as the Mono use does not require it + * + * Author: + * Miguel de Icaza (miguel@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include +#include + +#define set_error(msg...) do { if (error != NULL) *error = g_error_new (1, 1, msg); } while (0); + +typedef enum { + START, +} ParseState; + +struct _GMarkupParseContext { + GMarkupParser parser; + gpointer user_data; + GDestroyNotify user_data_dnotify; + ParseState state; +}; + +GMarkupParseContext * +g_markup_parse_context_new (const GMarkupParser *parser, + GMarkupParseFlags flags, + gpointer user_data, + GDestroyNotify user_data_dnotify) +{ + GMarkupParseContext *context = g_new0 (GMarkupParseContext, 1); + + context->parser = *parser; + context->user_data = user_data; + context->user_data_dnotify = user_data_dnotify; + + return context; +} + +void +g_markup_parse_context_free (GMarkupParseContext *context) +{ + g_free (context); +} + +gboolean +g_markup_parse_context_parse (GMarkupParseContext *context, + const gchar *text, gssize text_len, GError **error) +{ + char *p, *end; + + g_return_val_if_fail (context != NULL, FALSE); + g_return_val_if_fail (text != NULL, FALSE); + g_return_val_if_fail (text_len >= 0, FALSE); + + end = text + text_len; + + for (p = text; p < end; p++){ + char c = *p; + + switch (context->state){ + case START: + if (c == ' ' || c == '\t' || c == '\f' || c == '\n') + continue; + if (c == '<'){ + context->state = START_ELEMENT; + continue; + } + set_error ("Expected < to start the document"); + + return FALSE; + + + case START_ELEMENT: { + char *element_start = p; + char **names, *values; + + if (!(isascii (*p) && isalpha (*p))) + set_error ("Must start with a letter"); + + for (++p; p < end && isalnum (*p); p++) + ; + if (p == end){ + set_error ("Expected an element"); + return FALSE; + } + for (; p < end && isspace (*p); p++) + ; + if (p == end){ + set_error ("Unfinished element"); + return FALSE; + } + p = parse_attributes (p, end, &names, &values); + if (p == end){ + set_error ("unfinished element"); + return FALSE; + } + + } + } + } +} + diff --git a/eglib/test/markup.c b/eglib/test/markup.c new file mode 100644 index 0000000000000..cd37d7e38cc4d --- /dev/null +++ b/eglib/test/markup.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include "test.h" + +#define do_test(s) do { char *r = markup_test (s); if (r != NULL) FAILED (r); } while (0) + +static char * +markup_test (const char *s) +{ + GMarkupParser *parser = g_new0 (GMarkupParser, 1); + GMarkupParseContext *context; + GError *error = NULL; + + context = g_markup_parse_context_new (parser, 0, 0, 0); + + g_markup_parse_context_parse (context, s, strlen (s), &error); + g_markup_parse_context_free (context); + + if (error != NULL) + return error->message; + return NULL; +} + +RESULT invalid_documents (void) +{ + /* These should fail */ + do_test ("<1>"); + do_test (""); + + return OK; +} + +static Test markup_tests [] = { + {"invalid_documents", invalid_documents}, + {"t2", hash_t2}, + {"grow", hash_grow}, + {"default", hash_default}, + {"null_lookup", hash_null_lookup}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(hashtable_tests_init, hashtable_tests) +