/*
 * This file was generated automatically by ExtUtils::ParseXS version 3.22 from the
 * contents of GOption.xs. Do not edit this file, edit GOption.xs instead.
 *
 *    ANY CHANGES MADE HERE WILL BE LOST!
 *
 */

#line 1 "GOption.xs"
/*
 * Copyright (c) 2005-2009, 2013 by the gtk2-perl team (see the file AUTHORS)
 *
 * Licensed under the LGPL, see LICENSE file for more information.
 *
 * $Id$
 */

#include "gperl.h"
#include "gperl-gtypes.h"

/* ------------------------------------------------------------------------- */

/* This hash table is used to store option groups that have been handed to
 * GOptionContext.
 */
static GHashTable *transferred_groups = NULL;

static GOptionGroup *
gperl_option_group_transfer (GOptionGroup *group)
{
	if (!transferred_groups)
		transferred_groups =
			g_hash_table_new (g_direct_hash, g_direct_equal);

	g_hash_table_insert (transferred_groups, group, group);

	return group;
}

/* ------------------------------------------------------------------------- */

/* Define custom types for GOptionContext, GOptionGroup, GOptionFlags, and
 * GOptionArg since glib doesn't provide them.
 */

static gpointer
no_copy_for_you (gpointer boxed)
{
	croak ("copying Glib::OptionContext and Glib::OptionGroup isn't supported");
	return boxed;
}

/* glib assumes ownership of option groups it gets, and there's no copy
 * function.  So we need a custom free function here that checks if the group
 * was transferred to glib already before freeing it.
 */
static void
gperl_option_group_free (GOptionGroup *group)
{
	if (!g_hash_table_lookup (transferred_groups, group))
		g_option_group_free (group);
}

GType
gperl_option_context_get_type (void)
{
	static GType t = 0;
	if (!t)
		t = g_boxed_type_register_static ("GOptionContext",
		      (GBoxedCopyFunc) no_copy_for_you,
		      (GBoxedFreeFunc) g_option_context_free);
	return t;
}

GType
gperl_option_group_get_type (void)
{
	static GType t = 0;
	if (!t)
		t = g_boxed_type_register_static ("GOptionGroup",
		      (GBoxedCopyFunc) no_copy_for_you,
		      (GBoxedFreeFunc) gperl_option_group_free);
	return t;
}

/* ------------------------------------------------------------------------- */

#if 0
static SV *
newSVGOptionFlags (GOptionFlags flags)
{
	return gperl_convert_back_flags (GPERL_TYPE_OPTION_FLAGS, flags);
}
#endif

static GOptionFlags
SvGOptionFlags (SV *sv)
{
	return gperl_convert_flags (GPERL_TYPE_OPTION_FLAGS, sv);
}

/* ------------------------------------------------------------------------- */

#if 0
static SV *
newSVGOptionArg (GOptionArg arg)
{
	return gperl_convert_back_enum (GPERL_TYPE_OPTION_ARG, arg);
}
#endif

static GOptionArg
SvGOptionArg (SV *sv)
{
	return gperl_convert_enum (GPERL_TYPE_OPTION_ARG, sv);
}

/* ------------------------------------------------------------------------- */

typedef struct {
	GOptionArg arg;
	gpointer   arg_data;
} GPerlArgInfo;

static GPerlArgInfo *
gperl_arg_info_new (GOptionArg arg, gpointer arg_data)
{
	GPerlArgInfo *info = g_new0 (GPerlArgInfo, 1);
	info->arg = arg;
	info->arg_data = arg_data;
	return info;
}

static void
gperl_arg_info_destroy (GPerlArgInfo *info)
{
	g_free (info->arg_data); /* NULL-safe */
	g_free (info);
}

typedef struct {
	GHashTable *scalar_to_info;
	GSList *allocated_strings;
} GPerlArgInfoTable;

static GPerlArgInfoTable *
gperl_arg_info_table_new (void)
{
	GPerlArgInfoTable *table = g_new0 (GPerlArgInfoTable, 1);
	table->scalar_to_info =
		g_hash_table_new_full (g_direct_hash,
				       g_direct_equal,
				       NULL,
		      (GDestroyNotify) gperl_arg_info_destroy);
	table->allocated_strings = NULL;
	return table;
}

