#undef G_DISABLE_ASSERT
#undef G_LOG_DOMAIN

#include <stdio.h>
#include <glib.h>

static int depth = 0;

static void
indent (int extra)
{
  int i = 0;
  while (i < depth)
    {
      fputs ("  ", stdout);
      ++i;
    }
}

static void
start_element_handler  (GMarkupParseContext *context,
                        const gchar         *element_name,
                        const gchar        **attribute_names,
                        const gchar        **attribute_values,
                        gpointer             user_data,
                        GError             **error)
{
  int i;
  
  indent (0);
  printf ("ELEMENT '%s'\n", element_name);

  i = 0;
  while (attribute_names[i] != NULL)
    {
      indent (1);

      printf ("%s=\"%s\"\n",
              attribute_names[i],
              attribute_values[i]);
      
      ++i;
    }
  
  ++depth;
}

static void
end_element_handler    (GMarkupParseContext *context,
                        const gchar         *element_name,
                        gpointer             user_data,
                        GError             **error)
{
  --depth;
  indent (0);
  printf ("END '%s'\n", element_name);
}

static void
text_handler           (GMarkupParseContext *context,
                        const gchar         *text,
                        gsize                text_len,
                        gpointer             user_data,
                        GError             **error)
{
  indent (0);
  printf ("TEXT '%.*s'\n", (int)text_len, text);
}


static void
passthrough_handler    (GMarkupParseContext *context,
                        const gchar         *passthrough_text,
                        gsize                text_len,
                        gpointer             user_data,
                        GError             **error)
{
  indent (0);

  printf ("PASS '%.*s'\n", (int)text_len, passthrough_text);
}

static void
error_handler          (GMarkupParseContext *context,
                        GError              *error,
                        gpointer             user_data)
{
  fprintf (stderr, " %s\n", error->message);
}

static GMarkupParser parser = {
  start_element_handler,
  end_element_handler,
  text_handler,
  passthrough_handler,
  error_handler
};

static int
test_in_chunks (const gchar *contents,
                gint         length,
                gint         chunk_size)
{
  GMarkupParseContext *context;
  int i = 0;
  
  context = g_markup_parse_context_new (&parser, 0, NULL, NULL);

  while (i < length)
    {
      int this_chunk = MIN (length - i, chunk_size);

      if (!g_markup_parse_context_parse (context,
                                         contents + i,
                                         this_chunk,
                                         NULL))
        {
          g_markup_parse_context_free (context);
          return 1;
        }

      i += this_chunk;
    }
      
  if (!g_markup_parse_context_end_parse (context, NULL))
    {
      g_markup_parse_context_free (context);
      return 1;
    }

  g_markup_parse_context_free (context);

  return 0;
}

static int
test_file (const gchar *filename)
{
  gchar *contents;
  gsize  length;
  GError *error;
  GMarkupParseContext *context;
  
  error = NULL;
  if (!g_file_get_contents (filename,
                            &contents,
                            &length,
                            &error))
    {
      fprintf (stderr, "%s\n", error->message);
      g_error_free (error);
      return 1;
    }

  context = g_markup_parse_context_new (&parser, 0, NULL, NULL);

  if (!g_markup_parse_context_parse (context, contents, length, NULL))
    {
      g_markup_parse_context_free (context);
      return 1;
    }

  if (!g_markup_parse_context_end_parse (context, NULL))
    {
      g_markup_parse_context_free (context);
      return 1;
    }

  g_markup_parse_context_free (context);

  /* A byte at a time */
  if (test_in_chunks (contents, length, 1) != 0)
    return 1;

  /* 2 bytes */
  if (test_in_chunks (contents, length, 2) != 0)
    return 1;

  /*5 bytes */
  if (test_in_chunks (contents, length, 5) != 0)
    return 1;
  
  /* 12 bytes */
  if (test_in_chunks (contents, length, 12) != 0)
    return 1;
  
  /* 1024 bytes */
  if (test_in_chunks (contents, length, 1024) != 0)
    return 1;

  return 0;
}

int
main (int   argc,
      char *argv[])
{
  if (argc > 1)
    return test_file (argv[1]);
  else
    {
      fprintf (stderr, "Give a markup file on the command line\n");
      return 1;
    }
}

