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

#line 1 "PMDA.xs"
/*
 * Copyright (c) 2013-2014,2016-2017 Red Hat.
 * Copyright (c) 2008-2012 Aconex.  All Rights Reserved.
 * Copyright (c) 2004 Silicon Graphics, Inc.  All Rights Reserved.
 * 
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

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

static pmdaInterface dispatch;
static pmdaMetric *metrictab;
static int mtab_size;
static __pmnsTree *pmns;
static int need_refresh;
static pmdaIndom *indomtab;
static int itab_size;
static int *clustertab;
static int ctab_size;

static HV *metric_names;
static HV *metric_oneline;
static HV *metric_helptext;
static HV *indom_helptext;
static HV *indom_oneline;

static SV *fetch_func;
static SV *refresh_func;
static SV *instance_func;
static SV *store_cb_func;
static SV *fetch_cb_func;

int
clustertab_lookup(int cluster)
{
    int i, found = 0;

    for (i = 0; i < ctab_size; i++) {
	if (cluster == clustertab[i]) {
	    found = 1;
	    break;
	}
    }
    return found;
}

void
clustertab_replace(int index, int cluster)
{
    if (index >= 0 && index < ctab_size)
	clustertab[index] = cluster;
    else
	warn("invalid cluster table replacement requested");
}

void
clustertab_scratch()
{
    memset(clustertab, -1, sizeof(int) * ctab_size);
}

void
clustertab_refresh(int index)
{
    dSP;
    ENTER;
    SAVETMPS;
    PUSHMARK(sp);
    XPUSHs(sv_2mortal(newSVuv(clustertab[index])));
    PUTBACK;

    perl_call_sv(refresh_func, G_VOID);

    SPAGAIN;
    PUTBACK;
    FREETMPS;
    LEAVE;
}

void
refresh(int numpmid, pmID *pmidlist)
{
    int i, numclusters = 0;
    __pmID_int *pmid;

    /* Create list of affected clusters from pmidlist
     * Note: we overwrite the initial cluster array here, to avoid
     * allocating memory.  The initial array contains all possible
     * clusters whereas we (possibly) construct a subset here.  We
     * do not touch ctab_size at all, however, which lets us reuse
     * the preallocated array space on every fetch.
     */
    clustertab_scratch();
    for (i = 0; i < numpmid; i++) {
	pmid = (__pmID_int *) &pmidlist[i];
	if (clustertab_lookup(pmid->cluster) == 0)
	    clustertab_replace(numclusters++, pmid->cluster);
    }

    /* For each unique cluster, call the cluster refresh method */
    for (i = 0; i < numclusters; i++)
	clustertab_refresh(i);
}

void
pmns_refresh(void)
{
    char *pmid, *next;
    I32 idsize;
    SV *metric;
    int sts;

    if (pmns)
	__pmFreePMNS(pmns);

    if ((sts = __pmNewPMNS(&pmns)) < 0)
	croak("failed to create namespace root: %s", pmErrStr(sts));

    hv_iterinit(metric_names);
    while ((metric = hv_iternextsv(metric_names, &pmid, &idsize)) != NULL) {
	unsigned int domain, cluster, item, id;

	domain = strtoul(pmid, &next, 10);
	cluster = strtoul(next+1, &next, 10);
	item = strtoul(next+1, &next, 10);
	id = pmID_build(domain, cluster, item);
	if ((sts = __pmAddPMNSNode(pmns, id, SvPV_nolen(metric))) < 0)
	    croak("failed to add metric %s(%s) to namespace: %s",
		SvPV_nolen(metric), pmIDStr(id), pmErrStr(sts));
    }

    pmdaTreeRebuildHash(pmns, mtab_size); /* for reverse (pmid->name) lookups */
    need_refresh = 0;
}

int
pmns_desc(pmID pmid, pmDesc *desc, pmdaExt *ep)
{
    if (need_refresh)
	pmns_refresh();
    return pmdaDesc(pmid, desc, ep);
}

int
pmns_pmid(const char *name, pmID *pmid, pmdaExt *pmda)
{
    if (need_refresh)
	pmns_refresh();
    return pmdaTreePMID(pmns, name, pmid);
}

int
pmns_name(pmID pmid, char ***nameset, pmdaExt *pmda)
{
    if (need_refresh)
	pmns_refresh();
    return pmdaTreeName(pmns, pmid, nameset);
}

int
pmns_children(const char *name, int traverse, char ***kids, int **sts, pmdaExt *pmda)
{
    if (need_refresh)
	pmns_refresh();
    return pmdaTreeChildren(pmns, name, traverse, kids, sts);
}

void
pmns_write(void)
{
    __pmnsNode *node;
    char *pppenv = getenv("PCP_PERL_PMNS");
    int root = pppenv ? strcmp(pppenv, "root") == 0 : 0;
    char *prefix = root ? "\t" : "";

    pmns_refresh();

    if (root)
	printf("root {\n");
    for (node = pmns->root->first; node != NULL; node = node->next)
	printf("%s%s\t%u:*:*\n", prefix, node->name, dispatch.domain);
    if (root)
	printf("}\n");
}

void
domain_write(void)
{
    char *p, name[512] = { 0 };
    int i, len = strlen(pmGetProgname());

    if (len >= sizeof(name) - 1)
	len = sizeof(name) - 2;
    p = pmGetProgname();
    if (strncmp(p, "pmda", 4) == 0)
	p += 4;
    for (i = 0; i < len; i++)
	name[i] = toupper(p[i]);
    printf("#define %s %u\n", name, dispatch.domain);
}

void
prefetch(void)
{
    dSP;
    ENTER;
    SAVETMPS;
    PUSHMARK(sp);
    PUTBACK;

    perl_call_sv(fetch_func, G_VOID|G_NOARGS);

    SPAGAIN;
    PUTBACK;
    FREETMPS;
    LEAVE;
}

int
fetch_wrapper(int numpmid, pmID *pmidlist, pmdaResult **rp, pmdaExt *pmda)
{
    if (need_refresh)
	pmns_refresh();
    if (fetch_func)
	prefetch();
    if (refresh_func)
	refresh(numpmid, pmidlist);
    return pmdaFetch(numpmid, pmidlist, rp, pmda);
}

int
instance_index(pmInDom indom)
{
    int i;

    for (i = 0; i < itab_size; i++)
	if (indomtab[i].it_indom == indom)
	    return i;
    return PM_INDOM_NULL;
}

void
preinstance(pmInDom indom)
{
    dSP;
    ENTER;
    SAVETMPS;
    PUSHMARK(sp);
    XPUSHs(sv_2mortal(newSVuv(indom)));
    PUTBACK;

    perl_call_sv(instance_func, G_VOID);

    SPAGAIN;
    PUTBACK;
    FREETMPS;
    LEAVE;
}

