GLib.MarkupParseContext.push

### Method

# GLib MarkupParseContextpush

since: 2.18

#### Declaration [src]

    void
    g_markup_parse_context_push (
      GMarkupParseContext* context,
      const GMarkupParser* parser,
      gpointer user_data
    )

#### Description [src]

Temporarily redirects markup data to a sub-parser.

This function may only be called from the start_element handler of a `GMarkupParser`. It must be matched with a corresponding call to `g_markup_parse_context_pop()` in the matching end_element handler (except in the case that the parser aborts due to an error).

All tags, text and other data between the matching tags is redirected to the subparser given by `parser`. `user_data` is used as the user_data for that parser. `user_data` is also passed to the error callback in the event that an error occurs. This includes errors that occur in subparsers of the subparser.

The end tag matching the start tag for which this call was made is handled by the previous parser (which is given its own user_data) which is why `g_markup_parse_context_pop()` is provided to allow “one last access” to the `user_data` provided to this function. In the case of error, the `user_data` provided here is passed directly to the error callback of the subparser and `g_markup_parse_context_pop()` should not be called. In either case, if `user_data` was allocated then it ought to be freed from both of these locations.

This function is not intended to be directly called by users interested in invoking subparsers. Instead, it is intended to be used by the subparsers themselves to implement a higher-level interface.

As an example, see the following implementation of a simple parser that counts the number of tags encountered.

    typedef struct
    {
      gint tag_count;
    } CounterData;

    static void
    counter_start_element (GMarkupParseContext  *context,
                           const gchar          *element_name,
                           const gchar         **attribute_names,
                           const gchar         **attribute_values,
                           gpointer              user_data,
                           GError              **error)
    {
      CounterData *data = user_data;

      data->tag_count++;
    }

    static void
    counter_error (GMarkupParseContext *context,
                   GError              *error,
                   gpointer             user_data)
    {
      CounterData *data = user_data;

      g_slice_free (CounterData, data);
    }

    static GMarkupParser counter_subparser =
    {
      counter_start_element,
      NULL,
      NULL,
      NULL,
      counter_error
    };

In order to allow this parser to be easily used as a subparser, the following interface is provided:

    void
    start_counting (GMarkupParseContext *context)
    {
      CounterData *data = g_slice_new (CounterData);

      data->tag_count = 0;
      g_markup_parse_context_push (context, &counter_subparser, data);
    }

    gint
    end_counting (GMarkupParseContext *context)
    {
      CounterData *data = g_markup_parse_context_pop (context);
      int result;

      result = data->tag_count;
      g_slice_free (CounterData, data);

      return result;
    }

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...
    }

    static void end_element (context, element_name, ...)
    {
      if (strcmp (element_name, "count-these") == 0)
        g_print ("Counted %d tags\n", end_counting (context));

      // else, handle other tags...
    }

Available since: 2.18

#### Parameters

`parser`

  Type: `GMarkupParser`

  A `GMarkupParser`.

  The data is owned by the caller of the method.

`user_data`

  Type: `gpointer`

  User data to pass to `GMarkupParser` functions.

  The argument can be `NULL`.
  The data is owned by the caller of the method.