static void
gperl_arg_info_table_destroy (GPerlArgInfoTable *table)
{
	g_hash_table_destroy (table->scalar_to_info);

	/* These are NULL-safe. */
	g_slist_foreach (table->allocated_strings, (GFunc) g_free, NULL);
	g_slist_free (table->allocated_strings);

	g_free (table);
}

/* ------------------------------------------------------------------------- */

#define INSTALL_POINTER(type)						\
{									\
	type *pointer = g_new0 (type, 1);				\
	g_hash_table_insert (scalar_to_info, 				\
			     ref,					\
			     gperl_arg_info_new (entry->arg, pointer));	\
	entry->arg_data = pointer;					\
}

static void
handle_arg_data (GOptionEntry *entry, SV *ref, GHashTable *scalar_to_info)
{
	if (!gperl_sv_is_ref (ref))
		croak ("encountered non-reference variable for the arg_value "
		       "field");

	switch (entry->arg) {
	    case G_OPTION_ARG_NONE:
		INSTALL_POINTER (gboolean);
		break;

	    case G_OPTION_ARG_STRING:
	    case G_OPTION_ARG_FILENAME:
	        INSTALL_POINTER (gchar *);
		break;

	    case G_OPTION_ARG_INT:
	        INSTALL_POINTER (gint);
		break;

	    case G_OPTION_ARG_CALLBACK:
		croak ("unhandled arg type G_OPTION_ARG_CALLBACK encountered");
		break;

	    case G_OPTION_ARG_STRING_ARRAY:
	    case G_OPTION_ARG_FILENAME_ARRAY:
	        INSTALL_POINTER (gchar **);
		break;

#if GLIB_CHECK_VERSION (2, 12, 0)
	    case G_OPTION_ARG_DOUBLE:
	        INSTALL_POINTER (gdouble);
		break;

	    case G_OPTION_ARG_INT64:
	        INSTALL_POINTER (gint64);
		break;
#endif
	}
}

static gchar *
copy_string (gchar *src, GPerlArgInfoTable *table)
{
	gchar *result;
	if (!src)
		return NULL;
	result = g_strdup (src);
	table->allocated_strings =
		g_slist_prepend (table->allocated_strings, result);
	return result;
}

static GOptionEntry *
sv_to_option_entry (SV *sv, GPerlArgInfoTable *table)
{
	SV *long_name = NULL,
	   *short_name = NULL,
	   *flags = NULL,
	   *description = NULL,
	   *arg_description = NULL,
	   *arg_type = NULL,
	   *arg_value = NULL;
	GOptionEntry *entry;

	if (!gperl_sv_is_hash_ref (sv) && !gperl_sv_is_array_ref (sv))
		croak ("an option entry must be either a hash or an array "
		       "reference");

	if (gperl_sv_is_hash_ref (sv)) {
		HV *hv = (HV *) SvRV (sv);
		SV **value;

		value = hv_fetch (hv, "long_name", 9, 0);
		if (value) long_name = *value;

		value = hv_fetch (hv, "short_name", 10, 0);
		if (value) short_name = *value;

		value = hv_fetch (hv, "flags", 5, 0);
		if (value) flags = *value;

		value = hv_fetch (hv, "description", 11, 0);
		if (value) description = *value;

		value = hv_fetch (hv, "arg_description", 15, 0);
		if (value) arg_description = *value;

		value = hv_fetch (hv, "arg_type", 8, 0);
		if (value) arg_type = *value;

		value = hv_fetch (hv, "arg_value", 9, 0);
		if (value) arg_value = *value;
	} else {
		AV *av = (AV *) SvRV (sv);
		SV **value;

		if (4 != av_len (av) + 1)
			croak ("an option entry array reference must contain "
			       "four values: long_name, short_name, arg_type, "
			       "and arg_value");

		value = av_fetch (av, 0, 0);
		if (value) long_name = *value;

		value = av_fetch (av, 1, 0);
		if (value) short_name = *value;

		value = av_fetch (av, 2, 0);
		if (value) arg_type = *value;

		value = av_fetch (av, 3, 0);
		if (value) arg_value = *value;
	}

	if (!gperl_sv_is_defined (long_name) ||
	    !gperl_sv_is_defined (arg_type) ||
	    !gperl_sv_is_defined (arg_value))
		croak ("in an option entry, the fields long_name, arg_type, and "
		       "arg_value must be specified");

	entry = gperl_alloc_temp (sizeof (GOptionEntry));

	entry->long_name       = copy_string (SvGChar (long_name), table);
	entry->arg             = SvGOptionArg (arg_type);
	entry->arg_data        = NULL;
	handle_arg_data (entry, arg_value, table->scalar_to_info);

	entry->short_name      = gperl_sv_is_defined (short_name)
	                       ? (SvGChar (short_name))[0]
	                       : 0;
	entry->flags           = gperl_sv_is_defined (flags)
	                       ? SvGOptionFlags (flags)
                               : 0;
	entry->description     = gperl_sv_is_defined (description)
	                       ? copy_string (SvGChar (description), table)
	                       : NULL;
	entry->arg_description = gperl_sv_is_defined (arg_description)
	                       ? copy_string (SvGChar (arg_description), table)
	                       : NULL;

	return entry;
}

