X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=eglib%2Fsrc%2Fgmarkup.c;h=c256f123a146a4694f5dfd229e2508bd72036f6b;hb=d069259e0cc4fab0f4a7a9267a40f3ede7e552ce;hp=4c8e81d18b9163e99ba9447b6f0c238b26d712e1;hpb=f1f8b8a867c800b21b6a03767252403c2f72cae2;p=mono.git diff --git a/eglib/src/gmarkup.c b/eglib/src/gmarkup.c index 4c8e81d18b9..c256f123a14 100644 --- a/eglib/src/gmarkup.c +++ b/eglib/src/gmarkup.c @@ -42,7 +42,7 @@ #include #include -#define set_error(msg...) do { if (error != NULL) *error = g_error_new (GINT_TO_POINTER (1), 1, msg); } while (0); +#define set_error(msg, ...) do { if (error != NULL) *error = g_error_new (GINT_TO_POINTER (1), 1, msg, __VA_ARGS__); } while (0); typedef enum { START, @@ -50,7 +50,8 @@ typedef enum { TEXT, FLUSH_TEXT, CLOSING_ELEMENT, - COMMENT + COMMENT, + SKIP_XML_DECLARATION } ParseState; struct _GMarkupParseContext { @@ -113,16 +114,17 @@ parse_value (const char *p, const char *end, char **value, GError **error) int l; if (*p != '"'){ - set_error ("Expected the attribute value to start with a quote"); + set_error ("%s", "Expected the attribute value to start with a quote"); return end; } start = ++p; - for (++p; p < end && *p != '"'; p++) + for (; p < end && *p != '"'; p++) + ; if (p == end) return end; - l = p - start; + l = (int)(p - start); p++; - *value = malloc (l + 1); + *value = g_malloc (l + 1); if (*value == NULL) return end; strncpy (*value, start, l); @@ -141,8 +143,8 @@ parse_name (const char *p, const char *end, char **value) if (p == end) return end; - l = p - start; - *value = malloc (l + 1); + l = (int)(p - start); + *value = g_malloc (l + 1); if (*value == NULL) return end; strncpy (*value, start, l); @@ -151,7 +153,7 @@ parse_name (const char *p, const char *end, char **value) } static const char * -parse_attributes (const char *p, const char *end, char ***names, char ***values, GError **error, int *full_stop) +parse_attributes (const char *p, const char *end, char ***names, char ***values, GError **error, int *full_stop, int state) { int nnames = 0; @@ -164,6 +166,11 @@ parse_attributes (const char *p, const char *end, char ***names, char ***values, *full_stop = 0; return p; } + if (state == SKIP_XML_DECLARATION && *p == '?' && ((p+1) < end) && *(p+1) == '>'){ + *full_stop = 0; + return p+1; + } + if (*p == '/' && ((p+1) < end && *(p+1) == '>')){ *full_stop = 1; return p+1; @@ -176,24 +183,24 @@ parse_attributes (const char *p, const char *end, char ***names, char ***values, p = skip_space (p, end); if (p == end){ - free (name); + g_free (name); return p; } if (*p != '='){ set_error ("Expected an = after the attribute name `%s'", name); - free (name); + g_free (name); return end; } p++; p = skip_space (p, end); if (p == end){ - free (name); + g_free (name); return end; } p = parse_value (p, end, &value, error); if (p == end){ - free (name); + g_free (name); return p; } @@ -238,19 +245,23 @@ g_markup_parse_context_parse (GMarkupParseContext *context, 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; + if (p+1 < end && p [1] == '?'){ + context->state = SKIP_XML_DECLARATION; + p++; + } else + context->state = START_ELEMENT; continue; } - set_error ("Expected < to start the document"); + set_error ("%s", "Expected < to start the document"); goto fail; - + case SKIP_XML_DECLARATION: case START_ELEMENT: { const char *element_start = p, *element_end; char *ename = NULL; @@ -260,7 +271,7 @@ g_markup_parse_context_parse (GMarkupParseContext *context, for (; p < end && isspace (*p); p++) ; if (p == end){ - set_error ("Unfinished element"); + set_error ("%s", "Unfinished element"); goto fail; } @@ -271,14 +282,14 @@ g_markup_parse_context_parse (GMarkupParseContext *context, } if (!(isascii (*p) && isalpha (*p))){ - set_error ("Expected an element name"); + set_error ("%s", "Expected an element name"); goto fail; } - for (++p; p < end && isalnum (*p); p++) + for (++p; p < end && (isalnum (*p) || (*p == '.')); p++) ; if (p == end){ - set_error ("Expected an element"); + set_error ("%s", "Expected an element"); goto fail; } element_end = p; @@ -286,10 +297,10 @@ g_markup_parse_context_parse (GMarkupParseContext *context, for (; p < end && isspace (*p); p++) ; if (p == end){ - set_error ("Unfinished element"); + set_error ("%s", "Unfinished element"); goto fail; } - p = parse_attributes (p, end, &names, &values, error, &full_stop); + p = parse_attributes (p, end, &names, &values, error, &full_stop, context->state); if (p == end){ if (names != NULL) { g_strfreev (names); @@ -297,21 +308,22 @@ g_markup_parse_context_parse (GMarkupParseContext *context, } /* Only set the error if parse_attributes did not */ if (error != NULL && *error == NULL) - set_error ("Unfinished sequence"); + set_error ("%s", "Unfinished sequence"); goto fail; } - l = element_end - element_start; - ename = malloc (l + 1); + l = (int)(element_end - element_start); + ename = g_malloc (l + 1); if (ename == NULL) goto fail; strncpy (ename, element_start, l); ename [l] = 0; - - if (context->parser.start_element != NULL) - context->parser.start_element (context, ename, - (const gchar **) names, - (const gchar **) values, - context->user_data, error); + + if (context->state == START_ELEMENT) + if (context->parser.start_element != NULL) + context->parser.start_element (context, ename, + (const gchar **) names, + (const gchar **) values, + context->user_data, error); if (names != NULL){ g_strfreev (names); @@ -319,21 +331,22 @@ g_markup_parse_context_parse (GMarkupParseContext *context, } if (error != NULL && *error != NULL){ - free (ename); + g_free (ename); goto fail; } if (full_stop){ - if (context->parser.end_element != NULL){ + if (context->parser.end_element != NULL && context->state == START_ELEMENT){ context->parser.end_element (context, ename, context->user_data, error); if (error != NULL && *error != NULL){ free (ename); goto fail; } } - free (ename); - } else + g_free (ename); + } else { context->level = g_slist_prepend (context->level, ename); + } context->state = TEXT; break; @@ -360,7 +373,7 @@ g_markup_parse_context_parse (GMarkupParseContext *context, p += 2; break; } - + break; case FLUSH_TEXT: if (context->parser.text != NULL){ @@ -383,22 +396,26 @@ g_markup_parse_context_parse (GMarkupParseContext *context, char *text; if (context->level == NULL){ - set_error ("Too many closing tags, not enough open tags"); + set_error ("%s", "Too many closing tags, not enough open tags"); goto fail; } - text = current->data; + text = current->data; if (context->parser.end_element != NULL){ context->parser.end_element (context, text, context->user_data, error); if (error != NULL && *error != NULL){ - free (text); + g_free (text); goto fail; } } - free (text); + g_free (text); + + while (p < end && *p != '>') + p++; context->level = context->level->next; g_slist_free_1 (current); + context->state = TEXT; break; } /* case CLOSING_ELEMENT */ @@ -408,7 +425,7 @@ g_markup_parse_context_parse (GMarkupParseContext *context, return TRUE; fail: - if (context->parser.error) + if (context->parser.error && error != NULL && *error) context->parser.error (context, *error, context->user_data); destroy_parse_state (context);