X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=glib%2Fgmarkup.c;h=d84068a19de1c96e1229a47ed8b1a9dfe0374f5f;hb=bc6ee788b4ff6590513da6ab657448885e92b20b;hp=11f68de6fbf07ec2bf329e5cf9fd7fdad3baf12c;hpb=5e62827efdf8a6efbf48e5ed88e02ec4e3a40329;p=platform%2Fupstream%2Fglib.git diff --git a/glib/gmarkup.c b/glib/gmarkup.c index 11f68de..d84068a 100644 --- a/glib/gmarkup.c +++ b/glib/gmarkup.c @@ -15,8 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with GLib; see the file COPYING.LIB. If not, - * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * see . */ #include "config.h" @@ -40,10 +39,8 @@ /** * SECTION:markup - * @Title: Simple XML Subset Parser - * @Short_description: parses a subset of XML - * @See_also: XML - * Specification + * @Title: Simple XML Subset Parser * @Short_description: parses a subset of XML + * @See_also: [XML Specification](http://www.w3.org/TR/REC-xml/) * * The "GMarkup" parser is intended to parse a simple markup format * that's a subset of XML. This is a small, efficient, easy-to-use @@ -57,31 +54,34 @@ * * GMarkup is not guaranteed to signal an error on all invalid XML; * the parser may accept documents that an XML parser would not. - * However, XML documents which are not well-formedBeing wellformed is a weaker condition than being - * valid. See the XML - * specification for definitions of these terms. - * are not considered valid GMarkup documents. + * However, XML documents which are not well-formed (which is a + * weaker condition than being valid. See the + * [XML specification](http://www.w3.org/TR/REC-xml/) + * for definitions of these terms.) are not considered valid GMarkup + * documents. * * Simplifications to XML include: - * - * Only UTF-8 encoding is allowed - * No user-defined entities - * Processing instructions, comments and the doctype declaration - * are "passed through" but are not interpreted in any way - * No DTD or validation. - * + * + * - Only UTF-8 encoding is allowed + * + * - No user-defined entities + * + * - Processing instructions, comments and the doctype declaration + * are "passed through" but are not interpreted in any way + * + * - No DTD or validation * * The markup format does support: - * - * Elements - * Attributes - * 5 standard entities: - * &amp; &lt; &gt; &quot; &apos; - * - * Character references - * Sections marked as CDATA - * + * + * - Elements + * + * - Attributes + * + * - 5 standard entities: & < > " ' + * + * - Character references + * + * - Sections marked as CDATA */ G_DEFINE_QUARK (g-markup-error-quark, g_markup_error) @@ -403,6 +403,7 @@ set_error_literal (GMarkupParseContext *context, g_propagate_error (error, tmp_error); } +G_GNUC_PRINTF(4, 5) static void set_error (GMarkupParseContext *context, GError **error, @@ -564,6 +565,7 @@ utf8_str (const gchar *utf8, return buf; } +G_GNUC_PRINTF(5, 6) static void set_unescape_error (GMarkupParseContext *context, GError **error, @@ -629,7 +631,7 @@ unescape_gstring_inplace (GMarkupParseContext *context, normalize_attribute = FALSE; /* - * Meeks' theorum: unescaping can only shrink text. + * Meeks' theorem: unescaping can only shrink text. * for < etc. this is obvious, for ￿ more * thought is required, but this is patently so. */ @@ -682,7 +684,7 @@ unescape_gstring_inplace (GMarkupParseContext *context, "inside a character reference " "(ê for example) - perhaps " "the digit is too large"), - end - from, from); + (int)(end - from), from); return FALSE; } else if (*end != ';') @@ -717,7 +719,7 @@ unescape_gstring_inplace (GMarkupParseContext *context, from, G_MARKUP_ERROR_PARSE, _("Character reference '%-.*s' does not " "encode a permitted character"), - end - from, from); + (int)(end - from), from); return FALSE; } } @@ -762,7 +764,7 @@ unescape_gstring_inplace (GMarkupParseContext *context, set_unescape_error (context, error, from, G_MARKUP_ERROR_PARSE, _("Entity name '%-.*s' is not known"), - end-from, from); + (int)(end - from), from); else set_unescape_error (context, error, from, G_MARKUP_ERROR_PARSE, @@ -1002,21 +1004,40 @@ static inline void emit_start_element (GMarkupParseContext *context, GError **error) { - int i; + int i, j = 0; const gchar *start_name; const gchar **attr_names; const gchar **attr_values; GError *tmp_error; + /* In case we want to ignore qualified tags and we see that we have + * one here, we push a subparser. This will ignore all tags inside of + * the qualified tag. + * + * We deal with the end of the subparser from emit_end_element. + */ + if ((context->flags & G_MARKUP_IGNORE_QUALIFIED) && strchr (current_element (context), ':')) + { + static const GMarkupParser ignore_parser; + g_markup_parse_context_push (context, &ignore_parser, NULL); + clear_attributes (context); + return; + } + attr_names = g_newa (const gchar *, context->cur_attr + 2); attr_values = g_newa (const gchar *, context->cur_attr + 2); for (i = 0; i < context->cur_attr + 1; i++) { - attr_names[i] = context->attr_names[i]->str; - attr_values[i] = context->attr_values[i]->str; + /* Possibly omit qualified attribute names from the list */ + if ((context->flags & G_MARKUP_IGNORE_QUALIFIED) && strchr (context->attr_names[i]->str, ':')) + continue; + + attr_names[j] = context->attr_names[i]->str; + attr_values[j] = context->attr_values[i]->str; + j++; } - attr_names[i] = NULL; - attr_values[i] = NULL; + attr_names[j] = NULL; + attr_values[j] = NULL; /* Call user callback for element start */ tmp_error = NULL; @@ -1036,6 +1057,45 @@ emit_start_element (GMarkupParseContext *context, propagate_error (context, error, tmp_error); } +static void +emit_end_element (GMarkupParseContext *context, + GError **error) +{ + /* We need to pop the tag stack and call the end_element + * function, since this is the close tag + */ + GError *tmp_error = NULL; + + g_assert (context->tag_stack != NULL); + + possibly_finish_subparser (context); + + /* We might have just returned from our ignore subparser */ + if ((context->flags & G_MARKUP_IGNORE_QUALIFIED) && strchr (current_element (context), ':')) + { + g_markup_parse_context_pop (context); + pop_tag (context); + return; + } + + tmp_error = NULL; + if (context->parser->end_element) + (* context->parser->end_element) (context, + current_element (context), + context->user_data, + &tmp_error); + + ensure_no_outstanding_subparser (context); + + if (tmp_error) + { + mark_error (context, tmp_error); + g_propagate_error (error, tmp_error); + } + + pop_tag (context); +} + /** * g_markup_parse_context_parse: * @context: a #GMarkupParseContext @@ -1182,54 +1242,25 @@ g_markup_parse_context_parse (GMarkupParseContext *context, case STATE_AFTER_ELISION_SLASH: /* Possible next state: AFTER_CLOSE_ANGLE */ + if (*context->iter == '>') + { + /* move after the close angle */ + advance_char (context); + context->state = STATE_AFTER_CLOSE_ANGLE; + emit_end_element (context, error); + } + else + { + gchar buf[8]; - { - /* We need to pop the tag stack and call the end_element - * function, since this is the close tag - */ - GError *tmp_error = NULL; - - g_assert (context->tag_stack != NULL); - - possibly_finish_subparser (context); - - tmp_error = NULL; - if (context->parser->end_element) - (* context->parser->end_element) (context, - current_element (context), - context->user_data, - &tmp_error); - - ensure_no_outstanding_subparser (context); - - if (tmp_error) - { - mark_error (context, tmp_error); - g_propagate_error (error, tmp_error); - } - else - { - if (*context->iter == '>') - { - /* move after the close angle */ - advance_char (context); - context->state = STATE_AFTER_CLOSE_ANGLE; - } - else - { - gchar buf[8]; - - set_error (context, - error, - G_MARKUP_ERROR_PARSE, - _("Odd character '%s', expected a '>' character " - "to end the empty-element tag '%s'"), - utf8_str (context->iter, buf), - current_element (context)); - } - } - pop_tag (context); - } + set_error (context, + error, + G_MARKUP_ERROR_PARSE, + _("Odd character '%s', expected a '>' character " + "to end the empty-element tag '%s'"), + utf8_str (context->iter, buf), + current_element (context)); + } break; case STATE_INSIDE_OPEN_TAG_NAME: @@ -1587,26 +1618,11 @@ g_markup_parse_context_parse (GMarkupParseContext *context, } else { - GError *tmp_error; advance_char (context); context->state = STATE_AFTER_CLOSE_ANGLE; context->start = NULL; - possibly_finish_subparser (context); - - /* call the end_element callback */ - tmp_error = NULL; - if (context->parser->end_element) - (* context->parser->end_element) (context, - close_name->str, - context->user_data, - &tmp_error); - - ensure_no_outstanding_subparser (context); - pop_tag (context); - - if (tmp_error) - propagate_error (context, error, tmp_error); + emit_end_element (context, error); } context->partial_chunk = close_name; truncate_partial (context); @@ -1980,7 +1996,7 @@ g_markup_parse_context_get_user_data (GMarkupParseContext *context) * As an example, see the following implementation of a simple * parser that counts the number of tags encountered. * - * |[ + * |[ * typedef struct * { * gint tag_count; @@ -2022,7 +2038,7 @@ g_markup_parse_context_get_user_data (GMarkupParseContext *context) * In order to allow this parser to be easily used as a subparser, the * following interface is provided: * - * |[ + * |[ * void * start_counting (GMarkupParseContext *context) * { @@ -2047,13 +2063,13 @@ g_markup_parse_context_get_user_data (GMarkupParseContext *context) * * The subparser would then be used as follows: * - * |[ + * |[ * static void start_element (context, element_name, ...) * { * if (strcmp (element_name, "count-these") == 0) * start_counting (context); * - * /* else, handle other tags... */ + * // else, handle other tags... * } * * static void end_element (context, element_name, ...) @@ -2061,7 +2077,7 @@ g_markup_parse_context_get_user_data (GMarkupParseContext *context) * if (strcmp (element_name, "count-these") == 0) * g_print ("Counted %d tags\n", end_counting (context)); * - * /* else, handle other tags... */ + * // else, handle other tags... * } * ]| * @@ -2199,7 +2215,7 @@ append_escaped_text (GString *str, * of line endings and attribute values. * * Note also that this function will produce character references in - * the range of &#x1; ... &#x1f; for all control sequences + * the range of  ...  for all control sequences * except for tabstop, newline and carriage return. The character * references in this range are not valid XML 1.0, but they are * valid XML 1.1 and will be accepted by the GMarkup parser. @@ -2364,6 +2380,9 @@ find_conversion (const char *format, * * Since: 2.4 */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" + gchar * g_markup_vprintf_escaped (const gchar *format, va_list args) @@ -2398,9 +2417,9 @@ g_markup_vprintf_escaped (const gchar *format, * To find the span of the first argument, we find the first position * where the two arguments differ, which tells us that the first * argument formatted to "Susan & Fred". We then escape that - * to "Susan & Fred" and join up with the intermediate portions + * to "Susan & Fred" and join up with the intermediate portions * of the format string and the second argument to get - * "Susan & Fred ate 5 apples". + * "Susan & Fred ate 5 apples". */ /* Create the two modified format strings @@ -2428,6 +2447,7 @@ g_markup_vprintf_escaped (const gchar *format, G_VA_COPY (args2, args); output1 = g_strdup_vprintf (format1->str, args); + if (!output1) { va_end (args2); @@ -2438,7 +2458,6 @@ g_markup_vprintf_escaped (const gchar *format, va_end (args2); if (!output2) goto cleanup; - result = g_string_new (NULL); /* Iterate through the original format string again, @@ -2490,6 +2509,8 @@ g_markup_vprintf_escaped (const gchar *format, return NULL; } +#pragma GCC diagnostic pop + /** * g_markup_printf_escaped: * @format: printf() style format string @@ -2502,15 +2523,15 @@ g_markup_vprintf_escaped (const gchar *format, * output, without having to worry that the strings * might themselves contain markup. * - * |[ - * const char *store = "Fortnum & Mason"; + * |[ + * const char *store = "Fortnum & Mason"; * const char *item = "Tea"; * char *output; - *   - * output = g_markup_printf_escaped ("<purchase>" - * "<store>%s</store>" - * "<item>%s</item>" - * "</purchase>", + * + * output = g_markup_printf_escaped ("" + * "%s" + * "%s" + * "", * store, item); * ]| *