static GOptionEntry *
sv_to_option_entries (SV *sv, GPerlArgInfoTable *table)
{
	GOptionEntry *entries;
	AV *av;
	int length, i;
	SV **value;

	if (!gperl_sv_is_array_ref (sv))
		croak ("option entries must be an array reference containing hash references");

	av = (AV *) SvRV (sv);
	length = av_len (av) + 1;

	/* Allocating length + 1 entries here because the list is supposed to
	 * be NULL-terminated. */
	entries = gperl_alloc_temp (sizeof (GOptionEntry) * (length + 1));

	for (i = 0; i < length; i++) {
		value = av_fetch (av, i, 0);
		if (value && gperl_sv_is_defined (*value))
			entries[i] = *(sv_to_option_entry (*value, table));
	}

	return entries;
}

/* ------------------------------------------------------------------------- */

static gchar **
strings_from_sv (SV *sv)
{
	AV *av;
	gint n_strings, i;
	gchar **result;

	if (!gperl_sv_is_array_ref (sv))
		return NULL;

	av = (AV *) SvRV (sv);
	n_strings = av_len (av) + 1;
	if (n_strings <= 0)
		return NULL;

	/* NULL-terminated */
	result = gperl_alloc_temp (sizeof (gchar *) * (n_strings + 1));
	for (i = 0; i < n_strings; i++) {
		SV **string_sv = av_fetch (av, i, 0);
		result[i] = string_sv ? SvGChar (*string_sv) : NULL;
	}

	return result;
}

static gchar **
filenames_from_sv (SV *sv)
{
	AV *av;
	gint n_filenames, i;
	gchar **result;

	if (!gperl_sv_is_array_ref (sv))
		return NULL;

	av = (AV *) SvRV (sv);
	n_filenames = av_len (av) + 1;
	if (n_filenames <= 0)
		return NULL;

	/* NULL-terminated */
	result = gperl_alloc_temp (sizeof (gchar *) * (n_filenames + 1));
	for (i = 0; i < n_filenames; i++) {
		SV **string_sv = av_fetch (av, i, 0);
		result[i] = string_sv ? SvPV_nolen (*string_sv) : NULL;
	}

	return result;
}

#define INITIALIZE_POINTER(type, converter)			\
{								\
	SV *sv = SvRV (ref);					\
	if (gperl_sv_is_defined (sv))				\
		*((type *) info->arg_data) = converter (sv);	\
}

static void
initialize_scalar (gpointer key,
		   gpointer value,
		   gpointer data)
{
	SV *ref = key;
	GPerlArgInfo *info = value;
	PERL_UNUSED_VAR (data);

	switch (info->arg) {
	    case G_OPTION_ARG_NONE:
		INITIALIZE_POINTER (gboolean, sv_2bool);
		break;

	    case G_OPTION_ARG_STRING:
		INITIALIZE_POINTER (gchar *, SvGChar);
		break;

	    case G_OPTION_ARG_INT:
		INITIALIZE_POINTER (gint, SvIV);
		break;

	    case G_OPTION_ARG_CALLBACK:
		croak ("unhandled arg type G_OPTION_ARG_CALLBACK encountered");
		break;

	    case G_OPTION_ARG_FILENAME:
		/* FIXME: Is this the correct converter? */
		INITIALIZE_POINTER (gchar *, SvPV_nolen);
		break;

	    case G_OPTION_ARG_STRING_ARRAY:
		INITIALIZE_POINTER (gchar **, strings_from_sv);
		break;

	    case G_OPTION_ARG_FILENAME_ARRAY:
		INITIALIZE_POINTER (gchar **, filenames_from_sv);
		break;

#if GLIB_CHECK_VERSION (2, 12, 0)
	    case G_OPTION_ARG_DOUBLE:
		INITIALIZE_POINTER (gdouble, SvNV);
		break;

	    case G_OPTION_ARG_INT64:
		INITIALIZE_POINTER (gint64, SvGInt64);
		break;
#endif
	}
}