int
instance_wrapper(pmInDom indom, int a, char *b, pmInResult **rp, pmdaExt *pmda)
{
    if (need_refresh)
	pmns_refresh();
    if (instance_func)
	preinstance(instance_index(indom));
    return pmdaInstance(indom, a, b, rp, pmda);
}

void
timer_callback(int afid, void *data)
{
    dSP;
    ENTER;
    SAVETMPS;
    PUSHMARK(sp);
    XPUSHs(sv_2mortal(newSViv(local_timer_get_cookie(afid))));
    PUTBACK;

    perl_call_sv(local_timer_get_callback(afid), G_VOID);

    SPAGAIN;
    PUTBACK;
    FREETMPS;
    LEAVE;
}

void
input_callback(SV *input_cb_func, int data, char *string)
{
    dSP;
    ENTER;
    SAVETMPS;
    PUSHMARK(sp);
    XPUSHs(sv_2mortal(newSViv(data)));
    XPUSHs(sv_2mortal(newSVpv(string,0)));
    PUTBACK;

    perl_call_sv(input_cb_func, G_VOID);

    SPAGAIN;
    PUTBACK;
    FREETMPS;
    LEAVE;
}

int
fetch_callback(pmdaMetric *metric, unsigned int inst, pmAtomValue *atom)
{
    dSP;
    __pmID_int	*pmid;
    int		sts;
    STRLEN	n_a;	/* required by older Perl versions, used in POPpx */

    ENTER;
    SAVETMPS;	/* allows us to tidy our perl stack changes later */

    (void)n_a;
    pmid = (__pmID_int *) &metric->m_desc.pmid;

    PUSHMARK(sp);
    XPUSHs(sv_2mortal(newSVuv(pmid->cluster)));
    XPUSHs(sv_2mortal(newSVuv(pmid->item)));
    XPUSHs(sv_2mortal(newSVuv(inst)));
    PUTBACK;

    sts = perl_call_sv(fetch_cb_func, G_ARRAY);
    SPAGAIN;	/* refresh local perl stack pointer after call */
    if (sts != 2) {
	croak("fetch CB error (returned %d values, expected 2)", sts); 
	sts = -EINVAL;
	goto fetch_end;
    }
    sts = POPi;		/* pop function return status */
    if (sts < 0) {
	goto fetch_end;
    }
    else if (sts == 0) {
	sts = POPi;
	goto fetch_end;
    }

    sts = PMDA_FETCH_STATIC;
    switch (metric->m_desc.type) {	/* pop result value */
	case PM_TYPE_32:	atom->l = POPi; break;
	case PM_TYPE_U32:	atom->ul = POPi; break;
	case PM_TYPE_64:	atom->ll = POPl; break;
	case PM_TYPE_U64:	atom->ull = POPl; break;
	case PM_TYPE_FLOAT:	atom->f = POPn; break;
	case PM_TYPE_DOUBLE:	atom->d = POPn; break;
	case PM_TYPE_STRING:	{
	    atom->cp = strdup(POPpx);
	    sts = PMDA_FETCH_DYNAMIC;
	    break;
	}
    }

fetch_end:
    PUTBACK;
    FREETMPS;
    LEAVE;	/* fix up the perl stack, freeing anything we created */
    return sts;
}

int
store_callback(__pmID_int *pmid, unsigned int inst, pmAtomValue av, int type)
{
    dSP;
    int sts;
    ENTER;
    SAVETMPS;
    PUSHMARK(sp);
    XPUSHs(sv_2mortal(newSVuv(pmid->cluster)));
    XPUSHs(sv_2mortal(newSVuv(pmid->item)));
    XPUSHs(sv_2mortal(newSVuv(inst)));
    switch (type) {
	case PM_TYPE_32:     XPUSHs(sv_2mortal(newSViv(av.l))); break;
	case PM_TYPE_U32:    XPUSHs(sv_2mortal(newSVuv(av.ul))); break;
	case PM_TYPE_64:     XPUSHs(sv_2mortal(newSVuv(av.ll))); break;
	case PM_TYPE_U64:    XPUSHs(sv_2mortal(newSVuv(av.ull))); break;
	case PM_TYPE_FLOAT:  XPUSHs(sv_2mortal(newSVnv(av.f))); break;
	case PM_TYPE_DOUBLE: XPUSHs(sv_2mortal(newSVnv(av.d))); break;
	case PM_TYPE_STRING: XPUSHs(sv_2mortal(newSVpv(av.cp,0)));break;
    }
    PUTBACK;

    sts = perl_call_sv(store_cb_func, G_SCALAR);
    SPAGAIN;	/* refresh local perl stack pointer after call */
    if (sts != 1) {
	croak("store CB error (returned %d values, expected 1)", sts); 
	sts = -EINVAL;
	goto store_end;
    }
    sts = POPi;				/* pop function return status */

store_end:
    PUTBACK;
    FREETMPS;
    LEAVE;	/* fix up the perl stack, freeing anything we created */
    return sts;
}

int
store(pmdaResult *result, pmdaExt *pmda)
{
    int		i, j;
    int		type;
    int		sts;
    pmAtomValue	av;
    pmValueSet	*vsp;
    __pmID_int	*pmid;

    if (need_refresh)
	pmns_refresh();

    pmdaStore(result, pmda);	/* setup context */

    for (i = 0; i < result->numpmid; i++) {
	vsp = result->vset[i];
	pmid = (__pmID_int *)&vsp->pmid;

	/* need to find the type associated with this PMID */
	for (j = 0; j < mtab_size; j++)
	    if (metrictab[j].m_desc.pmid == *(pmID *)pmid)
		break;
	if (j == mtab_size)
	    return PM_ERR_PMID;
	type = metrictab[j].m_desc.type;

	for (j = 0; j < vsp->numval; j++) {
	    sts = pmExtractValue(vsp->valfmt, &vsp->vlist[j],type, &av, type);
	    if (sts < 0)
		return sts;
	    sts = store_callback(pmid, vsp->vlist[j].inst, av, type);
	    if (sts < 0)
		return sts;
	}
    }
    return 0;
}

int
text(int ident, int type, char **buffer, pmdaExt *pmda)
{
    const char *hash;
    int size;
    SV **sv;
    HV *hv;

    if (need_refresh)
	pmns_refresh();

    if ((type & PM_TEXT_PMID) == PM_TEXT_PMID) {
	hash = pmIDStr((pmID)ident);
	size = strlen(hash);
	if (type & PM_TEXT_ONELINE)
	    hv = metric_oneline;
	else
	    hv = metric_helptext;
    }
    else {
	hash = pmInDomStr((pmInDom)ident);
	size = strlen(hash);
	if (type & PM_TEXT_ONELINE)
	    hv = indom_oneline;
	else
	    hv = indom_helptext;
    }
    if (hv_exists(hv, hash, size))
	sv = hv_fetch(hv, hash, size, 0);
    else
	sv = NULL;

    if (sv && (*sv))
	*buffer = SvPV_nolen(*sv);
    else
	*buffer = NULL;
    return (*buffer == NULL) ? PM_ERR_TEXT : 0;
}

