/*
 * This file was generated automatically by ExtUtils::ParseXS version 3.51 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;

/* Indexes for gdbm_flags aliases */
enum {
    opt_flags = 0,
    opt_cache_size,
    opt_sync_mode,
    opt_centfree,
    opt_coalesce,
    opt_dbname,
    opt_block_size,
    opt_mmap,
    opt_mmapsize
};

/* Names of gdbm_flags aliases, for error reporting.
   Indexed by opt_ constants above.
*/
char const *opt_names[] = {
    "GDBM_File::flags",
    "GDBM_File::cache_size",
    "GDBM_File::sync_mode",
    "GDBM_File::centfree",
    "GDBM_File::coalesce",
    "GDBM_File::dbname",
    "GDBM_File::block_size",
    "GDBM_File::mmap",
    "GDBM_File::mmapsize"
};    

#ifdef GDBM_VERSION_MAJOR
# define GDBM_VERSION_GUESS 0
#else
/* Try educated guess
 * The value of GDBM_VERSION_GUESS indicates how rough the guess is:
 *   1 - Precise; based on the CVS logs and existing archives
 *   2 - Moderate. The major and minor number are correct. The patchlevel
 *       is set to the upper bound.
 *   3 - Rough; The version is guaranteed to be not newer than major.minor.
 */
# if defined(GDBM_SYNCMODE)
/* CHANGES from 1.7.3 to 1.8
 *   1.  Added GDBM_CENTFREE functionality and option.
 */  
#  define GDBM_VERSION_MAJOR 1
#  define GDBM_VERSION_MINOR 8
#  define GDBM_VERSION_PATCH 3
#  define GDBM_VERSION_GUESS 1
# elif defined(GDBM_FASTMODE)
/* CHANGES from 1.7.2 to 1.7.3
 *  1.  Fixed a couple of last minute problems. (Namely, no autoconf.h in
 *      version.c, and no GDBM_FASTMODE in gdbm.h!)
 */
#  define GDBM_VERSION_MAJOR 1
#  define GDBM_VERSION_MINOR 7
#  define GDBM_VERSION_PATCH 3
#  define GDBM_VERSION_GUESS 1
# elif defined(GDBM_FAST)
/* From CVS logs:
 * Mon May 17 12:32:02 1993  Phil Nelson  (phil at cs.wwu.edu)
 *
 * * gdbm.proto: Added GDBM_FAST to the read_write flags.
 */
#  define GDBM_VERSION_MAJOR 1
#  define GDBM_VERSION_MINOR 7
#  define GDBM_VERSION_PATCH 2
#  define GDBM_VERSION_GUESS 2
# else
#  define GDBM_VERSION_MAJOR 1
#  define GDBM_VERSION_MINOR 6
#  define GDBM_VERSION_GUESS 3
# endif
#endif

#ifndef GDBM_VERSION_PATCH
# define GDBM_VERSION_PATCH 0
#endif

/* The use of fatal_func argument to gdbm_open is deprecated since 1.13 */
#if GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 13
# define FATALFUNC NULL
#elif GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 9
# define FATALFUNC croak_string
# define NEED_FATALFUNC 1
#else
# define FATALFUNC (void (*)()) croak_string
# define NEED_FATALFUNC 1
#endif

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

#define not_here(s) (croak("GDBM_File::%s not implemented", #s),-1)

#if ! (GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 11)
typedef unsigned gdbm_count_t;
#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

#if GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR < 13
/* Prior to 1.13, only gdbm_fetch set GDBM_ITEM_NOT_FOUND if the requested
   key did not exist.  Other similar functions would set GDBM_NO_ERROR instead.
   The GDBM_ITEM_NOT_FOUND existed as early as in 1.7.3 */
# define ITEM_NOT_FOUND()  (gdbm_errno == GDBM_NO_ERROR || gdbm_errno == GDBM_ITEM_NOT_FOUND)
#else
# define ITEM_NOT_FOUND()  (gdbm_errno == GDBM_ITEM_NOT_FOUND)
#endif

#define CHECKDB(db) do {                        \
    if (!db->dbp) {                             \
        croak("database was closed");           \
    }                                           \
 } while (0)

static void
dbcroak(GDBM_File db, char const *func)
{
#if GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 13
    if (db)
        croak("%s: %s", func, gdbm_db_strerror(db->dbp));
    if (gdbm_check_syserr(gdbm_errno))
        croak("%s: %s: %s", func, gdbm_strerror(gdbm_errno), strerror(errno));
#else
    (void)db;
#endif
    croak("%s: %s", func, gdbm_strerror(gdbm_errno));
}

#if GDBM_VERSION_MAJOR == 1 && (GDBM_VERSION_MINOR > 16 || GDBM_VERSION_PATCH >= 90)
# define gdbm_close(db)    gdbm_close(db->dbp)
#else
# define gdbm_close(db)    (gdbm_close(db->dbp),0)
#endif
static int
gdbm_file_close(GDBM_File db)
{
    int rc = 0;
    if (db->dbp) {
        rc = gdbm_close(db);
        db->dbp = NULL;
    }
    return rc;
}

#if GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 13
/* Error-reporting wrapper for gdbm_recover */
static void
rcvr_errfun(void *cv, char const *fmt, ...)
{
    dTHX;
    dSP;
    va_list ap;

    ENTER;
    SAVETMPS;

    PUSHMARK(SP);
    va_start(ap, fmt);
    XPUSHs(sv_2mortal(vnewSVpvf(fmt, &ap)));
    va_end(ap);
    PUTBACK;

    call_sv((SV*)cv, G_DISCARD);

    FREETMPS;
    LEAVE;
}
#endif

#if GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR < 13
static int
gdbm_check_syserr(int ec)
{
        switch (ec) {
        case GDBM_FILE_OPEN_ERROR:
        case GDBM_FILE_WRITE_ERROR:
        case GDBM_FILE_SEEK_ERROR:
        case GDBM_FILE_READ_ERROR:
            return 1;

        default:
            return 0;
        }
}
#endif