static gboolean
initialize_scalars (GOptionContext *context,
		    GOptionGroup *group,
		    gpointer data,
		    GError **error)
{
	GPerlArgInfoTable *table = data;
	PERL_UNUSED_VAR (context);
	PERL_UNUSED_VAR (group);
	PERL_UNUSED_VAR (error);
	g_hash_table_foreach (table->scalar_to_info, initialize_scalar, NULL);
	return TRUE;
}

/* ------------------------------------------------------------------------- */

static SV *
sv_from_strings (gchar **strings)
{
	AV *av;
	gint i;

	if (!strings)
		return &PL_sv_undef;

	av = newAV ();
	for (i = 0; strings[i] != NULL; i++) {
		av_push (av, newSVGChar (strings[i]));
	}

	return newRV_noinc ((SV *) av);
}

static SV *
sv_from_filenames (gchar **filenames)
{
	AV *av;
	gint i;

	if (!filenames)
		return &PL_sv_undef;

	av = newAV ();
	for (i = 0; filenames[i] != NULL; i++) {
		/* FIXME: Is this the correct converter? */
		av_push (av, newSVpv (filenames[i], 0));
	}

	return newRV_noinc ((SV *) av);
}

#define READ_POINTER(type) (*((type *) info->arg_data))

static void
fill_in_scalar (gpointer key,
	        gpointer value,
		gpointer data)
{
	SV *ref = key;
	GPerlArgInfo *info = value;
	SV *sv = SvRV (ref);
	PERL_UNUSED_VAR (data);

	switch (info->arg) {
	    case G_OPTION_ARG_NONE:
		sv_setsv (sv, boolSV (READ_POINTER (gboolean)));
		break;

	    case G_OPTION_ARG_STRING:
		sv_setpv (sv, READ_POINTER (gchar *));
		SvUTF8_on (sv);
		break;

	    case G_OPTION_ARG_INT:
	        sv_setiv (sv, READ_POINTER (gint));
		break;

	    case G_OPTION_ARG_CALLBACK:
		croak ("unhandled arg type G_OPTION_ARG_CALLBACK encountered");
		break;

	    case G_OPTION_ARG_FILENAME:
		/* FIXME: Is this the correct converter? */
		sv_setpv (sv, READ_POINTER (gchar *));
		break;

	    case G_OPTION_ARG_STRING_ARRAY:
		sv_setsv (sv, sv_from_strings (READ_POINTER (gchar **)));
		break;

	    case G_OPTION_ARG_FILENAME_ARRAY:
		sv_setsv (sv, sv_from_filenames (READ_POINTER (gchar **)));
		break;

#if GLIB_CHECK_VERSION (2, 12, 0)
	    case G_OPTION_ARG_DOUBLE:
	        sv_setnv (sv, READ_POINTER (gdouble));
		break;

	    case G_OPTION_ARG_INT64:
		sv_setsv (sv, newSVGInt64 (READ_POINTER (gint64)));
		break;
#endif
	}
}

static gboolean
fill_in_scalars (GOptionContext *context,
		 GOptionGroup *group,
		 gpointer data,
		 GError **error)
{
	GPerlArgInfoTable *table = data;
	PERL_UNUSED_VAR (context);
	PERL_UNUSED_VAR (group);
	PERL_UNUSED_VAR (error);
	g_hash_table_foreach (table->scalar_to_info, fill_in_scalar, NULL);
	return TRUE;
}

/* ------------------------------------------------------------------------- */

static GPerlCallback *
gperl_translate_func_create (SV *func, SV *data)
{
	GType param_types [1];
	param_types[0] = G_TYPE_STRING;
	return gperl_callback_new (func, data, G_N_ELEMENTS (param_types),
				   param_types, G_TYPE_STRING);
}

