/* Bug: GOption: A short option's value is included in G_OPTION_REMAINING
 *
 * Test case. Try
 * ./testcase    --number 4 --text=hello file1 file2
 * ./testcase -r --number 4 --text=hello file1 file2
 * ./testcase    -n 4 -t hello file1 file2
 * ./testcase -r -n 4 -t hello file1 file2
 * ./testcase -i  --number 4 --text=hello file1 file2
 * ./testcase -ri --number 4 --text=hello file1 file2
 * ./testcase -i  -n 4 -t hello file1 file2
 * ./testcase -ri -n 4 -t hello file1 file2
 *
 * The result shall be one of
 *   ignore=x:x, remaining=0:0, number=4, text=hello, files=, argv= ./testcase file1 file2
 *   ignore=x:x, remaining=1:1, number=4, text=hello, files= file1 file2, argv= ./testcase
 * where x=0 or x=1.
 *
 * The following result is wrong
 *   ignore=1:1, remaining=1:1, number=4, text=hello, files= 4 hello file1 file2, argv= ./testcase
 */

#include <glib.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[])
{
  gboolean ignore1 = FALSE;
  gboolean ignore2 = FALSE;
  gboolean remaining1 = FALSE;
  gboolean remaining2 = FALSE;
  int number = 0;
  gchar* text = NULL;
  gchar** files = NULL;
  GError* error = NULL;
  int i;

  GOptionEntry entries[] =
  {
    { "ignore", 'i', 0, G_OPTION_ARG_NONE, &ignore2, NULL, NULL },
    { "remaining", 'r', 0, G_OPTION_ARG_NONE, &remaining2, NULL, NULL },
    { "number", 'n', 0, G_OPTION_ARG_INT, &number, NULL, NULL },
    { "text", 't', 0, G_OPTION_ARG_STRING, &text, NULL, NULL },
    { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &files, NULL, NULL },
    { NULL }
  };

  GOptionContext* context;

  /* Before the calls to g_option_context_add_main_entries() and
   * g_option_context_parse(),
   * check if the first parameter is -i, -r, -ir, or -ri. */
  if (argc > 1 && strlen(argv[1]) > 1 && *argv[1] == '-' && *(argv[1] + 1) != '-')
  {
    if (strchr(argv[1], 'i'))
      ignore1 = TRUE;

    if (strchr(argv[1], 'r'))
      remaining1 = TRUE;
  }

  if (!remaining1)
    entries[4].long_name = NULL; /* Skip G_OPTION_REMAINING */

  context = g_option_context_new(NULL);
  g_option_context_add_main_entries(context, entries, NULL);

  g_option_context_set_ignore_unknown_options(context, ignore1);

  g_option_context_parse(context, &argc, &argv, &error);

  printf("ignore=%d:%d, remaining=%d:%d, number=%d, text=%s, files=",
    ignore1, ignore2, remaining1, remaining2, number, text ? text : "NULL");

  if (files)
    for (i = 0; files[i]; ++i)
      printf(" %s", files[i]);

  printf(", argv=");
  for (i = 0; argv[i]; ++i)
    printf(" %s", argv[i]);
  printf("\n");

  if (error)
  {
    printf("Error: %s\n", error->message);
    g_error_free(error);
  }

  g_free(text);
  g_strfreev(files);

  return EXIT_SUCCESS;
}