/*
 * Converts Perl hash ref like {'foo' => \&data, 'boo' => \&data}
 * into an instance structure (indom).
 */
static int
update_hash_indom(SV *insts, pmInDom indom)
{
    int sts;
    SV *data;
    I32 instsize;
    char *instance;
    HV *ihash = (HV *) SvRV(insts);

    sts = pmdaCacheOp(indom, PMDA_CACHE_INACTIVE);
    if (sts < 0)
	warn("pmda cache inactivation failed: %s", pmErrStr(sts));

    hv_iterinit(ihash);
    while ((data = hv_iternextsv(ihash, &instance, &instsize)) != NULL)
	pmdaCacheStore(indom, PMDA_CACHE_ADD, instance, SvREFCNT_inc(data));

    sts = pmdaCacheOp(indom, PMDA_CACHE_SAVE);
    if (sts < 0)
	warn("pmda cache persistence failed: %s", pmErrStr(sts));

    return 0;
}

/*
 * Free all memory associated with a Perl list based indom
 */
static void
release_list_indom(pmdaInstid *instances, int numinst)
{
    int i;

    if (instances && numinst > 0) {
	for (i = 0; i < numinst; i++)
	    free(instances[i].i_name);	/* update_list_indom strdup */
	free(instances);	/* update_list_indom calloc */
    }
}

/*
 * Converts Perl list ref like [a => 'foo', b => 'boo'] into an indom.
 */
static int
update_list_indom(SV *insts, pmdaInstid **set)
{
    int	i, len;
    SV **id;
    SV **name;
    AV *ilist = (AV *) SvRV(insts);
    pmdaInstid *instances;

    if ((len = av_len(ilist)) == -1) {	/* empty */
	*set = NULL;
	return 0;
    }
    if (len++ % 2 == 0) {
	warn("invalid instance list (length must be a multiple of 2)");
	return -1;
    }

    len /= 2;
    instances = (pmdaInstid *) calloc(len, sizeof(pmdaInstid));
    if (instances == NULL) {
	warn("insufficient memory for instance array");
	return -1;
    }
    for (i = 0; i < len; i++) {
	id = av_fetch(ilist,i*2,0);
	name = av_fetch(ilist,i*2+1,0);
	instances[i].i_inst = SvIV(*id);
	instances[i].i_name = strdup(SvPV_nolen(*name));
	if (instances[i].i_name == NULL) {
	    release_list_indom(instances, i);
	    warn("insufficient memory for instance array names");
	    return -1;
	}
    }
    *set = instances;
    return len;
}

/*
 * Reload a Perl instance reference into a populated indom.
 * This interface allows either the hash or list formats,
 * but only the hash format can be persisted and reloaded.
 */
static int
reload_indom(SV *insts, pmInDom indom)
{
    SV *rv = (SV *) SvRV(insts);

    if (! SvROK(insts)) {
	warn("expected a reference for instances argument");
	return -1;
    }
    if (SvTYPE(rv) == SVt_PVHV)
	(void) pmdaCacheOp(indom, PMDA_CACHE_LOAD);
    else if (SvTYPE(rv) != SVt_PVAV)
        warn("instance argument is neither an array nor hash reference");
    return 0;
}

/*
 * Converts a Perl instance reference into a populated indom.
 * This interface handles either the hash or list formats.
 */
static int
update_indom(SV *insts, pmInDom indom, pmdaInstid **set)
{
    SV *rv = (SV *) SvRV(insts);

    if (! SvROK(insts)) {
	warn("expected a reference for instances argument");
	return -1;
    }
    if (SvTYPE(rv) == SVt_PVAV)
	return update_list_indom(insts, set);
    if (SvTYPE(rv) == SVt_PVHV)
	return update_hash_indom(insts, indom);
    warn("instance argument is neither an array nor hash reference");
    return -1;
}


#line 630 "PMDA.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

/* simple backcompat versions of the TARGx() macros with no optimisation */
#ifndef TARGi
#  define TARGi(iv, do_taint) sv_setiv_mg(TARG, iv)
#  define TARGu(uv, do_taint) sv_setuv_mg(TARG, uv)
#  define TARGn(nv, do_taint) sv_setnv_mg(TARG, nv)
#endif

#line 781 "PMDA.c"