static const gchar *
gperl_translate_func (const gchar *str, gpointer data)
{
	GPerlCallback *callback = (GPerlCallback *) data;
	GValue value = {0,};
	const gchar *retval;

	/* FIXME: This leaks but I've no idea how to make sure the string
         * survives. */
	g_value_init (&value, callback->return_type);
	gperl_callback_invoke (callback, &value, str);
	retval = g_value_dup_string (&value);
	g_value_unset (&value);

	return retval;
}

/* ------------------------------------------------------------------------- */

#line 615 "GOption.c"
#ifndef PERL_UNUSED_VAR
#  define PERL_UNUSED_VAR(var) if (0) var = var
#endif

#ifndef dVAR
#  define dVAR		dNOOP
#endif


/* This stuff is not part of the API! You have been warned. */
#ifndef PERL_VERSION_DECIMAL
#  define PERL_VERSION_DECIMAL(r,v,s) (r*1000000 + v*1000 + s)
#endif
#ifndef PERL_DECIMAL_VERSION
#  define PERL_DECIMAL_VERSION \
	  PERL_VERSION_DECIMAL(PERL_REVISION,PERL_VERSION,PERL_SUBVERSION)
#endif
#ifndef PERL_VERSION_GE
#  define PERL_VERSION_GE(r,v,s) \
	  (PERL_DECIMAL_VERSION >= PERL_VERSION_DECIMAL(r,v,s))
#endif
#ifndef PERL_VERSION_LE
#  define PERL_VERSION_LE(r,v,s) \
	  (PERL_DECIMAL_VERSION <= PERL_VERSION_DECIMAL(r,v,s))
#endif

/* XS_INTERNAL is the explicit static-linkage variant of the default
 * XS macro.
 *
 * XS_EXTERNAL is the same as XS_INTERNAL except it does not include
 * "STATIC", ie. it exports XSUB symbols. You probably don't want that
 * for anything but the BOOT XSUB.
 *
 * See XSUB.h in core!
 */


/* TODO: This might be compatible further back than 5.10.0. */
#if PERL_VERSION_GE(5, 10, 0) && PERL_VERSION_LE(5, 15, 1)
#  undef XS_EXTERNAL
#  undef XS_INTERNAL
#  if defined(__CYGWIN__) && defined(USE_DYNAMIC_LOADING)
#    define XS_EXTERNAL(name) __declspec(dllexport) XSPROTO(name)
#    define XS_INTERNAL(name) STATIC XSPROTO(name)
#  endif
#  if defined(__SYMBIAN32__)
#    define XS_EXTERNAL(name) EXPORT_C XSPROTO(name)
#    define XS_INTERNAL(name) EXPORT_C STATIC XSPROTO(name)
#  endif
#  ifndef XS_EXTERNAL
#    if defined(HASATTRIBUTE_UNUSED) && !defined(__cplusplus)
#      define XS_EXTERNAL(name) void name(pTHX_ CV* cv __attribute__unused__)
#      define XS_INTERNAL(name) STATIC void name(pTHX_ CV* cv __attribute__unused__)
#    else
#      ifdef __cplusplus
#        define XS_EXTERNAL(name) extern "C" XSPROTO(name)
#        define XS_INTERNAL(name) static XSPROTO(name)
#      else
#        define XS_EXTERNAL(name) XSPROTO(name)
#        define XS_INTERNAL(name) STATIC XSPROTO(name)
#      endif
#    endif
#  endif
#endif

/* perl >= 5.10.0 && perl <= 5.15.1 */


/* The XS_EXTERNAL macro is used for functions that must not be static
 * like the boot XSUB of a module. If perl didn't have an XS_EXTERNAL
 * macro defined, the best we can do is assume XS is the same.
 * Dito for XS_INTERNAL.
 */
#ifndef XS_EXTERNAL
#  define XS_EXTERNAL(name) XS(name)
#endif
#ifndef XS_INTERNAL
#  define XS_INTERNAL(name) XS(name)
#endif

/* Now, finally, after all this mess, we want an ExtUtils::ParseXS
 * internal macro that we're free to redefine for varying linkage due
 * to the EXPORT_XSUB_SYMBOLS XS keyword. This is internal, use
 * XS_EXTERNAL(name) or XS_INTERNAL(name) in your code if you need to!
 */

#undef XS_EUPXS
#if defined(PERL_EUPXS_ALWAYS_EXPORT)
#  define XS_EUPXS(name) XS_EXTERNAL(name)
#else
   /* default to internal */