static I32
get_gdbm_errno(pTHX_ IV idx, SV *sv)
{
    PERL_UNUSED_ARG(idx);
    sv_setiv(sv, gdbm_errno);
    sv_setpv(sv, gdbm_strerror(gdbm_errno));
    if (gdbm_check_syserr(gdbm_errno)) {
        SV *val = get_sv("!", 0);
        if (val) {
            sv_catpv(sv, ": ");
            sv_catsv(sv, val);
        }
    }
    SvIOK_on(sv);
    return 0;
}

static I32
set_gdbm_errno(pTHX_ IV idx, SV *sv)
{
    PERL_UNUSED_ARG(idx);
    gdbm_errno = SvIV(sv);
    return 0;
}


#include "const-c.inc"

#line 273 "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 417 "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 257 "./const-xs.inc"
	SV *sv = newSVpvn_flags(SvPVX(cv), SvCUR(cv), SVs_TEMP | SvUTF8(cv));
	const COP *cop = PL_curcop;
#line 434 "GDBM_File.c"
#line 260 "./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 457 "GDBM_File.c"
	PUTBACK;
	return;
    }
}


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


XS_EUPXS(XS_GDBM_File_GDBM_version); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_GDBM_version)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "package");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
#line 282 "GDBM_File.xs"
	I32 gimme = GIMME_V;
        if (gimme == G_VOID) {
	    /* nothing */;
        } else if (gimme == G_SCALAR) {
	    static char const *guess[] = {
		    "",
		    " (exact guess)",
		    " (approximate)",
		    " (rough guess)"
	    };
 	    if (GDBM_VERSION_PATCH > 0) {
		XPUSHs(sv_2mortal(newSVpvf("%d.%d.%d%s",
					   GDBM_VERSION_MAJOR,
					   GDBM_VERSION_MINOR,
					   GDBM_VERSION_PATCH,
					   guess[GDBM_VERSION_GUESS])));
	    } else {
		XPUSHs(sv_2mortal(newSVpvf("%d.%d%s",
					   GDBM_VERSION_MAJOR,
					   GDBM_VERSION_MINOR,
					   guess[GDBM_VERSION_GUESS])));
	    }
	} else {
		XPUSHs(sv_2mortal(newSVuv(GDBM_VERSION_MAJOR)));
		XPUSHs(sv_2mortal(newSVuv(GDBM_VERSION_MINOR)));
		XPUSHs(sv_2mortal(newSVuv(GDBM_VERSION_PATCH)));
		if (GDBM_VERSION_GUESS > 0) {
			XPUSHs(sv_2mortal(newSVuv(GDBM_VERSION_GUESS)));
		}
	}
#line 507 "GDBM_File.c"
	PUTBACK;
	return;
    }
}


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 320 "GDBM_File.xs"
	GDBM_FILE dbp;
#line 531 "GDBM_File.c"
	GDBM_File	RETVAL;
#line 322 "GDBM_File.xs"
	dbp = gdbm_open(name, 0, read_write, mode, FATALFUNC);
	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);
	}
	if (dbp) {
	    RETVAL = (GDBM_File)safecalloc(1, sizeof(GDBM_File_type));
	    RETVAL->dbp = dbp;
	} else {
	    RETVAL = NULL;
	}
#line 553 "GDBM_File.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv(RETVALSV, dbtype, (void*)RETVAL);
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


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 348 "GDBM_File.xs"
	int i = store_value;
#line 575 "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 350 "GDBM_File.xs"
        if (gdbm_file_close(db)) {
            croak("gdbm_close: %s; %s", gdbm_strerror(gdbm_errno),
                  strerror(errno));
	}
	do {
	    if (db->filter[i])
		SvREFCNT_dec(db->filter[i]);
	} while (i-- > 0);
	safefree(db);
#line 596 "GDBM_File.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_GDBM_File_UNTIE); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_UNTIE)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "db, count");
    {
	GDBM_File	db;
	unsigned	count = (unsigned)SvUV(ST(1))
;

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GDBM_File")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    db = INT2PTR(GDBM_File,tmp);
	}
	else {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::UNTIE",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 365 "GDBM_File.xs"
        if (count == 0) {
            if (gdbm_file_close(db))
                croak("gdbm_close: %s; %s",
                      gdbm_strerror(gdbm_errno),
                      strerror(errno));
	}
#line 633 "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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::FETCH",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;

	DBM_ckFilter(ST(1), filter[store_key], "filter_store_key");
	{
	    STRLEN len;
	    key.dptr = SvPVbyte(ST(1), len);
	    key.dsize = (int)len;
	}
;
#line 379 "GDBM_File.xs"
        CHECKDB(db);
#line 674 "GDBM_File.c"

	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;
	}
#line 381 "GDBM_File.xs"
        if (RETVAL.dptr == NULL && !ITEM_NOT_FOUND()) {
            dbcroak(db, "gdbm_fetch");
        }
#line 688 "GDBM_File.c"
    }
    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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::STORE",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;

	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))
;
	}
#line 393 "GDBM_File.xs"
        CHECKDB(db);
#line 752 "GDBM_File.c"

	RETVAL = gdbm_STORE(db, key, value, flags);
	XSprePUSH;
	PUSHi((IV)RETVAL);
#line 395 "GDBM_File.xs"
	if (RETVAL) {
	    dbcroak(db, "gdbm_store");
	}
#line 761 "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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::DELETE",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;

	DBM_ckFilter(ST(1), filter[store_key], "filter_store_key");
	{
	    STRLEN len;
	    key.dptr = SvPVbyte(ST(1), len);
	    key.dsize = (int)len;
	}
;
#line 405 "GDBM_File.xs"
        CHECKDB(db);
#line 803 "GDBM_File.c"

	RETVAL = gdbm_DELETE(db, key);
	XSprePUSH;
	PUSHi((IV)RETVAL);
#line 407 "GDBM_File.xs"
        if (RETVAL && !ITEM_NOT_FOUND()) {
            dbcroak(db, "gdbm_delete");
        }
#line 812 "GDBM_File.c"
    }
    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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::FIRSTKEY",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 416 "GDBM_File.xs"
        CHECKDB(db);
#line 844 "GDBM_File.c"

	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;
	}
#line 418 "GDBM_File.xs"
        if (RETVAL.dptr == NULL && !ITEM_NOT_FOUND()) {
            dbcroak(db, "gdbm_firstkey");
        }
