/* markup.h -- simple XML-like string parser
   Copyright (C) 2015 Free Software Foundation, Inc.

   This file is not part of the GNU gettext program, but is used with
   GNU gettext.

   This is a stripped down version of GLib's gmarkup.h.  The original
   copyright notice is as follows:
 */

/* gmarkup.h - Simple XML-like string parser/writer
 *
 *  Copyright 2000 Red Hat, Inc.
 *
 * GLib is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * GLib 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
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with GLib; see the file COPYING.LIB.  If not,
 * see <https://www.gnu.org/licenses/>.
 */

#ifndef __MARKUP_H__
#define __MARKUP_H__ 1

#ifdef __cplusplus
extern "C" {
#endif

#include <stdbool.h>
#include <stddef.h>
#include <sys/types.h>

/**
 * markup_parse_flags_ty:
 * @MARKUP_DO_NOT_USE_THIS_UNSUPPORTED_FLAG: flag you should not use
 * @MARKUP_TREAT_CDATA_AS_TEXT: When this flag is set, CDATA marked
 *     sections are not passed literally to the @passthrough function of
 *     the parser. Instead, the content of the section (without the
 *     `<![CDATA[` and `]]>`) is
 *     passed to the @text function. This flag was added in GLib 2.12
 * @MARKUP_PREFIX_ERROR_POSITION: Normally errors caught by GMarkup
 *     itself have line/column information prefixed to them to let the
 *     caller know the location of the error. When this flag is set the
 *     location information is also prefixed to errors generated by the
 *     #GMarkupParser implementation functions
 * @MARKUP_IGNORE_QUALIFIED: Ignore (don't report) qualified
 *     attributes and tags, along with their contents.  A qualified
 *     attribute or tag is one that contains ':' in its name (ie: is in
 *     another namespace).  Since: 2.40.
 *
 * Flags that affect the behaviour of the parser.
 */
typedef enum
  {
    MARKUP_DO_NOT_USE_THIS_UNSUPPORTED_FLAG = 1 << 0,
    MARKUP_TREAT_CDATA_AS_TEXT = 1 << 1,
    MARKUP_PREFIX_ERROR_POSITION = 1 << 2,
    MARKUP_IGNORE_QUALIFIED = 1 << 3
  } markup_parse_flags_ty;

/**
 * markup_parse_context_ty:
 *
 * A parse context is used to parse a stream of bytes that
 * you expect to contain marked-up text.
 *
 * See markup_parse_context_new(), #markup_parser_ty, and so
 * on for more details.
 */
typedef struct _markup_parse_context_ty markup_parse_context_ty;
typedef struct _markup_parser_ty markup_parser_ty;

/**
 * markup_parser_ty:
 * @start_element: Callback to invoke when the opening tag of an element
 *     is seen. The callback's @attribute_names and @attribute_values parameters
 *     are %NULL-terminated.
 * @end_element: Callback to invoke when the closing tag of an element
 *     is seen. Note that this is also called for empty tags like
 *     `<empty/>`.
 * @text: Callback to invoke when some text is seen (text is always
 *     inside an element). Note that the text of an element may be spread
 *     over multiple calls of this function. If the
 *     %MARKUP_TREAT_CDATA_AS_TEXT flag is set, this function is also
 *     called for the content of CDATA marked sections.
 * @passthrough: Callback to invoke for comments, processing instructions
 *     and doctype declarations; if you're re-writing the parsed document,
 *     write the passthrough text back out in the same position. If the
 *     %MARKUP_TREAT_CDATA_AS_TEXT flag is not set, this function is also
 *     called for CDATA marked sections.
 * @error: Callback to invoke when an error occurs.
 *
 * Any of the fields in #markup_parser_ty can be %NULL, in which case they
 * will be ignored. Except for the @error function, any of these callbacks
 * can set an error; in particular the %MARKUP_ERROR_UNKNOWN_ELEMENT,
 * %MARKUP_ERROR_UNKNOWN_ATTRIBUTE, and %MARKUP_ERROR_INVALID_CONTENT
 * errors are intended to be set from these callbacks. If you set an error
 * from a callback, markup_parse_context_parse() will report that error
 * back to its caller.
 */
struct _markup_parser_ty
{
  /* Called for open tags <foo bar="baz"> */
  bool (*start_element) (markup_parse_context_ty *context,
                         const char *element_name,
                         const char **attribute_names,
                         const char **attribute_values,
                         void *user_data);

  /* Called for close tags </foo> */
  bool (*end_element) (markup_parse_context_ty *context,
                       const char *element_name,
                       void *user_data);

  /* Called for character data */
  /* text is not nul-terminated */
  bool (*text) (markup_parse_context_ty *context,
                const char *text,
                size_t text_len,
                void *user_data);

  /* 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. */
  bool (*passthrough) (markup_parse_context_ty *context,
                       const char *passthrough_text,
                       size_t text_len,
                       void *user_data);

  /* Called on error, including one set by other
   * methods in the vtable. The GError should not be freed.
   */
  void (*error) (markup_parse_context_ty *context,
                 const char *error_text,
                 void *user_data);
};

extern markup_parse_context_ty *
       markup_parse_context_new (const markup_parser_ty *parser,
                                 markup_parse_flags_ty flags,
                                 void *user_data);
extern void markup_parse_context_free (markup_parse_context_ty *context);
extern bool markup_parse_context_parse (markup_parse_context_ty *context,
                                        const char *text,
                                        ssize_t text_len);
extern bool markup_parse_context_end_parse (markup_parse_context_ty *context);
extern const char *
       markup_parse_context_get_error (markup_parse_context_ty *context);

#ifdef __cplusplus
}
#endif

#endif /* __MARKUP_H__ */
