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

#line 1 "GDBM_File.xs"
#define PERL_NO_GET_CONTEXT

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include <gdbm.h>
#include <fcntl.h>

#define fetch_key 0
#define store_key 1
#define fetch_value 2
#define store_value 3

typedef struct {
	GDBM_FILE 	dbp ;
	SV *    filter[4];
	int     filtering ;
	} GDBM_File_type;

typedef GDBM_File_type * GDBM_File ;
typedef datum datum_key ;
typedef datum datum_value ;
typedef datum datum_key_copy;

#if defined(GDBM_VERSION_MAJOR) && defined(GDBM_VERSION_MINOR) \
    && GDBM_VERSION_MAJOR > 1 || \
    (GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 9)
typedef void (*FATALFUNC)(const char *);
#else
typedef void (*FATALFUNC)();
#endif

#ifndef GDBM_FAST
static int
not_here(char *s)
{
    croak("GDBM_File::%s not implemented on this architecture", s);
    return -1;
}
#endif

/* GDBM allocates the datum with system malloc() and expects the user
 * to free() it.  So we either have to free() it immediately, or have
 * perl free() it when it deallocates the SV, depending on whether
 * perl uses malloc()/free() or not. */
static void
output_datum(pTHX_ SV *arg, char *str, int size)
{
	sv_setpvn(arg, str, size);
#	undef free
	free(str);
}

/* Versions of gdbm prior to 1.7x might not have the gdbm_sync,
   gdbm_exists, and gdbm_setopt functions.  Apparently Slackware
   (Linux) 2.1 contains gdbm-1.5 (which dates back to 1991).
*/
#ifndef GDBM_FAST
#define gdbm_exists(db,key) not_here("gdbm_exists")
#define gdbm_sync(db) (void) not_here("gdbm_sync")
#define gdbm_setopt(db,optflag,optval,optlen) not_here("gdbm_setopt")
#endif

static void
croak_string(const char *message) {
    Perl_croak_nocontext("%s", message);
}

#include "const-c.inc"

#line 82 "GDBM_File.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(const CV *const cv, const char *const params);

STATIC void
S_croak_xs_usage(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_nocontext("Usage: %s::%s(%s)", hvname, gvname, params);
        else
	    Perl_croak_nocontext("Usage: %s(%s)", gvname, params);
    } else {
        /* Pants. I don't think that it should be possible to get here. */
	Perl_croak_nocontext("Usage: CODE(0x%" UVxf ")(%s)", PTR2UV(cv), params);
    }
}
#undef  PERL_ARGS_ASSERT_CROAK_XS_USAGE

#define croak_xs_usage        S_croak_xs_usage

#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) */

#if PERL_VERSION_LE(5, 21, 5)
#  define newXS_deffile(a,b) Perl_newXS(aTHX_ a,b,file)
#else
#  define newXS_deffile(a,b) Perl_newXS_deffile(aTHX_ a,b)
#endif

#line 226 "GDBM_File.c"

/* INCLUDE:  Including 'const-xs.inc' from 'GDBM_File.xs' */