#line 858 "GDBM_File.c"
    }
    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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::NEXTKEY",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;

	DBM_ckFilter(ST(1), filter[store_key], "filter_store_key");
	{
	    STRLEN len;
	    key.dptr = SvPVbyte(ST(1), len);
	    key.dsize = (int)len;
	}
;
#line 428 "GDBM_File.xs"
        CHECKDB(db);
#line 899 "GDBM_File.c"

	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;
	}
#line 430 "GDBM_File.xs"
        if (RETVAL.dptr == NULL && !ITEM_NOT_FOUND()) {
            dbcroak(db, "gdbm_nextkey");
        }
#line 913 "GDBM_File.c"
    }
    XSRETURN(1);
}

#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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::EXISTS",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;

	DBM_ckFilter(ST(1), filter[store_key], "filter_store_key");
	{
	    STRLEN len;
	    key.dptr = SvPVbyte(ST(1), len);
	    key.dsize = (int)len;
	}
;
#line 440 "GDBM_File.xs"
        CHECKDB(db);
#line 955 "GDBM_File.c"

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


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;
	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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::close",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 448 "GDBM_File.xs"
        CHECKDB(db);
#line 991 "GDBM_File.c"
#line 450 "GDBM_File.xs"
        RETVAL = gdbm_file_close(db);
#line 994 "GDBM_File.c"
	XSprePUSH;
	PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}

#define gdbm_gdbm_check_syserr(ec) gdbm_check_syserr(ec)

XS_EUPXS(XS_GDBM_File_gdbm_check_syserr); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_gdbm_check_syserr)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "ec");
    {
	int	ec = (int)SvIV(ST(0))
;
	int	RETVAL;
	dXSTARG;

	RETVAL = gdbm_gdbm_check_syserr(ec);
	XSprePUSH;
	PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_GDBM_File_errno); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_errno)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "db");
    {
	GDBM_File	db;
	SV *	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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::errno",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 463 "GDBM_File.xs"
        CHECKDB(db);
#line 1048 "GDBM_File.c"
#line 465 "GDBM_File.xs"
#if GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 13
    {
        int ec = gdbm_last_errno(db->dbp);
        RETVAL = newSViv(ec);
        sv_setpv(RETVAL, gdbm_db_strerror (db->dbp));
        SvIOK_on(RETVAL);
    }
#else
        RETVAL = newSVsv(get_sv("GDBM_File::gdbm_errno", 0));
#endif
#line 1060 "GDBM_File.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_GDBM_File_syserrno); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_syserrno)
{
    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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::syserrno",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 482 "GDBM_File.xs"
        CHECKDB(db);
#line 1094 "GDBM_File.c"
#line 484 "GDBM_File.xs"
#if GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 13
    {
        int ec = gdbm_last_errno(db->dbp);
        if (gdbm_check_syserr(ec)) {
            RETVAL = gdbm_last_syserr(db->dbp);
        } else {
            RETVAL = 0;
        }
    }
#else
        RETVAL = not_here("syserrno");
#endif
#line 1108 "GDBM_File.c"
	XSprePUSH;
	PUSHi((IV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_GDBM_File_strerror); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_strerror)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "db");
    {
	GDBM_File	db;
#line 503 "GDBM_File.xs"
        char const *errstr;
#line 1126 "GDBM_File.c"
	SV *	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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::strerror",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 505 "GDBM_File.xs"
        CHECKDB(db);
#line 1144 "GDBM_File.c"
#line 507 "GDBM_File.xs"
#if GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 13        
        errstr = gdbm_db_strerror(db->dbp);
#else
        errstr = gdbm_strerror(gdbm_errno);
#endif
        RETVAL = newSVpv(errstr, 0);            
#line 1152 "GDBM_File.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}

#if GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 13        
# define gdbm_clear_error(db)        gdbm_clear_error(db->dbp)
#else
# define gdbm_clear_error(db)        (gdbm_errno = 0)
#endif        

XS_EUPXS(XS_GDBM_File_clear_error); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_clear_error)
{
    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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::clear_error",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 525 "GDBM_File.xs"
        CHECKDB(db);
#line 1189 "GDBM_File.c"

	gdbm_clear_error(db);
    }
    XSRETURN_EMPTY;
}

#if GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 13        
# define gdbm_needs_recovery(db)     gdbm_needs_recovery(db->dbp)
#else
# define gdbm_needs_recovery(db)     not_here("gdbm_needs_recovery")
#endif        

XS_EUPXS(XS_GDBM_File_needs_recovery); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_needs_recovery)
{
    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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::needs_recovery",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 536 "GDBM_File.xs"
        CHECKDB(db);
#line 1228 "GDBM_File.c"

	RETVAL = gdbm_needs_recovery(db);
	XSprePUSH;
	PUSHi((IV)RETVAL);
    }
    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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::reorganize",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 543 "GDBM_File.xs"
        CHECKDB(db);
#line 1265 "GDBM_File.c"

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

#if GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 13
#define XSubPPtmpAAAA 1