#  define XS_EUPXS(name) XS_INTERNAL(name)
#endif

#ifndef PERL_ARGS_ASSERT_CROAK_XS_USAGE
#define PERL_ARGS_ASSERT_CROAK_XS_USAGE assert(cv); assert(params)

/* prototype to pass -Wmissing-prototypes */
STATIC void
S_croak_xs_usage(pTHX_ const CV *const cv, const char *const params);

STATIC void
S_croak_xs_usage(pTHX_ const CV *const cv, const char *const params)
{
    const GV *const gv = CvGV(cv);

    PERL_ARGS_ASSERT_CROAK_XS_USAGE;

    if (gv) {
        const char *const gvname = GvNAME(gv);
        const HV *const stash = GvSTASH(gv);
        const char *const hvname = stash ? HvNAME(stash) : NULL;

        if (hvname)
            Perl_croak(aTHX_ "Usage: %s::%s(%s)", hvname, gvname, params);
        else
            Perl_croak(aTHX_ "Usage: %s(%s)", gvname, params);
    } else {
        /* Pants. I don't think that it should be possible to get here. */
        Perl_croak(aTHX_ "Usage: CODE(0x%"UVxf")(%s)", PTR2UV(cv), params);
    }
}
#undef  PERL_ARGS_ASSERT_CROAK_XS_USAGE

#ifdef PERL_IMPLICIT_CONTEXT
#define croak_xs_usage(a,b)    S_croak_xs_usage(aTHX_ a,b)
#else
#define croak_xs_usage        S_croak_xs_usage
#endif

#endif

/* NOTE: the prototype of newXSproto() is different in versions of perls,
 * so we define a portable version of newXSproto()
 */
#ifdef newXS_flags
#define newXSproto_portable(name, c_impl, file, proto) newXS_flags(name, c_impl, file, proto, 0)
#else
#define newXSproto_portable(name, c_impl, file, proto) (PL_Sv=(SV*)newXS(name, c_impl, file), sv_setpv(PL_Sv, proto), (CV*)PL_Sv)
#endif /* !defined(newXS_flags) */

#line 757 "GOption.c"