XS_EUPXS(XS_GDBM_File_AUTOLOAD); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_AUTOLOAD)
{
    dVAR; dXSARGS;
    if (items != 0)
       croak_xs_usage(cv,  "");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
#line 122 "./const-xs.inc"
	SV *sv = newSVpvn_flags(SvPVX(cv), SvCUR(cv), SVs_TEMP | SvUTF8(cv));
	const COP *cop = PL_curcop;
#line 243 "GDBM_File.c"
#line 125 "./const-xs.inc"
#ifndef SYMBIAN
	/* It's not obvious how to calculate this at C pre-processor time.
	   However, any compiler optimiser worth its salt should be able to
	   remove the dead code, and hopefully the now-obviously-unused static
	   function too.  */
	HV *constant_missing = (C_ARRAY_LENGTH(values_for_notfound) > 1)
	    ? get_missing_hash(aTHX) : NULL;
	if ((C_ARRAY_LENGTH(values_for_notfound) > 1)
	    ? hv_exists_ent(constant_missing, sv, 0) : 0) {
	    sv = newSVpvf("Your vendor has not defined GDBM_File macro %" SVf
			  ", used at %" COP_FILE_F " line %" UVuf "\n", 
			  sv, COP_FILE(cop), (UV)CopLINE(cop));
	} else
#endif
	{
	    sv = newSVpvf("%" SVf
                          " is not a valid GDBM_File macro at %"
			  COP_FILE_F " line %" UVuf "\n",
			  sv, COP_FILE(cop), (UV)CopLINE(cop));
	}
	croak_sv(sv_2mortal(sv));
#line 266 "GDBM_File.c"
	PUTBACK;
	return;
    }
}


/* INCLUDE: Returning to 'GDBM_File.xs' from 'const-xs.inc' */


XS_EUPXS(XS_GDBM_File_TIEHASH); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_TIEHASH)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "dbtype, name, read_write, mode");
    {
	char *	dbtype = (char *)SvPV_nolen(ST(0))
;
	char *	name = (char *)SvPV_nolen(ST(1))
;
	int	read_write = (int)SvIV(ST(2))
;
	int	mode = (int)SvIV(ST(3))
;
#line 83 "GDBM_File.xs"
	GDBM_FILE dbp;
#line 293 "GDBM_File.c"
	GDBM_File	RETVAL;
#line 85 "GDBM_File.xs"
	dbp = gdbm_open(name, 0, read_write, mode, (FATALFUNC)croak_string);
	if (!dbp && gdbm_errno == GDBM_BLOCK_SIZE_ERROR) {
	    /*
	     * By specifying a block size of 0 above, we asked gdbm to
	     * default to the filesystem's block size.	That's usually the
	     * right size to choose.  But some versions of gdbm require
	     * a power-of-two block size, and some unusual filesystems
	     * or devices have a non-power-of-two size that cause this
	     * defaulting to fail.  In that case, force an acceptable
	     * block size.
	     */
	    dbp = gdbm_open(name, 4096, read_write, mode,
		    (FATALFUNC)croak_string);
	}
	if (dbp) {
	    RETVAL = (GDBM_File)safecalloc(1, sizeof(GDBM_File_type));
	    RETVAL->dbp = dbp;
	} else {
	    RETVAL = NULL;
	}
#line 316 "GDBM_File.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, dbtype, (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}

#define gdbm_close(db)			gdbm_close(db->dbp)

XS_EUPXS(XS_GDBM_File_close); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_close)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "db");
    {
	GDBM_File	db;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GDBM_File")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    db = INT2PTR(GDBM_File,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"GDBM_File::close",
			"db", "GDBM_File")
;

	gdbm_close(db);
#line 113 "GDBM_File.xs"
#line 350 "GDBM_File.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_GDBM_File_DESTROY); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_DESTROY)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "db");
    {
	GDBM_File	db;
#line 119 "GDBM_File.xs"
	int i = store_value;
#line 366 "GDBM_File.c"

	if (SvROK(ST(0))) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    db = INT2PTR(GDBM_File,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not a reference",
			"GDBM_File::DESTROY",
			"db")
;
#line 121 "GDBM_File.xs"
	gdbm_close(db);
	do {
	    if (db->filter[i])
		SvREFCNT_dec(db->filter[i]);
	} while (i-- > 0);
	safefree(db);
#line 384 "GDBM_File.c"
    }
    XSRETURN_EMPTY;
}

#define gdbm_FETCH(db,key)			gdbm_fetch(db->dbp,key)

XS_EUPXS(XS_GDBM_File_FETCH); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_FETCH)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "db, key");
    {
	GDBM_File	db;
	datum_key_copy	key;
	datum_value	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GDBM_File")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    db = INT2PTR(GDBM_File,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"GDBM_File::FETCH",
			"db", "GDBM_File")