XS_EUPXS(XS_GDBM_File_recover); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_recover)
{
    dVAR; dXSARGS;
    if (items < 1)
       croak_xs_usage(cv,  "db, ...");
    {
	GDBM_File	db;
#line 560 "GDBM_File.xs"
        int flags = GDBM_RCVR_FORCE;
        SV *backup_ref = &PL_sv_undef;
        SV *stat_ref = &PL_sv_undef;
        gdbm_recovery rcvr;
#line 1291 "GDBM_File.c"

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GDBM_File")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    db = INT2PTR(GDBM_File,tmp);
	}
	else {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::recover",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 565 "GDBM_File.xs"
        CHECKDB(db);
#line 1308 "GDBM_File.c"
#line 567 "GDBM_File.xs"
        if (items > 1) {
            int i;
            if ((items % 2) == 0) {
                croak_xs_usage(cv, "db, %opts");
            }
            for (i = 1; i < items; i += 2) {
                char *kw;
                SV *sv = ST(i);
                SV *val = ST(i+1);

                kw = SvPV_nolen(sv);
                if (strcmp(kw, "err") == 0) {
                    SvGETMAGIC(val);
                    if (SvROK(val) && SvTYPE(SvRV(val)) == SVt_PVCV) {
                        rcvr.data = SvRV(val);
                    } else {
                        croak("%s must be a code ref", kw);
                    }
                    rcvr.errfun = rcvr_errfun;
                    flags |= GDBM_RCVR_ERRFUN;
                } else if (strcmp(kw, "max_failed_keys") == 0) {
                    rcvr.max_failed_keys = SvUV(val);
                    flags |= GDBM_RCVR_MAX_FAILED_KEYS;
                } else if (strcmp(kw, "max_failed_buckets") == 0) {
                    rcvr.max_failed_buckets = SvUV(val);
                    flags |= GDBM_RCVR_MAX_FAILED_BUCKETS;
                } else if (strcmp(kw, "max_failures") == 0) {
                    rcvr.max_failures = SvUV(val);
                    flags |= GDBM_RCVR_MAX_FAILURES;
                } else if (strcmp(kw, "backup") == 0) {
                    SvGETMAGIC(val);
                    if (SvROK(val) && SvTYPE(SvRV(val)) < SVt_PVAV) {
                        backup_ref = val;
                    } else {
                        croak("%s must be a scalar reference", kw);
                    } 
                    flags |= GDBM_RCVR_BACKUP;
                } else if (strcmp(kw, "stat") == 0) {
                    SvGETMAGIC(val);
                    if (SvROK(val) && SvTYPE(SvRV(val)) == SVt_PVHV) {
                        stat_ref = val;
                    } else {
                        croak("%s must be a scalar reference", kw);
                    } 
                } else {
                    croak("%s: unrecognized argument", kw);
                }
            }
        }
        if (gdbm_recover(db->dbp, &rcvr, flags)) {
            dbcroak(db, "gdbm_recover");
        }
        if (stat_ref != &PL_sv_undef) {
            HV *hv = (HV*)SvRV(stat_ref);
#define STAT_RECOVERED_KEYS_STR "recovered_keys"
#define STAT_RECOVERED_KEYS_LEN (sizeof(STAT_RECOVERED_KEYS_STR)-1)
#define STAT_RECOVERED_BUCKETS_STR "recovered_buckets"
#define STAT_RECOVERED_BUCKETS_LEN (sizeof(STAT_RECOVERED_BUCKETS_STR)-1)
#define STAT_FAILED_KEYS_STR "failed_keys"
#define STAT_FAILED_KEYS_LEN (sizeof(STAT_FAILED_KEYS_STR)-1)
#define STAT_FAILED_BUCKETS_STR "failed_buckets"
#define STAT_FAILED_BUCKETS_LEN (sizeof(STAT_FAILED_BUCKETS_STR)-1)
            hv_store(hv, STAT_RECOVERED_KEYS_STR, STAT_RECOVERED_KEYS_LEN,
                     newSVuv(rcvr.recovered_keys), 0);
            hv_store(hv,
                     STAT_RECOVERED_BUCKETS_STR,
                     STAT_RECOVERED_BUCKETS_LEN,
                     newSVuv(rcvr.recovered_buckets), 0);
            hv_store(hv,
                     STAT_FAILED_KEYS_STR,
                     STAT_FAILED_KEYS_LEN,
                     newSVuv(rcvr.failed_keys), 0);
            hv_store(hv,
                     STAT_FAILED_BUCKETS_STR,
                     STAT_FAILED_BUCKETS_LEN,
                     newSVuv(rcvr.failed_buckets), 0);
        }
        if (backup_ref != &PL_sv_undef) {
            SV *sv = SvRV(backup_ref);
            sv_setpv(sv, rcvr.backup_name);
            free(rcvr.backup_name);
        }
#line 1392 "GDBM_File.c"
    }
    XSRETURN_EMPTY;
}

#endif
#if GDBM_VERSION_MAJOR == 1 && (GDBM_VERSION_MINOR > 16 || GDBM_VERSION_PATCH >= 90)
# define gdbm_sync(db)				gdbm_sync(db->dbp)
#else
# define gdbm_sync(db)				(gdbm_sync(db->dbp),0)
#endif

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;
	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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::sync",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 661 "GDBM_File.xs"
        CHECKDB(db);
#line 1430 "GDBM_File.c"

	RETVAL = gdbm_sync(db);
	XSprePUSH;
	PUSHi((IV)RETVAL);
#line 663 "GDBM_File.xs"
        if (RETVAL) {
            dbcroak(db, "gdbm_sync");
        }
#line 1439 "GDBM_File.c"
    }
    XSRETURN(1);
}

#if GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 11
#define XSubPPtmpAAAB 1


XS_EUPXS(XS_GDBM_File_count); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_count)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "db");
    {
	GDBM_File	db;
#line 673 "GDBM_File.xs"
         gdbm_count_t c;
#line 1458 "GDBM_File.c"
	gdbm_count_t	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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::count",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 675 "GDBM_File.xs"
        CHECKDB(db);
#line 1477 "GDBM_File.c"
#line 677 "GDBM_File.xs"
        if (gdbm_count(db->dbp, &c)) {
            dbcroak(db, "gdbm_count");
        }
        RETVAL = c;
#line 1483 "GDBM_File.c"
	XSprePUSH;
	PUSHu((UV)RETVAL);
    }
    XSRETURN(1);
}