XS_EUPXS(XS_PCP__PMDA_new); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_new)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "CLASS, name, domain");
    {
	char *	CLASS = (char *)SvPV_nolen(ST(0))
;
	char *	name = (char *)SvPV_nolen(ST(1))
;
	int	domain = (int)SvIV(ST(2))
;
#line 629 "PMDA.xs"
	int	sep;
	char *	p;
	char *	logfile;
	char *	pmdaname;
	char	helpfile[256];
#line 802 "PMDA.c"
	pmdaInterface *	RETVAL;
#line 635 "PMDA.xs"
	RETVAL = &dispatch;
	logfile = local_strdup_suffix(name, ".log");
	pmdaname = local_strdup_prefix("pmda", name);
	pmSetProgname(pmdaname);
	sep = pmPathSeparator();
	if ((p = getenv("PCP_PERL_DEBUG")) != NULL) {
	    if (pmSetDebug(p) < 0)
		fprintf(stderr, "unrecognized debug options specification (%s)\n", p);
	}
#ifndef IS_MINGW
	setsid();
#endif
	atexit(&local_atexit);
	pmsprintf(helpfile, sizeof(helpfile), "%s%c%s%c" "help",
			pmGetConfig("PCP_PMDAS_DIR"), sep, name, sep);
	if (access(helpfile, R_OK) != 0) {
	    pmdaDaemon(&dispatch, PMDA_INTERFACE_5, pmdaname, domain,
			logfile, NULL);
	    dispatch.version.four.text = text;
	}
	else {
	    pmdaDaemon(&dispatch, PMDA_INTERFACE_5, pmdaname, domain,
			logfile, helpfile);
	}
	dispatch.version.four.fetch = fetch_wrapper;
	dispatch.version.four.instance = instance_wrapper;
	dispatch.version.four.desc = pmns_desc;
	dispatch.version.four.pmid = pmns_pmid;
	dispatch.version.four.name = pmns_name;
	dispatch.version.four.children = pmns_children;

	if (!local_install())
	    pmdaOpenLog(&dispatch);
	metric_names = newHV();
	metric_oneline = newHV();
	metric_helptext = newHV();
	indom_helptext = newHV();
	indom_oneline = newHV();
#line 843 "PMDA.c"
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    sv_setref_pv( RETVALSV, CLASS, (void*)RETVAL );
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_pmda_pmid); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_pmda_pmid)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "cluster, item");
    {
	unsigned int	cluster = (unsigned int)SvUV(ST(0))
;
	unsigned int	item = (unsigned int)SvUV(ST(1))
;
	int	RETVAL;
	dXSTARG;
#line 681 "PMDA.xs"
	RETVAL = pmID_build(dispatch.domain, cluster, item);
#line 870 "PMDA.c"
	TARGi((IV)RETVAL, 1);
	ST(0) = TARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_pmda_pmid_name); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_pmda_pmid_name)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "cluster, item");
    {
	unsigned int	cluster = (unsigned int)SvUV(ST(0))
;
	unsigned int	item = (unsigned int)SvUV(ST(1))
;
#line 690 "PMDA.xs"
	const char	*name;
	SV		**rval;
#line 892 "PMDA.c"
	SV *	RETVAL;
#line 693 "PMDA.xs"
	name = pmIDStr(pmID_build(dispatch.domain, cluster, item));
	rval = hv_fetch(metric_names, name, strlen(name), 0);
	if (!rval || !(*rval))
	    XSRETURN_UNDEF;
	RETVAL = newSVsv(*rval);
#line 900 "PMDA.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_pmda_pmid_text); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_pmda_pmid_text)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "cluster, item");
    {
	unsigned int	cluster = (unsigned int)SvUV(ST(0))
;
	unsigned int	item = (unsigned int)SvUV(ST(1))
;
#line 706 "PMDA.xs"
	const char	*name;
	SV		**rval;
#line 922 "PMDA.c"
	SV *	RETVAL;
#line 709 "PMDA.xs"
	name = pmIDStr(pmID_build(dispatch.domain, cluster, item));
	rval = hv_fetch(metric_oneline, name, strlen(name), 0);
	if (!rval || !(*rval))
	    XSRETURN_UNDEF;
	RETVAL = newSVsv(*rval);
#line 930 "PMDA.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_pmda_inst_name); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_pmda_inst_name)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "index, instance");
    {
	unsigned int	index = (unsigned int)SvUV(ST(0))
;
	int	instance = (int)SvIV(ST(1))
;
#line 722 "PMDA.xs"
	int		i, sts;
	char *		name;
	pmdaIndom *	p;
#line 953 "PMDA.c"
	SV *	RETVAL;
#line 726 "PMDA.xs"
	if (index >= itab_size)	/* is this a valid indom */
	    XSRETURN_UNDEF;
	p = indomtab + index;
	if (!p->it_set)	{ /* was this indom previously setup via a hash? */
	    sts = pmdaCacheLookup(p->it_indom, instance, &name, NULL);
	    if (sts != PMDA_CACHE_ACTIVE)
		XSRETURN_UNDEF;
	    RETVAL = newSVpv(name,0);
	}
	else {	/* we've been handed an array-based indom */
	    /* Optimistic (fast) direct lookup first, then iterate */
	    i = instance;
	    if (i > p->it_numinst || i < 0 || instance != p->it_set[i].i_inst) {
		for (i = 0; i < p->it_numinst; i++)
		    if (instance == p->it_set[i].i_inst)
			break;
		if (i == p->it_numinst)
		    XSRETURN_UNDEF;
	    }
	    RETVAL = newSVpv(p->it_set[i].i_name,0);
	}
#line 977 "PMDA.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_pmda_inst_lookup); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_pmda_inst_lookup)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "index, instance");
    {
	unsigned int	index = (unsigned int)SvUV(ST(0))
;
	int	instance = (int)SvIV(ST(1))
;
#line 755 "PMDA.xs"
	pmdaIndom *	p;
	SV *		svp;
	int		sts;
#line 1000 "PMDA.c"
	SV *	RETVAL;
#line 759 "PMDA.xs"
	if (index >= itab_size)	/* is this a valid indom */
	    XSRETURN_UNDEF;
	p = indomtab + index;
	if (p->it_set)	/* was this indom previously setup via an array? */
	    XSRETURN_UNDEF;
	sts = pmdaCacheLookup(p->it_indom, instance, NULL, (void *)&svp);
	if (sts != PMDA_CACHE_ACTIVE)
	    XSRETURN_UNDEF;
	RETVAL = SvREFCNT_inc(svp);
#line 1012 "PMDA.c"
	RETVAL = sv_2mortal(RETVAL);
	ST(0) = RETVAL;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_pmda_units); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_pmda_units)
{
    dVAR; dXSARGS;
    if (items != 6)
       croak_xs_usage(cv,  "dim_space, dim_time, dim_count, scale_space, scale_time, scale_count");
    {
	unsigned int	dim_space = (unsigned int)SvUV(ST(0))
;
	unsigned int	dim_time = (unsigned int)SvUV(ST(1))
;
	unsigned int	dim_count = (unsigned int)SvUV(ST(2))
;
	unsigned int	scale_space = (unsigned int)SvUV(ST(3))
;
	unsigned int	scale_time = (unsigned int)SvUV(ST(4))
;
	unsigned int	scale_count = (unsigned int)SvUV(ST(5))
;
#line 780 "PMDA.xs"
	pmUnits	units;
#line 1041 "PMDA.c"
	int	RETVAL;
	dXSTARG;
#line 782 "PMDA.xs"
	units.pad = 0;
	units.dimSpace = dim_space;	units.scaleSpace = scale_space;
	units.dimTime = dim_time;	units.scaleTime = scale_time;
	units.dimCount = dim_count;	units.scaleCount = scale_count;
	RETVAL = *(int *)(&units);
#line 1050 "PMDA.c"
	TARGi((IV)RETVAL, 1);
	ST(0) = TARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_pmda_config); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_pmda_config)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "name");
    {
	char *	name = (char *)SvPV_nolen(ST(0))
;
	char *	RETVAL;
	dXSTARG;
#line 794 "PMDA.xs"
	RETVAL = pmGetConfig(name);
	if (!RETVAL)
	    XSRETURN_UNDEF;
#line 1073 "PMDA.c"
	sv_setpv((SV*)TARG, RETVAL);
	ST(0) = TARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_pmda_uptime); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_pmda_uptime)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "now");
    {
	int	now = (int)SvIV(ST(0))
;
#line 804 "PMDA.xs"
	static char s[32];
	size_t sz = sizeof(s);
	int days, hours, mins, secs;
#line 1094 "PMDA.c"
	char *	RETVAL;
	dXSTARG;
#line 808 "PMDA.xs"
	days = now / (60 * 60 * 24);
	now %= (60 * 60 * 24);
	hours = now / (60 * 60);
	now %= (60 * 60);
	mins = now / 60;
	now %= 60;
	secs = now;

	if (days > 1)
	    pmsprintf(s, sz, "%ddays %02d:%02d:%02d", days, hours, mins, secs);
	else if (days == 1)
	    pmsprintf(s, sz, "%dday %02d:%02d:%02d", days, hours, mins, secs);
	else
	    pmsprintf(s, sz, "%02d:%02d:%02d", hours, mins, secs);
	RETVAL = s;
#line 1113 "PMDA.c"
	sv_setpv((SV*)TARG, RETVAL);
	ST(0) = TARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_pmda_long); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_pmda_long)
{
    dVAR; dXSARGS;
    if (items != 0)
       croak_xs_usage(cv,  "");
    {
	int	RETVAL;
	dXSTARG;
#line 829 "PMDA.xs"
	RETVAL = (sizeof(long) == 4) ? PM_TYPE_32 : PM_TYPE_64;
#line 1132 "PMDA.c"
	TARGi((IV)RETVAL, 1);
	ST(0) = TARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_pmda_ulong); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_pmda_ulong)
{
    dVAR; dXSARGS;
    if (items != 0)
       croak_xs_usage(cv,  "");
    {
	int	RETVAL;
	dXSTARG;
#line 836 "PMDA.xs"
	RETVAL = (sizeof(unsigned long) == 4) ? PM_TYPE_U32 : PM_TYPE_U64;
#line 1151 "PMDA.c"
	TARGi((IV)RETVAL, 1);
	ST(0) = TARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_pmda_install); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_pmda_install)
{
    dVAR; dXSARGS;
    if (items != 0)
       croak_xs_usage(cv,  "");
    {
	int	RETVAL;
	dXSTARG;
#line 843 "PMDA.xs"
	RETVAL = local_install();
#line 1170 "PMDA.c"
	TARGi((IV)RETVAL, 1);
	ST(0) = TARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_error); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_error)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "self, message");
    {
	pmdaInterface *	self;
	char *	message = (char *)SvPV_nolen(ST(1))
;
#line 852 "PMDA.xs"
	(void)self;
#line 1190 "PMDA.c"

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::error() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 854 "PMDA.xs"
	pmNotifyErr(LOG_ERR, "%s", message);
#line 1201 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_PCP__PMDA_set_user); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_set_user)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "self, username");
    {
	pmdaInterface *	self;
	char *	username = (char *)SvPV_nolen(ST(1))
;
#line 861 "PMDA.xs"
	(void)self;
#line 1219 "PMDA.c"
	int	RETVAL;
	dXSTARG;

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::set_user() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 863 "PMDA.xs"
	RETVAL = pmSetProcessIdentity(username);
#line 1232 "PMDA.c"
	TARGi((IV)RETVAL, 1);
	ST(0) = TARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_set_fetch); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_set_fetch)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "self, function");
    {
	pmdaInterface *	self;
	SV *	function = ST(1)
;
#line 872 "PMDA.xs"
	(void)self;
#line 1252 "PMDA.c"

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::set_fetch() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 874 "PMDA.xs"
	if (function != (SV *)NULL) {
	    fetch_func = newSVsv(function);
	}
#line 1265 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_PCP__PMDA_set_refresh); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_set_refresh)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "self, function");
    {
	pmdaInterface *	self;
	SV *	function = ST(1)
;
#line 883 "PMDA.xs"
	(void)self;
#line 1283 "PMDA.c"

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::set_refresh() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 885 "PMDA.xs"
	if (function != (SV *)NULL) {
	    refresh_func = newSVsv(function);
	}
#line 1296 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_PCP__PMDA_set_instance); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_set_instance)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "self, function");
    {
	pmdaInterface *	self;
	SV *	function = ST(1)
;
#line 894 "PMDA.xs"
	(void)self;
#line 1314 "PMDA.c"

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::set_instance() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 896 "PMDA.xs"
	if (function != (SV *)NULL) {
	    instance_func = newSVsv(function);
	}
#line 1327 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_PCP__PMDA_set_store_callback); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_set_store_callback)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "self, cb_function");
    {
	pmdaInterface *	self;
	SV *	cb_function = ST(1)
;

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::set_store_callback() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 905 "PMDA.xs"
	if (cb_function != (SV *)NULL) {
	    store_cb_func = newSVsv(cb_function);
	    self->version.four.store = store;
	}
#line 1356 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_PCP__PMDA_set_fetch_callback); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_set_fetch_callback)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "self, cb_function");
    {
	pmdaInterface *	self;
	SV *	cb_function = ST(1)
;

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::set_fetch_callback() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 915 "PMDA.xs"
	if (cb_function != (SV *)NULL) {
	    fetch_cb_func = newSVsv(cb_function);
	    pmdaSetFetchCallBack(self, fetch_callback);
	}
#line 1385 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_PCP__PMDA_set_inet_socket); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_set_inet_socket)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "self, port");
    {
	pmdaInterface *	self;
	int	port = (int)SvIV(ST(1))
;

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::set_inet_socket() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 925 "PMDA.xs"
	self->version.four.ext->e_io = pmdaInet;
	self->version.four.ext->e_port = port;
#line 1412 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_PCP__PMDA_set_ipv6_socket); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_set_ipv6_socket)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "self, port");
    {
	pmdaInterface *	self;
	int	port = (int)SvIV(ST(1))
;

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::set_ipv6_socket() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 933 "PMDA.xs"
	self->version.four.ext->e_io = pmdaIPv6;
	self->version.four.ext->e_port = port;
#line 1439 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_PCP__PMDA_set_unix_socket); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_set_unix_socket)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "self, socket_name");
    {
	pmdaInterface *	self;
	char *	socket_name = (char *)SvPV_nolen(ST(1))
;

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::set_unix_socket() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 941 "PMDA.xs"
	self->version.four.ext->e_io = pmdaUnix;
	self->version.four.ext->e_sockname = socket_name;
#line 1466 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_PCP__PMDA_clear_metrics); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_clear_metrics)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "self");
    {
	pmdaInterface *	self;
#line 948 "PMDA.xs"
	(void)self;
#line 1482 "PMDA.c"

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::clear_metrics() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 950 "PMDA.xs"
	need_refresh = 1;
	if (clustertab)
	    free(clustertab);
	ctab_size = 0;
	if (metrictab)
	    free(metrictab);
	mtab_size = 0;
	hv_clear(metric_names);
	hv_clear(metric_oneline);
	hv_clear(metric_helptext);
#line 1502 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_PCP__PMDA_add_metric); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_add_metric)
{
    dVAR; dXSARGS;
    if (items != 9)
       croak_xs_usage(cv,  "self, pmid, type, indom, sem, units, name, help, longhelp");
    {
	pmdaInterface *	self;
	int	pmid = (int)SvIV(ST(1))
;
	int	type = (int)SvIV(ST(2))
;
	int	indom = (int)SvIV(ST(3))
;
	int	sem = (int)SvIV(ST(4))
;
	int	units = (int)SvIV(ST(5))
;
	char *	name = (char *)SvPV_nolen(ST(6))
;
	char *	help = (char *)SvPV_nolen(ST(7))
;
	char *	longhelp = (char *)SvPV_nolen(ST(8))
;
#line 973 "PMDA.xs"
	pmdaMetric * p;
	__pmID_int * pmidp;
	const char * hash;
	int          size;
	(void)self;
#line 1538 "PMDA.c"

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::add_metric() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 979 "PMDA.xs"
	need_refresh = 1;
	pmidp = (__pmID_int *)&pmid;
	if (!clustertab_lookup(pmidp->cluster)) {
	    size = sizeof(int) * (ctab_size + 1);
	    clustertab = (int *)realloc(clustertab, size);
	    if (clustertab)
		clustertab[ctab_size++] = pmidp->cluster;
	    else {
		warn("unable to allocate memory for cluster table");
		ctab_size = 0;
		XSRETURN_UNDEF;
	    }
	}

	size = sizeof(pmdaMetric) * (mtab_size + 1);
	metrictab = (pmdaMetric *)realloc(metrictab, size);
	if (metrictab == NULL) {
	    warn("unable to allocate memory for metric table");
	    mtab_size = 0;
	    XSRETURN_UNDEF;
	}

	p = metrictab + mtab_size++;
	p->m_user = NULL;	p->m_desc.pmid = *(pmID *)&pmid;
	p->m_desc.type = type;	p->m_desc.indom = *(pmInDom *)&indom;
	p->m_desc.sem = sem;	p->m_desc.units = *(pmUnits *)&units;

	hash = pmIDStr(pmid);
	size = strlen(hash);
	hv_store(metric_names, hash, size, newSVpv(name,0), 0);
	if (help)
	    hv_store(metric_oneline, hash, size, newSVpv(help,0), 0);
	if (longhelp)
	    hv_store(metric_helptext, hash, size, newSVpv(longhelp,0), 0);
#line 1582 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_PCP__PMDA_clear_indoms); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_clear_indoms)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "self");
    {
	pmdaInterface *	self;
#line 1018 "PMDA.xs"
	(void)self;
#line 1598 "PMDA.c"

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::clear_indoms() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 1020 "PMDA.xs"
	if (indomtab)
	    free(indomtab);
	itab_size = 0;
	if (metrictab)
	    free(metrictab);
	mtab_size = 0;
	hv_clear(indom_oneline);
	hv_clear(indom_helptext);
#line 1616 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_PCP__PMDA_add_indom); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_add_indom)
{
    dVAR; dXSARGS;
    if (items != 5)
       croak_xs_usage(cv,  "self, indom, insts, help, longhelp");
    {
	pmdaInterface *	self;
	int	indom = (int)SvIV(ST(1))
;
	SV *	insts = ST(2)
;
	char *	help = (char *)SvPV_nolen(ST(3))
;
	char *	longhelp = (char *)SvPV_nolen(ST(4))
;
#line 1037 "PMDA.xs"
	pmdaIndom  * p;
	const char * hash;
	int          sts, size;
	(void)self;
#line 1643 "PMDA.c"
	int	RETVAL;
	dXSTARG;

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::add_indom() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 1042 "PMDA.xs"
	size = sizeof(pmdaIndom) * (itab_size + 1);
	indomtab = (pmdaIndom *)realloc(indomtab, size);
	if (indomtab == NULL) {
	    warn("unable to allocate memory for indom table");
	    itab_size = 0;
	    XSRETURN_UNDEF;
	}
	indom = pmInDom_build(self->domain, indom);
	reload_indom(insts, indom);

	p = indomtab + itab_size;
	memset(p, 0, sizeof(pmdaIndom));
	p->it_indom = indom;

	sts = update_indom(insts, indom, &p->it_set);
	if (sts < 0)
	    XSRETURN_UNDEF;
	p->it_numinst = sts;
	RETVAL = itab_size++;	/* used in calls to replace_indom() */

	hash = pmInDomStr(indom);
	size = strlen(hash);
	if (help)
	    hv_store(indom_oneline, hash, size, newSVpv(help,0), 0);
	if (longhelp)
	    hv_store(indom_helptext, hash, size, newSVpv(longhelp,0), 0);
#line 1681 "PMDA.c"
	TARGi((IV)RETVAL, 1);
	ST(0) = TARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_replace_indom); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_replace_indom)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "self, index, insts");
    {
	pmdaInterface *	self;
	unsigned int	index = (unsigned int)SvUV(ST(1))
;
	SV *	insts = ST(2)
;
#line 1077 "PMDA.xs"
	pmdaIndom *	p;
	int		sts;
	(void)self;
#line 1705 "PMDA.c"
	int	RETVAL;
	dXSTARG;

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::replace_indom() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 1081 "PMDA.xs"
	if (index >= itab_size) {
	    warn("attempt to replace non-existent instance domain");
	    XSRETURN_UNDEF;
	}
	else {
	    p = indomtab + index;
	    /* was this indom previously setup via an array? */
	    if (p->it_set) {
		release_list_indom(p->it_set, p->it_numinst);
		p->it_numinst = 0;
	    }
	    sts = update_indom(insts, p->it_indom, &p->it_set);
	    if (sts < 0)
		XSRETURN_UNDEF;
	    p->it_numinst = sts;
	    RETVAL = sts;
	}
#line 1734 "PMDA.c"
	TARGi((IV)RETVAL, 1);
	ST(0) = TARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_load_indom); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_load_indom)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "self, index");
    {
	pmdaInterface *	self;
	unsigned int	index = (unsigned int)SvUV(ST(1))
;
#line 1106 "PMDA.xs"
	pmdaIndom *	p;
	int		sts;
	(void)self;
#line 1756 "PMDA.c"
	int	RETVAL;
	dXSTARG;

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::load_indom() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 1110 "PMDA.xs"
	if (index >= itab_size) {
	    warn("attempt to load non-existent instance domain");
	    XSRETURN_UNDEF;
	}
	else {
	    p = indomtab + index;
	    /* is this indom setup via an array? (must be hash) */
	    if (p->it_set) {
		warn("cannot load an array instance domain");
		XSRETURN_UNDEF;
	    }
	    sts = pmdaCacheOp(p->it_indom, PMDA_CACHE_LOAD);
	    if (sts < 0)
		warn("pmda cache load failed: %s", pmErrStr(sts));
	    RETVAL = sts;
	}
#line 1784 "PMDA.c"
	TARGi((IV)RETVAL, 1);
	ST(0) = TARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_add_timer); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_add_timer)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "self, timeout, callback, data");
    {
	pmdaInterface *	self;
	double	timeout = (double)SvNV(ST(1))
;
	SV *	callback = ST(2)
;
	int	data = (int)SvIV(ST(3))
;
#line 1136 "PMDA.xs"
	(void)self;
#line 1808 "PMDA.c"
	int	RETVAL;
	dXSTARG;

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::add_timer() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 1138 "PMDA.xs"
	if (local_install() || !callback)
	    XSRETURN_UNDEF;
	RETVAL = local_timer(timeout, newSVsv(callback), data);
#line 1823 "PMDA.c"
	TARGi((IV)RETVAL, 1);
	ST(0) = TARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_add_pipe); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_add_pipe)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "self, command, callback, data");
    {
	pmdaInterface *	self;
	char *	command = (char *)SvPV_nolen(ST(1))
;
	SV *	callback = ST(2)
;
	int	data = (int)SvIV(ST(3))
;
#line 1151 "PMDA.xs"
	(void)self;
#line 1847 "PMDA.c"
	int	RETVAL;
	dXSTARG;

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::add_pipe() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 1153 "PMDA.xs"
	if (local_install() || !callback)
	    XSRETURN_UNDEF;
	RETVAL = local_pipe(command, newSVsv(callback), data);
#line 1862 "PMDA.c"
	TARGi((IV)RETVAL, 1);
	ST(0) = TARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_add_tail); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_add_tail)
{
    dVAR; dXSARGS;
    if (items != 4)
       croak_xs_usage(cv,  "self, filename, callback, data");
    {
	pmdaInterface *	self;
	char *	filename = (char *)SvPV_nolen(ST(1))
;
	SV *	callback = ST(2)
;
	int	data = (int)SvIV(ST(3))
;
#line 1166 "PMDA.xs"
	(void)self;
#line 1886 "PMDA.c"
	int	RETVAL;
	dXSTARG;

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::add_tail() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 1168 "PMDA.xs"
	if (local_install() || !callback)
	    XSRETURN_UNDEF;
	RETVAL = local_tail(filename, newSVsv(callback), data);
#line 1901 "PMDA.c"
	TARGi((IV)RETVAL, 1);
	ST(0) = TARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_add_sock); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_add_sock)
{
    dVAR; dXSARGS;
    if (items != 5)
       croak_xs_usage(cv,  "self, hostname, port, callback, data");
    {
	pmdaInterface *	self;
	char *	hostname = (char *)SvPV_nolen(ST(1))
;
	int	port = (int)SvIV(ST(2))
;
	SV *	callback = ST(3)
;
	int	data = (int)SvIV(ST(4))
;
#line 1182 "PMDA.xs"
	(void)self;
#line 1927 "PMDA.c"
	int	RETVAL;
	dXSTARG;

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::add_sock() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 1184 "PMDA.xs"
	if (local_install() || !callback)
	    XSRETURN_UNDEF;
	RETVAL = local_sock(hostname, port, newSVsv(callback), data);
#line 1942 "PMDA.c"
	TARGi((IV)RETVAL, 1);
	ST(0) = TARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_put_sock); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_put_sock)
{
    dVAR; dXSARGS;
    if (items != 3)
       croak_xs_usage(cv,  "self, id, output");
    {
	pmdaInterface *	self;
	int	id = (int)SvIV(ST(1))
;
	char *	output = (char *)SvPV_nolen(ST(2))
;
#line 1196 "PMDA.xs"
	size_t	length = strlen(output);
	(void)self;
#line 1965 "PMDA.c"
	int	RETVAL;
	dXSTARG;

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::put_sock() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 1199 "PMDA.xs"
	RETVAL = __pmWrite(local_files_get_descriptor(id), output, length);
#line 1978 "PMDA.c"
	TARGi((IV)RETVAL, 1);
	ST(0) = TARG;
    }
    XSRETURN(1);
}


XS_EUPXS(XS_PCP__PMDA_log); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_log)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "self, message");
    {
	pmdaInterface *	self;
	char *	message = (char *)SvPV_nolen(ST(1))
;
#line 1208 "PMDA.xs"
	(void)self;
#line 1998 "PMDA.c"

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::log() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 1210 "PMDA.xs"
	pmNotifyErr(LOG_INFO, "%s", message);
#line 2009 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_PCP__PMDA_err); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_err)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "self, message");
    {
	pmdaInterface *	self;
	char *	message = (char *)SvPV_nolen(ST(1))
;
#line 1217 "PMDA.xs"
	(void)self;
#line 2027 "PMDA.c"

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::err() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 1219 "PMDA.xs"
	pmNotifyErr(LOG_ERR, "%s", message);
#line 2038 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


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

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::connect_pmcd() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 1225 "PMDA.xs"
	/*
	 * Call pmdaConnect() to complete the PMDA's IPC channel setup
	 * and complete the connection handshake with pmcd.
	 */
	if (!local_install()) {
	    /*
	     * On success pmdaConnect sets PMDA_EXT_CONNECTED in e_flags
	     * ... this is used in the guard below to stop run() calling
	     * pmdaConnect() again.
	     */
	    pmdaConnect(self);
	}
#line 2073 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


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

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::run() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 1242 "PMDA.xs"
	if (getenv("PCP_PERL_PMNS") != NULL)
	    pmns_write();	/* generate ascii namespace */
	else if (getenv("PCP_PERL_DOMAIN") != NULL)
	    domain_write();	/* generate the domain header */
	else {		/* or normal operating mode ... */
	    pmns_refresh();
	    pmdaInit(self, indomtab, itab_size, metrictab, mtab_size);
	    if ((self->version.any.ext->e_flags & PMDA_EXT_CONNECTED) != PMDA_EXT_CONNECTED) {
		/*
		 * connect_pmcd() not called before, so need pmdaConnect()
		 * here before falling into the PDU-driven mainloop
		 */
		pmdaConnect(self);
	    }
	    local_pmdaMain(self);
	}
#line 2112 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_PCP__PMDA_debug_metric); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_debug_metric)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "self");
    {
	pmdaInterface *	self;
#line 1263 "PMDA.xs"
	int	i;
	(void)self;
#line 2129 "PMDA.c"

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::debug_metric() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 1266 "PMDA.xs"
	/* NB: debugging only (used in test.pl to verify state) */
	fprintf(stderr, "metric table size = %d\n", mtab_size);
	for (i = 0; i < mtab_size; i++) {
	    fprintf(stderr, "metric idx = %d\n\tpmid = %s\n\ttype = %u\n"
			"\tindom= %d\n\tsem  = %u\n\tunits= %u\n",
		i, pmIDStr(metrictab[i].m_desc.pmid), metrictab[i].m_desc.type,
		(int)metrictab[i].m_desc.indom, metrictab[i].m_desc.sem,
		*(unsigned int *)&metrictab[i].m_desc.units);
	}
#line 2148 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


XS_EUPXS(XS_PCP__PMDA_debug_indom); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_PCP__PMDA_debug_indom)
{
    dVAR; dXSARGS;
    if (items != 1)
       croak_xs_usage(cv,  "self");
    {
	pmdaInterface *	self;
#line 1280 "PMDA.xs"
	int	i,j;
	(void)self;
#line 2165 "PMDA.c"

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::debug_indom() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 1283 "PMDA.xs"
	/* NB: debugging only (used in test.pl to verify state) */
	fprintf(stderr, "indom table size = %d\n", itab_size);
	for (i = 0; i < itab_size; i++) {
	    fprintf(stderr, "indom idx = %d\n\tindom = %d\n"
			    "\tninst = %u\n\tiptr = " PRINTF_P_PFX "%p\n",
		    i, *(int *)&indomtab[i].it_indom, indomtab[i].it_numinst,
		    indomtab[i].it_set);
	    for (j = 0; j < indomtab[i].it_numinst; j++) {
		fprintf(stderr, "\t\tid=%d name=%s\n",
		    indomtab[i].it_set[j].i_inst, indomtab[i].it_set[j].i_name);
	    }
	}
#line 2187 "PMDA.c"
    }
    XSRETURN_EMPTY;
}


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

	if (sv_isobject(ST(0)) && (SvTYPE(SvRV(ST(0))) == SVt_PVMG))
		self = (pmdaInterface *)((intptr_t)(SvIV((SV *)SvRV(ST(0)))));
	else {
		warn("PCP::PMDA::debug_init() -- self is not a blessed SV reference");
		XSRETURN_UNDEF;
	}
;
#line 1300 "PMDA.xs"
	/* NB: debugging only (used in test.pl to verify state) */
	pmdaInit(self, indomtab, itab_size, metrictab, mtab_size);
#line 2212 "PMDA.c"
    }
    XSRETURN_EMPTY;
}

#ifdef __cplusplus
extern "C" {
#endif
XS_EXTERNAL(boot_PCP__PMDA); /* prototype to pass -Wmissing-prototypes */
XS_EXTERNAL(boot_PCP__PMDA)
{
#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("PCP::PMDA::new", XS_PCP__PMDA_new);
        newXS_deffile("PCP::PMDA::pmda_pmid", XS_PCP__PMDA_pmda_pmid);
        newXS_deffile("PCP::PMDA::pmda_pmid_name", XS_PCP__PMDA_pmda_pmid_name);
        newXS_deffile("PCP::PMDA::pmda_pmid_text", XS_PCP__PMDA_pmda_pmid_text);
        newXS_deffile("PCP::PMDA::pmda_inst_name", XS_PCP__PMDA_pmda_inst_name);
        newXS_deffile("PCP::PMDA::pmda_inst_lookup", XS_PCP__PMDA_pmda_inst_lookup);
        newXS_deffile("PCP::PMDA::pmda_units", XS_PCP__PMDA_pmda_units);
        newXS_deffile("PCP::PMDA::pmda_config", XS_PCP__PMDA_pmda_config);
        newXS_deffile("PCP::PMDA::pmda_uptime", XS_PCP__PMDA_pmda_uptime);
        newXS_deffile("PCP::PMDA::pmda_long", XS_PCP__PMDA_pmda_long);
        newXS_deffile("PCP::PMDA::pmda_ulong", XS_PCP__PMDA_pmda_ulong);
        newXS_deffile("PCP::PMDA::pmda_install", XS_PCP__PMDA_pmda_install);
        newXS_deffile("PCP::PMDA::error", XS_PCP__PMDA_error);
        newXS_deffile("PCP::PMDA::set_user", XS_PCP__PMDA_set_user);
        newXS_deffile("PCP::PMDA::set_fetch", XS_PCP__PMDA_set_fetch);
        newXS_deffile("PCP::PMDA::set_refresh", XS_PCP__PMDA_set_refresh);
        newXS_deffile("PCP::PMDA::set_instance", XS_PCP__PMDA_set_instance);
        newXS_deffile("PCP::PMDA::set_store_callback", XS_PCP__PMDA_set_store_callback);
        newXS_deffile("PCP::PMDA::set_fetch_callback", XS_PCP__PMDA_set_fetch_callback);
        newXS_deffile("PCP::PMDA::set_inet_socket", XS_PCP__PMDA_set_inet_socket);
        newXS_deffile("PCP::PMDA::set_ipv6_socket", XS_PCP__PMDA_set_ipv6_socket);
        newXS_deffile("PCP::PMDA::set_unix_socket", XS_PCP__PMDA_set_unix_socket);
        newXS_deffile("PCP::PMDA::clear_metrics", XS_PCP__PMDA_clear_metrics);
        newXS_deffile("PCP::PMDA::add_metric", XS_PCP__PMDA_add_metric);
        newXS_deffile("PCP::PMDA::clear_indoms", XS_PCP__PMDA_clear_indoms);
        newXS_deffile("PCP::PMDA::add_indom", XS_PCP__PMDA_add_indom);
        newXS_deffile("PCP::PMDA::replace_indom", XS_PCP__PMDA_replace_indom);
        newXS_deffile("PCP::PMDA::load_indom", XS_PCP__PMDA_load_indom);
        newXS_deffile("PCP::PMDA::add_timer", XS_PCP__PMDA_add_timer);
        newXS_deffile("PCP::PMDA::add_pipe", XS_PCP__PMDA_add_pipe);
        newXS_deffile("PCP::PMDA::add_tail", XS_PCP__PMDA_add_tail);
        newXS_deffile("PCP::PMDA::add_sock", XS_PCP__PMDA_add_sock);
        newXS_deffile("PCP::PMDA::put_sock", XS_PCP__PMDA_put_sock);
        newXS_deffile("PCP::PMDA::log", XS_PCP__PMDA_log);
        newXS_deffile("PCP::PMDA::err", XS_PCP__PMDA_err);
        newXS_deffile("PCP::PMDA::connect_pmcd", XS_PCP__PMDA_connect_pmcd);
        newXS_deffile("PCP::PMDA::run", XS_PCP__PMDA_run);
        newXS_deffile("PCP::PMDA::debug_metric", XS_PCP__PMDA_debug_metric);
        newXS_deffile("PCP::PMDA::debug_indom", XS_PCP__PMDA_debug_indom);
        newXS_deffile("PCP::PMDA::debug_init", XS_PCP__PMDA_debug_init);
#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