;

	DBM_ckFilter(ST(1), filter[store_key], "filter_store_key");
	{
	    STRLEN len;
	    key.dptr = SvPVbyte(ST(1), len);
	    key.dsize = (int)len;
	}
;

	RETVAL = gdbm_FETCH(db, key);
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    output_datum(aTHX_ RETVALSV, RETVAL.dptr, RETVAL.dsize);
	    DBM_ckFilter(RETVALSV, filter[fetch_value],"filter_fetch_value");
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}

#define gdbm_STORE(db,key,value,flags)		gdbm_store(db->dbp,key,value,flags)

XS_EUPXS(XS_GDBM_File_STORE); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_STORE)
{
    dVAR; dXSARGS;
    if (items < 3 || items > 4)
       croak_xs_usage(cv,  "db, key, value, flags = GDBM_REPLACE");
    {
	GDBM_File	db;
	datum_key	key;
	datum_value	value;
	int	flags;
	int	RETVAL;
	dXSTARG;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GDBM_File")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    db = INT2PTR(GDBM_File,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"GDBM_File::STORE",
			"db", "GDBM_File")
;

	DBM_ckFilter(ST(1), filter[store_key], "filter_store_key");
	{
	    STRLEN len;
	    key.dptr = SvPVbyte(ST(1), len);
	    key.dsize = (int)len;
	}
;

        DBM_ckFilter(ST(2), filter[store_value], "filter_store_value");
	if (SvOK(ST(2))) {
	    STRLEN len;
	    value.dptr = SvPVbyte(ST(2), len);
	    value.dsize = (int)len;
	}
	else {
	    value.dptr = (char *)"";
	    /* better would be for .dptr to be const char * */
	    value.dsize = 0;
	}
;

	if (items < 4)
	    flags = GDBM_REPLACE;
	else {
	    flags = (int)SvIV(ST(3))
;
	}

	RETVAL = gdbm_STORE(db, key, value, flags);
	XSprePUSH; PUSHi((IV)RETVAL);
#line 142 "GDBM_File.xs"
	if (RETVAL) {
	    if (RETVAL < 0 && errno == EPERM)
		croak("No write permission to gdbm file");
	    croak("gdbm store returned %d, errno %d, key \"%.*s\"",
			RETVAL,errno,key.dsize,key.dptr);
	}
#line 495 "GDBM_File.c"
    }
    XSRETURN(1);
}

#define gdbm_DELETE(db,key)			gdbm_delete(db->dbp,key)

XS_EUPXS(XS_GDBM_File_DELETE); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_DELETE)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "db, key");
    {
	GDBM_File	db;
	datum_key	key;
	int	RETVAL;
	dXSTARG;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GDBM_File")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    db = INT2PTR(GDBM_File,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"GDBM_File::DELETE",
			"db", "GDBM_File")
;

	DBM_ckFilter(ST(1), filter[store_key], "filter_store_key");
	{
	    STRLEN len;
	    key.dptr = SvPVbyte(ST(1), len);
	    key.dsize = (int)len;
	}
;

	RETVAL = gdbm_DELETE(db, key);
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}

#define gdbm_FIRSTKEY(db)			gdbm_firstkey(db->dbp)

XS_EUPXS(XS_GDBM_File_FIRSTKEY); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_FIRSTKEY)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "db");
    {
	GDBM_File	db;
	datum_key	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GDBM_File")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    db = INT2PTR(GDBM_File,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"GDBM_File::FIRSTKEY",
			"db", "GDBM_File")
;

	RETVAL = gdbm_FIRSTKEY(db);
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    output_datum(aTHX_ RETVALSV, RETVAL.dptr, RETVAL.dsize);
	    DBM_ckFilter(RETVALSV, filter[fetch_key],"filter_fetch_key");
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}