XS_EUPXS(XS_GDBM_File_dump); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_dump)
{
    dVAR; dXSARGS;
    if (items < 2)
       croak_xs_usage(cv,  "db, filename, ...");
    {
	GDBM_File	db;
	char *	filename = (char *)SvPV_nolen(ST(1))
;
#line 689 "GDBM_File.xs"
        int             format = GDBM_DUMP_FMT_ASCII;
        int             flags = GDBM_WRCREAT;
        int             mode = 0666;
#line 1505 "GDBM_File.c"

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GDBM_File")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    db = INT2PTR(GDBM_File,tmp);
	}
	else {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::dump",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 693 "GDBM_File.xs"
        CHECKDB(db);
#line 1522 "GDBM_File.c"
#line 695 "GDBM_File.xs"
        if (items % 2) {
            croak_xs_usage(cv, "db, filename, %opts");
        } else {
            int i;

            for (i = 2; i < items; i += 2) {
                char *kw;
                SV *sv = ST(i);
                SV *val = ST(i+1);

                kw = SvPV_nolen(sv);
                if (strcmp(kw, "mode") == 0) {
                    mode = SvUV(val) & 0777;
                } else if (strcmp(kw, "binary") == 0) {
                    if (SvTRUE(val)) {
                        format = GDBM_DUMP_FMT_BINARY;
                    }
                } else if (strcmp(kw, "overwrite") == 0) {
                    if (SvTRUE(val)) {
                        flags = GDBM_NEWDB;
                    }
                } else {
                    croak("unrecognized keyword: %s", kw);
                }
            }
            if (gdbm_dump(db->dbp, filename, format, flags, mode)) {
                dbcroak(NULL, "dump");
            }
        }
#line 1553 "GDBM_File.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_GDBM_File_load); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_load)
{
    dVAR; dXSARGS;
    if (items < 2)
       croak_xs_usage(cv,  "db, filename, ...");
    {
	GDBM_File	db;
	char *	filename = (char *)SvPV_nolen(ST(1))
;
#line 730 "GDBM_File.xs"
        int flag = GDBM_INSERT;
        int meta_mask = 0;
        unsigned long errline;
        int result;
        int strict_errors = 0;
#line 1575 "GDBM_File.c"

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GDBM_File")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    db = INT2PTR(GDBM_File,tmp);
	}
	else {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::load",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 736 "GDBM_File.xs"
        CHECKDB(db);
#line 1592 "GDBM_File.c"
#line 738 "GDBM_File.xs"
        if (items % 2) {
            croak_xs_usage(cv, "db, filename, %opts");
        } else {
            int i;

            for (i = 2; i < items; i += 2) {
                char *kw;
                SV *sv = ST(i);
                SV *val = ST(i+1);

                kw = SvPV_nolen(sv);

                if (strcmp(kw, "restore_mode") == 0) {
                    if (!SvTRUE(val))
                        meta_mask |= GDBM_META_MASK_MODE;
                } else if (strcmp(kw, "restore_owner") == 0) {
                    if (!SvTRUE(val))
                        meta_mask |= GDBM_META_MASK_OWNER;
                } else if (strcmp(kw, "replace") == 0) {
                    if (SvTRUE(val))
                        flag = GDBM_REPLACE;
                } else if (strcmp(kw, "strict_errors") == 0) {
                    strict_errors = SvTRUE(val);
                } else {
                    croak("unrecognized keyword: %s", kw);
                }
            }
        }

        result = gdbm_load(&db->dbp, filename, flag, meta_mask, &errline);
        if (result == -1 || (result == 1 && strict_errors)) {
#if GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 13
            if (errline) {
                croak("%s:%lu: database load error: %s",
                      filename, errline, gdbm_db_strerror(db->dbp));
            } else {
                croak("%s: database load error: %s",
                      filename, gdbm_db_strerror(db->dbp));
            }
#else
            if (errline) {
                croak("%s:%lu: database load error: %s",
                      filename, errline, gdbm_strerror(gdbm_errno));
            } else {
                croak("%s: database load error: %s",
                      filename, gdbm_strerror(gdbm_errno));
            }
#endif
        }
#line 1643 "GDBM_File.c"
    }
    XSRETURN_EMPTY;
}

#endif
#define OPTNAME(a,b) a ## b        
#define INTOPTSETUP(opt)                                           \
        do {                                                       \
            if (items == 1) {                                      \
                opcode = OPTNAME(GDBM_GET, opt);                   \
            } else {                                               \
                opcode = OPTNAME(GDBM_SET, opt);                   \
                c_iv = SvIV(ST(1));                                \
            }                                                      \
        } while (0)
#if GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 9
# define OPTVALPTR void *
#else
# define OPTVALPTR int *
#endif        
#ifndef GDBM_GETFLAGS        
# define GDBM_GETFLAGS        -1
#endif
#ifndef GDBM_GETMMAP        
# define GDBM_GETMMAP         -1
#endif
#ifndef GDBM_GETCACHESIZE        
# define GDBM_GETCACHESIZE    -1
#endif
#ifndef GDBM_GETSYNCMODE
# define GDBM_GETSYNCMODE     -1
#endif
#ifndef GDBM_GETCENTFREE              
# define GDBM_GETCENTFREE     -1
#endif
#ifndef GDBM_GETCOALESCEBLKS
# define GDBM_GETCOALESCEBLKS -1
#endif
#ifndef GDBM_GETMAXMAPSIZE
# define GDBM_GETMAXMAPSIZE   -1
#endif
#ifndef GDBM_GETDBNAME
# define GDBM_GETDBNAME       -1
#endif
#ifndef GDBM_GETBLOCKSIZE
# define GDBM_GETBLOCKSIZE    -1
#endif
#ifndef GDBM_SETMAXMAPSIZE        
# define GDBM_SETMAXMAPSIZE   -1
#endif
#ifndef GDBM_SETMMAP        
# define GDBM_SETMMAP         -1
#endif
#ifndef GDBM_SETCACHESIZE        
# define GDBM_SETCACHESIZE    GDBM_CACHESIZE
#endif        
#ifndef GDBM_SETSYNCMODE
# define GDBM_SETSYNCMODE     GDBM_SYNCMODE
#endif        
#ifndef GDBM_SETCENTFREE
# define GDBM_SETCENTFREE     GDBM_CENTFREE
#endif        
#ifndef GDBM_SETCOALESCEBLKS
# define GDBM_SETCOALESCEBLKS GDBM_COALESCEBLKS
#endif

XS_EUPXS(XS_GDBM_File_flags); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_flags)
{
    dVAR; dXSARGS;
    dXSI32;
    if (items < 1)
       croak_xs_usage(cv,  "db, ...");
    {
	GDBM_File	db;
	SV *	RETVAL = &PL_sv_undef;
#line 879 "GDBM_File.xs"
        int opcode = -1;
        int c_iv;
        size_t c_uv;
        char *c_cv;
        OPTVALPTR vptr = (OPTVALPTR) &c_iv;
        size_t vsiz = sizeof(c_iv);
#line 1727 "GDBM_File.c"

	if (SvROK(ST(0)) && sv_derived_from(ST(0), "GDBM_File")) {
	    IV tmp = SvIV((SV*)SvRV(ST(0)));
	    db = INT2PTR(GDBM_File,tmp);
	}
	else {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			GvNAME(CvGV(cv)),
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 886 "GDBM_File.xs"
        CHECKDB(db);
#line 1744 "GDBM_File.c"
#line 888 "GDBM_File.xs"
        if (items > 2) {
            croak("%s: too many arguments", opt_names[ix]);
        }

        switch (ix) {
        case opt_flags:
            if (items > 1) {
                croak("%s: too many arguments", opt_names[ix]);
            }
            opcode = GDBM_GETFLAGS;
            break;
        case opt_cache_size:
            INTOPTSETUP(CACHESIZE);
            break;
        case opt_sync_mode:
            INTOPTSETUP(SYNCMODE);
            break;
        case opt_centfree:
            INTOPTSETUP(CENTFREE);
            break;
        case opt_coalesce:
            INTOPTSETUP(COALESCEBLKS);
            break;
        case opt_dbname:
            if (items > 1) {
                croak("%s: too many arguments", opt_names[ix]);
            }
            opcode = GDBM_GETDBNAME;
            vptr = (OPTVALPTR) &c_cv;
            vsiz = sizeof(c_cv);
            break;
        case opt_block_size:
            if (items > 1) {
                croak("%s: too many arguments", opt_names[ix]);
            }
            opcode = GDBM_GETBLOCKSIZE;
            break;
        case opt_mmap:
            if (items > 1) {
                croak("%s: too many arguments", opt_names[ix]);
            }
            opcode = GDBM_GETMMAP;
            break;
        case opt_mmapsize:
            vptr = (OPTVALPTR) &c_uv;
            vsiz = sizeof(c_uv);
            if (items == 1) {                             
                opcode = GDBM_GETMAXMAPSIZE;
            } else {                                      
                opcode = GDBM_SETMAXMAPSIZE;
                c_uv = SvUV(ST(1));
            }                                             
            break;
        }

        if (gdbm_setopt(db->dbp, opcode, vptr, vsiz)) {
            if (gdbm_errno == GDBM_OPT_ILLEGAL)
                croak("%s not implemented", opt_names[ix]);
            dbcroak(db, "gdbm_setopt");
        }

        if (vptr == (OPTVALPTR) &c_iv) {
            RETVAL = newSViv(c_iv);
        } else if (vptr == (OPTVALPTR) &c_uv) {
            RETVAL = newSVuv(c_uv);
        } else {
            RETVAL = newSVpv(c_cv, 0);
            free(c_cv);
        }
#line 1815 "GDBM_File.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = 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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::setopt",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 968 "GDBM_File.xs"
        CHECKDB(db);
#line 1856 "GDBM_File.c"

	RETVAL = gdbm_setopt(db, optflag, &optval, optlen);
	XSprePUSH;
	PUSHi((IV)RETVAL);
#line 970 "GDBM_File.xs"
        if (RETVAL) {
            dbcroak(db, "gdbm_setopt");
        }
#line 1865 "GDBM_File.c"
    }
    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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			GvNAME(CvGV(cv)),
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 985 "GDBM_File.xs"
        DBM_setFilter(db->filter[ix], code);
#line 1899 "GDBM_File.c"
    }
    XSRETURN(1);
}

#if GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 21
#define gdbm_convert(db, flag) gdbm_convert(db->dbp, flag)
#define XSubPPtmpAAAC 1


XS_EUPXS(XS_GDBM_File_convert); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_convert)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "db, flag");
    {
	GDBM_File	db;
	int	flag = (int)SvIV(ST(1))
;
	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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::convert",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 1004 "GDBM_File.xs"
        CHECKDB(db);
#line 1937 "GDBM_File.c"

	RETVAL = gdbm_convert(db, flag);
	XSprePUSH;
	PUSHi((IV)RETVAL);
#line 1006 "GDBM_File.xs"
        if (RETVAL) {
            dbcroak(db, "gdbm_convert");
        }
#line 1946 "GDBM_File.c"
    }
    XSRETURN(1);
}