XS_EUPXS(XS_Glib__OptionContext_new); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Glib__OptionContext_new)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "class, parameter_string");
    {
	const gchar *	parameter_string;
	GOptionContext_own *	RETVAL;

	/* same as SvGChar(), but not in a function */
	sv_utf8_upgrade (ST(1));
	parameter_string = (const gchar *)SvPV_nolen (ST(1))
;

	RETVAL = g_option_context_new(parameter_string);
	ST(0) = newSVGOptionContext_own (RETVAL);
	sv_2mortal(ST(0));
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Glib__OptionContext_set_help_enabled); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Glib__OptionContext_set_help_enabled)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "context, help_enabled");
    {
	GOptionContext *	context = SvGOptionContext (ST(0))
;
	gboolean	help_enabled = (bool)SvTRUE(ST(1))
;

	g_option_context_set_help_enabled(context, help_enabled);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_Glib__OptionContext_get_help_enabled); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Glib__OptionContext_get_help_enabled)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "context");
    {
	gboolean	RETVAL;
	GOptionContext *	context = SvGOptionContext (ST(0))
;

	RETVAL = g_option_context_get_help_enabled(context);
	ST(0) = boolSV(RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Glib__OptionContext_set_ignore_unknown_options); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Glib__OptionContext_set_ignore_unknown_options)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "context, ignore_unknown");
    {
	GOptionContext *	context = SvGOptionContext (ST(0))
;
	gboolean	ignore_unknown = (bool)SvTRUE(ST(1))
;

	g_option_context_set_ignore_unknown_options(context, ignore_unknown);
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_Glib__OptionContext_get_ignore_unknown_options); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Glib__OptionContext_get_ignore_unknown_options)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "context");
    {
	gboolean	RETVAL;
	GOptionContext *	context = SvGOptionContext (ST(0))
;

	RETVAL = g_option_context_get_ignore_unknown_options(context);
	ST(0) = boolSV(RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Glib__OptionContext_add_main_entries); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Glib__OptionContext_add_main_entries)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "context, entries, translation_domain");
    {
#line 667 "GOption.xs"
	GPerlArgInfoTable *table;
	GOptionGroup *group;
	GOptionEntry *real_entries;
#line 865 "GOption.c"
	GOptionContext *	context = SvGOptionContext (ST(0))
;
	SV *	entries = ST(1)
;
	const gchar *	translation_domain;

	/* same as SvGChar(), but not in a function */
	sv_utf8_upgrade (ST(2));
	translation_domain = (const gchar *)SvPV_nolen (ST(2))
;
#line 671 "GOption.xs"
	table = gperl_arg_info_table_new ();
	group = g_option_group_new (NULL, NULL, NULL,
				    table,
		   (GDestroyNotify) gperl_arg_info_table_destroy);
	g_option_group_set_parse_hooks (group, initialize_scalars,
	                                fill_in_scalars);

	real_entries = sv_to_option_entries (entries, table);
	if (real_entries)
		g_option_group_add_entries (group, real_entries);
	g_option_group_set_translation_domain (group, translation_domain);

	/* context assumes ownership of group */
	g_option_context_set_main_group (context, group);
#line 891 "GOption.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_Glib__OptionContext_parse); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Glib__OptionContext_parse)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "context");
    {
	GOptionContext *	context = SvGOptionContext (ST(0))
;
#line 694 "GOption.xs"
	GPerlArgv *pargv;
	GError *error = NULL;
#line 909 "GOption.c"
	gboolean	RETVAL;
#line 697 "GOption.xs"
	pargv = gperl_argv_new ();
	RETVAL = g_option_context_parse (context, &pargv->argc, &pargv->argv, &error);

	if (error) {
		gperl_argv_free (pargv);
		gperl_croak_gerror (NULL, error);
	}

	gperl_argv_update (pargv);
	gperl_argv_free (pargv);
#line 922 "GOption.c"
	ST(0) = boolSV(RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Glib__OptionContext_add_group); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Glib__OptionContext_add_group)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "context, group");
    {
	GOptionContext *	context = SvGOptionContext (ST(0))
;
	GOptionGroup *	group = SvGOptionGroup (ST(1))
;

	g_option_context_add_group(context, gperl_option_group_transfer (group));
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_Glib__OptionContext_set_main_group); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Glib__OptionContext_set_main_group)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "context, group");
    {
	GOptionContext *	context = SvGOptionContext (ST(0))
;
	GOptionGroup *	group = SvGOptionGroup (ST(1))
;

	g_option_context_set_main_group(context, gperl_option_group_transfer (group));
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_Glib__OptionContext_get_main_group); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Glib__OptionContext_get_main_group)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "context");
    {
	GOptionGroup *	RETVAL;
	GOptionContext *	context = SvGOptionContext (ST(0))
;

	RETVAL = g_option_context_get_main_group(context);
	ST(0) = newSVGOptionGroup (RETVAL);
	sv_2mortal(ST(0));
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Glib__OptionGroup_new); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Glib__OptionGroup_new)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "class, ...");
    {
#line 791 "GOption.xs"
	int i;
	gchar *name = NULL;
	gchar *description = NULL;
	gchar *help_description = NULL;
	SV *entries = NULL;
	GPerlArgInfoTable *table;
	GOptionEntry *real_entries = NULL;
#line 999 "GOption.c"
	GOptionGroup_own *	RETVAL;
#line 799 "GOption.xs"
	if ((items - 1) % 2 != 0)
		croak ("even number of arguments expected: key => value, ...");

	for (i = 1; i < items; i += 2) {
		char *key = SvPV_nolen (ST (i));
		SV *value = ST (i + 1);

		if (strEQ (key, "name"))
			name = SvGChar (value);
		else if (strEQ (key, "description"))
			description = SvGChar (value);
		else if (strEQ (key, "help_description"))
			help_description = SvGChar (value);
		else if (strEQ (key, "entries"))
			entries = value;
		else
			warn ("unknown key `%s´ encountered; ignoring", key);
	}

	table = gperl_arg_info_table_new ();
	if (entries)
		real_entries = sv_to_option_entries (entries, table);

	RETVAL = g_option_group_new (name,
				     description,
				     help_description,
				     table,
		    (GDestroyNotify) gperl_arg_info_table_destroy);

	g_option_group_set_parse_hooks (RETVAL, initialize_scalars, fill_in_scalars);

	if (real_entries)
		g_option_group_add_entries (RETVAL, real_entries);
#line 1035 "GOption.c"
	ST(0) = newSVGOptionGroup_own (RETVAL);
	sv_2mortal(ST(0));
    }
    XSRETURN(1);
}