#define gdbm_NEXTKEY(db,key)			gdbm_nextkey(db->dbp,key)

XS_EUPXS(XS_GDBM_File_NEXTKEY); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_NEXTKEY)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "db, key");
    {
	GDBM_File	db;
	datum_key	key;
	datum_key	RETVAL;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GDBM_File")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    db = INT2PTR(GDBM_File,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"GDBM_File::NEXTKEY",
			"db", "GDBM_File")
;

	DBM_ckFilter(ST(1), filter[store_key], "filter_store_key");
	{
	    STRLEN len;
	    key.dptr = SvPVbyte(ST(1), len);
	    key.dsize = (int)len;
	}
;

	RETVAL = gdbm_NEXTKEY(db, key);
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    output_datum(aTHX_ RETVALSV, RETVAL.dptr, RETVAL.dsize);
	    DBM_ckFilter(RETVALSV, filter[fetch_key],"filter_fetch_key");
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}

#define gdbm_reorganize(db)			gdbm_reorganize(db->dbp)

XS_EUPXS(XS_GDBM_File_reorganize); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_reorganize)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "db");
    {
	GDBM_File	db;
	int	RETVAL;
	dXSTARG;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GDBM_File")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    db = INT2PTR(GDBM_File,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"GDBM_File::reorganize",
			"db", "GDBM_File")
;

	RETVAL = gdbm_reorganize(db);
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}

#define gdbm_sync(db)				gdbm_sync(db->dbp)

XS_EUPXS(XS_GDBM_File_sync); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_sync)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "db");
    {
	GDBM_File	db;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GDBM_File")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    db = INT2PTR(GDBM_File,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"GDBM_File::sync",
			"db", "GDBM_File")
;

	gdbm_sync(db);
    }
    XSRETURN_EMPTY;
}

#define gdbm_EXISTS(db,key)			gdbm_exists(db->dbp,key)

XS_EUPXS(XS_GDBM_File_EXISTS); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_EXISTS)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "db, key");
    {
	GDBM_File	db;
	datum_key	key;
	int	RETVAL;
	dXSTARG;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GDBM_File")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    db = INT2PTR(GDBM_File,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"GDBM_File::EXISTS",
			"db", "GDBM_File")
;

	DBM_ckFilter(ST(1), filter[store_key], "filter_store_key");
	{
	    STRLEN len;
	    key.dptr = SvPVbyte(ST(1), len);
	    key.dsize = (int)len;
	}
;

	RETVAL = gdbm_EXISTS(db, key);
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}

#define gdbm_setopt(db,optflag, optval, optlen)	gdbm_setopt(db->dbp,optflag, optval, optlen)

XS_EUPXS(XS_GDBM_File_setopt); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_setopt)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "db, optflag, optval, optlen");
    {
	GDBM_File	db;
	int	optflag = (int)SvIV(ST(1))
;
	int	optval = (int)SvIV(ST(2))
;
	int	optlen = (int)SvIV(ST(3))
;
	int	RETVAL;
	dXSTARG;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GDBM_File")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    db = INT2PTR(GDBM_File,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			"GDBM_File::setopt",
			"db", "GDBM_File")
;

	RETVAL = gdbm_setopt(db, optflag, &optval, optlen);
	XSprePUSH; PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_GDBM_File_filter_fetch_key); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_filter_fetch_key)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items != 2)
       croak_xs_usage(cv,  "db, code");
    {
	GDBM_File	db;
	SV *	code = ST(1)
;
	SV *	RETVAL = &PL_sv_undef ;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GDBM_File")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    db = INT2PTR(GDBM_File,tmp);
	}
	else
	    Perl_croak_nocontext("%s: %s is not of type %s",
			GvNAME(CvGV(cv)),
			"db", "GDBM_File")
;
#line 203 "GDBM_File.xs"
	    DBM_setFilter(db->filter[ix], code);