#define gdbm_failure_atomic(db, even, odd) gdbm_failure_atomic(db->dbp, even, odd)

XS_EUPXS(XS_GDBM_File_failure_atomic); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_failure_atomic)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "db, even, odd");
    {
	GDBM_File	db;
	char *	even = (char *)SvPV_nolen(ST(1))
;
	char *	odd = (char *)SvPV_nolen(ST(2))
;
	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 {
		const char* refstr = SvROK(ST(0)) ? "" : SvOK(ST(0)) ? "scalar " : "undef";
	    Perl_croak_nocontext("%s: Expected %s to be of type %s; got %s%" SVf " instead",
			"GDBM_File::failure_atomic",
			"db", "GDBM_File",
			refstr, ST(0)
		);
	}
;
#line 1018 "GDBM_File.xs"
        CHECKDB(db);
#line 1983 "GDBM_File.c"

	RETVAL = gdbm_failure_atomic(db, even, odd);
	XSprePUSH;
	PUSHi((IV)RETVAL);
#line 1020 "GDBM_File.xs"
        if (RETVAL) {
            dbcroak(db, "gdbm_failure_atomic");
        }
#line 1992 "GDBM_File.c"
    }
    XSRETURN(1);
}


XS_EUPXS(XS_GDBM_File_latest_snapshot); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_latest_snapshot)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "package, even, odd");
    PERL_UNUSED_VAR(ax); /* -Wall */
    SP -= items;
    {
	char *	even = (char *)SvPV_nolen(ST(1))
;
	char *	odd = (char *)SvPV_nolen(ST(2))
;
#line 1029 "GDBM_File.xs"
        int             result;
        int             syserr;
        const char *    filename;
#line 2015 "GDBM_File.c"
#line 1033 "GDBM_File.xs"
        result = gdbm_latest_snapshot(even, odd, &filename);
        syserr = errno;
        if (result == GDBM_SNAPSHOT_OK) {
            XPUSHs(sv_2mortal(newSVpv(filename, 0)));
        } else {
            XPUSHs(&PL_sv_undef);
        }
        if (GIMME_V == G_ARRAY) {
            XPUSHs(sv_2mortal(newSVuv(result)));
            if (result == GDBM_SNAPSHOT_ERR)
                XPUSHs(sv_2mortal(newSVuv(syserr)));
        }
#line 2029 "GDBM_File.c"
	PUTBACK;
	return;
    }
}