XS_EUPXS(XS_Glib__OptionGroup_set_translate_func); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Glib__OptionGroup_set_translate_func)
{
    dVAR; dXSARGS;
    if (items < 2 || items > 3)
       croak_xs_usage(cv,  "group, func, data=NULL");
    {
	GOptionGroup *	group = SvGOptionGroup (ST(0))
;
	SV *	func = ST(1)
;
	SV *	data;
#line 842 "GOption.xs"
	GPerlCallback *callback;
#line 1057 "GOption.c"

	if (items < 3)
	    data = NULL;
	else {
	    data = ST(2)
;
	}
#line 844 "GOption.xs"
	callback = gperl_translate_func_create (func, data);
	g_option_group_set_translate_func (group,
	                                   gperl_translate_func,
	                                   callback,
	                                   (GDestroyNotify)
	                                     gperl_callback_destroy);
#line 1072 "GOption.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_Glib__OptionGroup_set_translation_domain); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_Glib__OptionGroup_set_translation_domain)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "group, domain");
    {
	GOptionGroup *	group = SvGOptionGroup (ST(0))
;
	const gchar *	domain;

	/* same as SvGChar(), but not in a function */
	sv_utf8_upgrade (ST(1));
	domain = (const gchar *)SvPV_nolen (ST(1))
;

	g_option_group_set_translation_domain(group, domain);
    }
    XSRETURN_EMPTY;
}

#ifdef __cplusplus
extern "C"
#endif
XS_EXTERNAL(boot_Glib__Option); /* prototype to pass -Wmissing-prototypes */
XS_EXTERNAL(boot_Glib__Option)
{
    dVAR; dXSARGS;
#if (PERL_REVISION == 5 && PERL_VERSION < 9)
    char* file = __FILE__;
#else
    const char* file = __FILE__;
#endif

    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
#ifdef XS_APIVERSION_BOOTCHECK
    XS_APIVERSION_BOOTCHECK;
#endif
    XS_VERSION_BOOTCHECK;

        newXS("Glib::OptionContext::new", XS_Glib__OptionContext_new, file);
        newXS("Glib::OptionContext::set_help_enabled", XS_Glib__OptionContext_set_help_enabled, file);
        newXS("Glib::OptionContext::get_help_enabled", XS_Glib__OptionContext_get_help_enabled, file);
        newXS("Glib::OptionContext::set_ignore_unknown_options", XS_Glib__OptionContext_set_ignore_unknown_options, file);
        newXS("Glib::OptionContext::get_ignore_unknown_options", XS_Glib__OptionContext_get_ignore_unknown_options, file);
        newXS("Glib::OptionContext::add_main_entries", XS_Glib__OptionContext_add_main_entries, file);
        newXS("Glib::OptionContext::parse", XS_Glib__OptionContext_parse, file);
        newXS("Glib::OptionContext::add_group", XS_Glib__OptionContext_add_group, file);
        newXS("Glib::OptionContext::set_main_group", XS_Glib__OptionContext_set_main_group, file);
        newXS("Glib::OptionContext::get_main_group", XS_Glib__OptionContext_get_main_group, file);
        newXS("Glib::OptionGroup::new", XS_Glib__OptionGroup_new, file);
        newXS("Glib::OptionGroup::set_translate_func", XS_Glib__OptionGroup_set_translate_func, file);
        newXS("Glib::OptionGroup::set_translation_domain", XS_Glib__OptionGroup_set_translation_domain, file);

    /* Initialisation Section */

#line 608 "GOption.xs"
	gperl_register_boxed (GPERL_TYPE_OPTION_CONTEXT, "Glib::OptionContext", NULL);
	gperl_register_boxed (GPERL_TYPE_OPTION_GROUP, "Glib::OptionGroup", NULL);
	gperl_register_fundamental (GPERL_TYPE_OPTION_ARG, "Glib::OptionArg");
	gperl_register_fundamental (GPERL_TYPE_OPTION_FLAGS, "Glib::OptionFlags");

#line 1141 "GOption.c"

    /* End of Initialisation Section */

#if (PERL_REVISION == 5 && PERL_VERSION >= 9)
  if (PL_unitcheckav)
       call_list(PL_scopestack_ix, PL_unitcheckav);
#endif
    XSRETURN_YES;
}