#line 768 "GDBM_File.c"
    }
    XSRETURN(1);
}

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

    PERL_UNUSED_VAR(file);

    PERL_UNUSED_VAR(cv); /* -W */
    PERL_UNUSED_VAR(items); /* -W */
#if PERL_VERSION_LE(5, 21, 5)
    XS_VERSION_BOOTCHECK;
#  ifdef XS_APIVERSION_BOOTCHECK
    XS_APIVERSION_BOOTCHECK;
#  endif
#endif

    {
        CV * cv;

        newXS_deffile("GDBM_File::AUTOLOAD", XS_GDBM_File_AUTOLOAD);
        newXS_deffile("GDBM_File::TIEHASH", XS_GDBM_File_TIEHASH);
        newXS_deffile("GDBM_File::close", XS_GDBM_File_close);
        newXS_deffile("GDBM_File::DESTROY", XS_GDBM_File_DESTROY);
        newXS_deffile("GDBM_File::FETCH", XS_GDBM_File_FETCH);
        newXS_deffile("GDBM_File::STORE", XS_GDBM_File_STORE);
        newXS_deffile("GDBM_File::DELETE", XS_GDBM_File_DELETE);
        newXS_deffile("GDBM_File::FIRSTKEY", XS_GDBM_File_FIRSTKEY);
        newXS_deffile("GDBM_File::NEXTKEY", XS_GDBM_File_NEXTKEY);
        newXS_deffile("GDBM_File::reorganize", XS_GDBM_File_reorganize);
        newXS_deffile("GDBM_File::sync", XS_GDBM_File_sync);
        newXS_deffile("GDBM_File::EXISTS", XS_GDBM_File_EXISTS);
        newXS_deffile("GDBM_File::setopt", XS_GDBM_File_setopt);
        cv = newXS_deffile("GDBM_File::filter_fetch_key", XS_GDBM_File_filter_fetch_key);
        XSANY.any_i32 = fetch_key;
        cv = newXS_deffile("GDBM_File::filter_fetch_value", XS_GDBM_File_filter_fetch_key);
        XSANY.any_i32 = fetch_value;
        cv = newXS_deffile("GDBM_File::filter_store_key", XS_GDBM_File_filter_fetch_key);
        XSANY.any_i32 = store_key;
        cv = newXS_deffile("GDBM_File::filter_store_value", XS_GDBM_File_filter_fetch_key);
        XSANY.any_i32 = store_value;
    }

    /* Initialisation Section */