#endif

XS_EUPXS(XS_GDBM_File_crash_tolerance_status); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_GDBM_File_crash_tolerance_status)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "package");
    {
	int	RETVAL;
	dXSTARG;
#line 1051 "GDBM_File.xs"
#if GDBM_VERSION_MAJOR == 1 && GDBM_VERSION_MINOR >= 21
        /*
         * The call below returns GDBM_SNAPSHOT_ERR and sets errno to
         * EINVAL, if crash tolerance is implemented, or ENOSYS, if it
         * is not.
         */
        gdbm_latest_snapshot(NULL, NULL, NULL);
        RETVAL = (errno != ENOSYS);
#else
        RETVAL = 0;
#endif
#line 2058 "GDBM_File.c"
	XSprePUSH;
	PUSHi((IV)RETVAL);
    }
    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_VERSION_LE(5, 8, 999) /* PERL_VERSION_LT is 5.33+ */
    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

        newXS_deffile("GDBM_File::AUTOLOAD", XS_GDBM_File_AUTOLOAD);
        newXS_deffile("GDBM_File::GDBM_version", XS_GDBM_File_GDBM_version);
        newXS_deffile("GDBM_File::TIEHASH", XS_GDBM_File_TIEHASH);
        newXS_deffile("GDBM_File::DESTROY", XS_GDBM_File_DESTROY);
        newXS_deffile("GDBM_File::UNTIE", XS_GDBM_File_UNTIE);
        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::EXISTS", XS_GDBM_File_EXISTS);
        newXS_deffile("GDBM_File::close", XS_GDBM_File_close);
        newXS_deffile("GDBM_File::gdbm_check_syserr", XS_GDBM_File_gdbm_check_syserr);
        newXS_deffile("GDBM_File::errno", XS_GDBM_File_errno);
        newXS_deffile("GDBM_File::syserrno", XS_GDBM_File_syserrno);
        newXS_deffile("GDBM_File::strerror", XS_GDBM_File_strerror);
        newXS_deffile("GDBM_File::clear_error", XS_GDBM_File_clear_error);
        newXS_deffile("GDBM_File::needs_recovery", XS_GDBM_File_needs_recovery);
        newXS_deffile("GDBM_File::reorganize", XS_GDBM_File_reorganize);
#if XSubPPtmpAAAA
        newXS_deffile("GDBM_File::recover", XS_GDBM_File_recover);
#endif
        newXS_deffile("GDBM_File::sync", XS_GDBM_File_sync);
#if XSubPPtmpAAAB
        newXS_deffile("GDBM_File::count", XS_GDBM_File_count);
        newXS_deffile("GDBM_File::dump", XS_GDBM_File_dump);
        newXS_deffile("GDBM_File::load", XS_GDBM_File_load);
#endif
        cv = newXS_deffile("GDBM_File::block_size", XS_GDBM_File_flags);
        XSANY.any_i32 = opt_block_size;
        cv = newXS_deffile("GDBM_File::cache_size", XS_GDBM_File_flags);
        XSANY.any_i32 = opt_cache_size;
        cv = newXS_deffile("GDBM_File::centfree", XS_GDBM_File_flags);
        XSANY.any_i32 = opt_centfree;
        cv = newXS_deffile("GDBM_File::coalesce", XS_GDBM_File_flags);
        XSANY.any_i32 = opt_coalesce;
        cv = newXS_deffile("GDBM_File::dbname", XS_GDBM_File_flags);
        XSANY.any_i32 = opt_dbname;
        cv = newXS_deffile("GDBM_File::flags", XS_GDBM_File_flags);
        XSANY.any_i32 = 0;
        cv = newXS_deffile("GDBM_File::mmap", XS_GDBM_File_flags);
        XSANY.any_i32 = opt_mmap;
        cv = newXS_deffile("GDBM_File::mmapsize", XS_GDBM_File_flags);
        XSANY.any_i32 = opt_mmapsize;
        cv = newXS_deffile("GDBM_File::sync_mode", XS_GDBM_File_flags);
        XSANY.any_i32 = opt_sync_mode;
        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;
#if XSubPPtmpAAAC
        newXS_deffile("GDBM_File::convert", XS_GDBM_File_convert);
        newXS_deffile("GDBM_File::failure_atomic", XS_GDBM_File_failure_atomic);
        newXS_deffile("GDBM_File::latest_snapshot", XS_GDBM_File_latest_snapshot);