#line 2 "./const-xs.inc"
  {
#if defined(dTHX) && !defined(PERL_NO_GET_CONTEXT)
    dTHX;
#endif
    HV *symbol_table = get_hv("GDBM_File::", GV_ADD);

    static const struct iv_s values_for_iv[] =
      {
#ifdef GDBM_CACHESIZE
        { "GDBM_CACHESIZE", 14, GDBM_CACHESIZE },
#endif
#ifdef GDBM_CENTFREE
        { "GDBM_CENTFREE", 13, GDBM_CENTFREE },
#endif
#ifdef GDBM_COALESCEBLKS
        { "GDBM_COALESCEBLKS", 17, GDBM_COALESCEBLKS },
#endif
#ifdef GDBM_FAST
        { "GDBM_FAST", 9, GDBM_FAST },
#endif
#ifdef GDBM_FASTMODE
        { "GDBM_FASTMODE", 13, GDBM_FASTMODE },
#endif
#ifdef GDBM_INSERT
        { "GDBM_INSERT", 11, GDBM_INSERT },
#endif
#ifdef GDBM_NEWDB
        { "GDBM_NEWDB", 10, GDBM_NEWDB },
#endif
#ifdef GDBM_NOLOCK
        { "GDBM_NOLOCK", 11, GDBM_NOLOCK },
#endif
#ifdef GDBM_OPENMASK
        { "GDBM_OPENMASK", 13, GDBM_OPENMASK },
#endif
#ifdef GDBM_READER
        { "GDBM_READER", 11, GDBM_READER },
#endif
#ifdef GDBM_REPLACE
        { "GDBM_REPLACE", 12, GDBM_REPLACE },
#endif
#ifdef GDBM_SYNC
        { "GDBM_SYNC", 9, GDBM_SYNC },
#endif
#ifdef GDBM_SYNCMODE
        { "GDBM_SYNCMODE", 13, GDBM_SYNCMODE },
#endif
#ifdef GDBM_WRCREAT
        { "GDBM_WRCREAT", 12, GDBM_WRCREAT },
#endif
#ifdef GDBM_WRITER
        { "GDBM_WRITER", 11, GDBM_WRITER },
#endif
        { NULL, 0, 0 } };
	const struct iv_s *value_for_iv = values_for_iv;
        while (value_for_iv->name) {
	    constant_add_symbol(aTHX_  symbol_table, value_for_iv->name,
				value_for_iv->namelen, newSViv(value_for_iv->value));
            ++value_for_iv;
	}
	if (C_ARRAY_LENGTH(values_for_notfound) > 1) {
#ifndef SYMBIAN
	    HV *const constant_missing = get_missing_hash(aTHX);
#endif
	    const struct notfound_s *value_for_notfound = values_for_notfound;
	    do {

		/* Need to add prototypes, else parsing will vary by platform.  */
		HE *he = (HE*) hv_common_key_len(symbol_table,
						 value_for_notfound->name,
						 value_for_notfound->namelen,
						 HV_FETCH_LVALUE, NULL, 0);
		SV *sv;
#ifndef SYMBIAN
		HEK *hek;
#endif
		if (!he) {
		    croak("Couldn't add key '%s' to %%GDBM_File::",
			  value_for_notfound->name);
		}
		sv = HeVAL(he);
		if (!SvOK(sv) && SvTYPE(sv) != SVt_PVGV) {
		    /* Nothing was here before, so mark a prototype of ""  */
		    sv_setpvn(sv, "", 0);
		} else if (SvPOK(sv) && SvCUR(sv) == 0) {
		    /* There is already a prototype of "" - do nothing  */
		} else {
		    /* Someone has been here before us - have to make a real
		       typeglob.  */
		    /* It turns out to be incredibly hard to deal with all the
		       corner cases of sub foo (); and reporting errors correctly,
		       so lets cheat a bit.  Start with a constant subroutine  */
		    CV *cv = newCONSTSUB(symbol_table,
					 value_for_notfound->name,
					 &PL_sv_yes);
		    /* and then turn it into a non constant declaration only.  */
		    SvREFCNT_dec(CvXSUBANY(cv).any_ptr);
		    CvCONST_off(cv);
		    CvXSUB(cv) = NULL;
		    CvXSUBANY(cv).any_ptr = NULL;
		}
#ifndef SYMBIAN
		hek = HeKEY_hek(he);
		if (!hv_common(constant_missing, NULL, HEK_KEY(hek),
 			       HEK_LEN(hek), HEK_FLAGS(hek), HV_FETCH_ISSTORE,
			       &PL_sv_yes, HEK_HASH(hek)))
		    croak("Couldn't add key '%s' to missing_hash",
			  value_for_notfound->name);
#endif
	    } while ((++value_for_notfound)->name);
	}
    /* As we've been creating subroutines, we better invalidate any cached
       methods  */
    mro_method_changed_in(symbol_table);
  }

#line 946 "GDBM_File.c"

    /* End of Initialisation Section */

#if PERL_VERSION_LE(5, 21, 5)
#  if PERL_VERSION_GE(5, 9, 0)
    if (PL_unitcheckav)
        call_list(PL_scopestack_ix, PL_unitcheckav);
#  endif
    XSRETURN_YES;
#else
    Perl_xs_boot_epilog(aTHX_ ax);
#endif
}