#endif
        newXS_deffile("GDBM_File::crash_tolerance_status", XS_GDBM_File_crash_tolerance_status);

    /* 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
#ifdef GDBM_NOMMAP
        { "GDBM_NOMMAP", 11, GDBM_NOMMAP },
#endif
#ifdef GDBM_CLOEXEC
        { "GDBM_CLOEXEC", 12, GDBM_CLOEXEC },
#endif
#ifdef GDBM_BSEXACT
        { "GDBM_BSEXACT", 12, GDBM_BSEXACT },
#endif
#ifdef GDBM_XVERIFY
        { "GDBM_XVERIFY", 12, GDBM_XVERIFY },
#endif
#ifdef GDBM_PREREAD
        { "GDBM_PREREAD", 12, GDBM_PREREAD },
#endif
#ifdef GDBM_NUMSYNC
        { "GDBM_NUMSYNC", 12, GDBM_NUMSYNC },
#endif
#if  GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 21
        { "GDBM_SNAPSHOT_OK", 16, GDBM_SNAPSHOT_OK },
#endif
#if  GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 21
        { "GDBM_SNAPSHOT_BAD", 17, GDBM_SNAPSHOT_BAD },
#endif
#if  GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 21
        { "GDBM_SNAPSHOT_ERR", 17, GDBM_SNAPSHOT_ERR },
#endif
#if  GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 21
        { "GDBM_SNAPSHOT_SAME", 18, GDBM_SNAPSHOT_SAME },
#endif
#if  GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 21
        { "GDBM_SNAPSHOT_SUSPICIOUS", 24, GDBM_SNAPSHOT_SUSPICIOUS },
#endif
        { "GDBM_NO_ERROR", 13, GDBM_NO_ERROR },
        { "GDBM_MALLOC_ERROR", 17, GDBM_MALLOC_ERROR },
        { "GDBM_BLOCK_SIZE_ERROR", 21, GDBM_BLOCK_SIZE_ERROR },
        { "GDBM_FILE_OPEN_ERROR", 20, GDBM_FILE_OPEN_ERROR },
        { "GDBM_FILE_WRITE_ERROR", 21, GDBM_FILE_WRITE_ERROR },
        { "GDBM_FILE_SEEK_ERROR", 20, GDBM_FILE_SEEK_ERROR },
        { "GDBM_FILE_READ_ERROR", 20, GDBM_FILE_READ_ERROR },
        { "GDBM_BAD_MAGIC_NUMBER", 21, GDBM_BAD_MAGIC_NUMBER },
        { "GDBM_EMPTY_DATABASE", 19, GDBM_EMPTY_DATABASE },
        { "GDBM_CANT_BE_READER", 19, GDBM_CANT_BE_READER },
        { "GDBM_CANT_BE_WRITER", 19, GDBM_CANT_BE_WRITER },
        { "GDBM_READER_CANT_DELETE", 23, GDBM_READER_CANT_DELETE },
        { "GDBM_READER_CANT_STORE", 22, GDBM_READER_CANT_STORE },
        { "GDBM_READER_CANT_REORGANIZE", 27, GDBM_READER_CANT_REORGANIZE },
        { "GDBM_UNKNOWN_UPDATE", 19, GDBM_UNKNOWN_UPDATE },
        { "GDBM_ITEM_NOT_FOUND", 19, GDBM_ITEM_NOT_FOUND },
        { "GDBM_REORGANIZE_FAILED", 22, GDBM_REORGANIZE_FAILED },
        { "GDBM_CANNOT_REPLACE", 19, GDBM_CANNOT_REPLACE },
        { "GDBM_ILLEGAL_DATA", 17, GDBM_ILLEGAL_DATA },
        { "GDBM_OPT_ALREADY_SET", 20, GDBM_OPT_ALREADY_SET },
        { "GDBM_OPT_ILLEGAL", 16, GDBM_OPT_ILLEGAL },
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 9
        { "GDBM_BYTE_SWAPPED", 17, GDBM_BYTE_SWAPPED },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 9
        { "GDBM_BAD_FILE_OFFSET", 20, GDBM_BAD_FILE_OFFSET },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 9
        { "GDBM_BAD_OPEN_FLAGS", 19, GDBM_BAD_OPEN_FLAGS },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 10
        { "GDBM_FILE_STAT_ERROR", 20, GDBM_FILE_STAT_ERROR },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 10
        { "GDBM_FILE_EOF", 13, GDBM_FILE_EOF },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 11
        { "GDBM_NO_DBNAME", 14, GDBM_NO_DBNAME },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 11
        { "GDBM_ERR_FILE_OWNER", 19, GDBM_ERR_FILE_OWNER },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 11
        { "GDBM_ERR_FILE_MODE", 18, GDBM_ERR_FILE_MODE },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 13
        { "GDBM_UNKNOWN_ERROR", 18, GDBM_UNKNOWN_ERROR },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 13
        { "GDBM_NEED_RECOVERY", 18, GDBM_NEED_RECOVERY },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 13
        { "GDBM_BACKUP_FAILED", 18, GDBM_BACKUP_FAILED },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 13
        { "GDBM_DIR_OVERFLOW", 17, GDBM_DIR_OVERFLOW },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 15
        { "GDBM_BAD_BUCKET", 15, GDBM_BAD_BUCKET },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 15
        { "GDBM_BAD_HEADER", 15, GDBM_BAD_HEADER },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 15
        { "GDBM_BAD_AVAIL", 14, GDBM_BAD_AVAIL },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 15
        { "GDBM_BAD_HASH_TABLE", 19, GDBM_BAD_HASH_TABLE },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 15
        { "GDBM_BAD_DIR_ENTRY", 18, GDBM_BAD_DIR_ENTRY },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 17
        { "GDBM_FILE_CLOSE_ERROR", 21, GDBM_FILE_CLOSE_ERROR },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 17
        { "GDBM_FILE_SYNC_ERROR", 20, GDBM_FILE_SYNC_ERROR },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR > 18 || ( GDBM_VERSION_MINOR == 18 && GDBM_VERSION_PATCH >= 1 )
        { "GDBM_FILE_TRUNCATE_ERROR", 24, GDBM_FILE_TRUNCATE_ERROR },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 20
        { "GDBM_BUCKET_CACHE_CORRUPTED", 27, GDBM_BUCKET_CACHE_CORRUPTED },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 20
        { "GDBM_BAD_HASH_ENTRY", 19, GDBM_BAD_HASH_ENTRY },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 21
        { "GDBM_MALFORMED_DATA", 19, GDBM_MALFORMED_DATA },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 21
        { "GDBM_OPT_BADVAL", 15, GDBM_OPT_BADVAL },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 21
        { "GDBM_ERR_SNAPSHOT_CLONE", 23, GDBM_ERR_SNAPSHOT_CLONE },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 21
        { "GDBM_ERR_REALPATH", 17, GDBM_ERR_REALPATH },
#endif
#if GDBM_VERSION_MAJOR > 1 || GDBM_VERSION_MINOR >= 21
        { "GDBM_ERR_USAGE", 14, GDBM_ERR_USAGE },
#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 268 "GDBM_File.xs"
    {
        SV *sv = get_sv("GDBM_File::gdbm_errno", GV_ADD);
        struct ufuncs uf;

        uf.uf_val = get_gdbm_errno;
        uf.uf_set = set_gdbm_errno;
        uf.uf_index = 0;

        sv_magic(sv, NULL, PERL_MAGIC_uvar, (char*)&uf, sizeof(uf));
    }

#if XSubPPtmpAAAA
#endif
#if XSubPPtmpAAAB
#endif
#if XSubPPtmpAAAC
#endif
#line 2427 "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
}

#ifdef __cplusplus
}
#endif
