OSSP CVS Repository

ossp - ossp-pkg/cfg/perl/cfg.xs
Not logged in
[Honeypot]  [Browse]  [Directory]  [Home]  [Login
[Reports]  [Search]  [Ticket]  [Timeline
  [Raw

ossp-pkg/cfg/perl/cfg.xs
/*
**  OSSP cfg - Configuration Parsing
**  Copyright (c) 2002-2006 Ralf S. Engelschall <rse@engelschall.com>
**  Copyright (c) 2002-2006 The OSSP Project <http://www.ossp.org/>
**
**  This file is part of OSSP cfg, a configuration parsing library which
**  can be found at http://www.ossp.org/pkg/lib/cfg/.
**
**  Permission to use, copy, modify, and distribute this software for
**  any purpose with or without fee is hereby granted, provided that
**  the above copyright notice and this permission notice appear in all
**  copies.
**
**  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
**  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
**  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
**  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
**  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
**  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
**  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
**  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
**  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
**  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
**  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
**  SUCH DAMAGE.
**
**  cfg.xs: Perl Binding (Perl/XS part)
*/

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

#include "cfg.h"

/* find/apply callback context */
typedef struct {
    SV *fct;
    SV *ctx;
} cb_ctx_t;

/* find/apply callback wrapper */
static cfg_rc_t cb_fct(cfg_t *cfg, cfg_node_t *node, void *_ctx)
{
    cb_ctx_t *ctx = (cb_ctx_t *)ctx;
    cfg_rc_t rc;
    dSP;

    ENTER; SAVETMPS;
    PUSHMARK(SP); 
    XPUSHs(sv_2mortal(newSViv(PTR2IV(cfg))));
    XPUSHs(sv_2mortal(newSViv(PTR2IV(node))));
    XPUSHs(ctx->ctx);
    PUTBACK;
    if (call_sv(ctx->fct, G_SCALAR) != 1)
        croak("cfg_node_find: expected single scalar as return value from callback");
    SPAGAIN;
    rc = (cfg_rc_t)SvIV(POPs);
    FREETMPS; LEAVE;
    return rc;
}

MODULE = OSSP::cfg PACKAGE = OSSP::cfg

void
constant(sv)
    PREINIT:
        dXSTARG;
        STRLEN          len;
        int             i;
        static struct {
            const char *name;
            int         value;
        } constant_table[] = {
            { "CFG_OK",                CFG_OK                },
            { "CFG_ERR_ARG",           CFG_ERR_ARG           },
            { "CFG_ERR_USE",           CFG_ERR_USE           },
            { "CFG_ERR_MEM",           CFG_ERR_MEM           },
            { "CFG_ERR_SYS",           CFG_ERR_SYS           },
            { "CFG_ERR_FMT",           CFG_ERR_FMT           },
            { "CFG_ERR_INT",           CFG_ERR_INT           },
            { "CFG_ERR_SYN",           CFG_ERR_SYN           },
            { "CFG_ERR_NDE",           CFG_ERR_NDE           },
            { "CFG_FMT_CFG",           CFG_FMT_CFG           },
            { "CFG_FMT_XML",           CFG_FMT_XML           },
            { "CFG_NODE_TYPE_SEQ",     CFG_NODE_TYPE_SEQ     },
            { "CFG_NODE_TYPE_DIR",     CFG_NODE_TYPE_DIR     },
            { "CFG_NODE_TYPE_OPT",     CFG_NODE_TYPE_OPT     },
            { "CFG_NODE_TYPE_ARG",     CFG_NODE_TYPE_ARG     },
            { "CFG_NODE_ATTR_PARENT",  CFG_NODE_ATTR_PARENT  },
            { "CFG_NODE_ATTR_LBROTH",  CFG_NODE_ATTR_LBROTH  },
            { "CFG_NODE_ATTR_RBROTH",  CFG_NODE_ATTR_RBROTH  },
            { "CFG_NODE_ATTR_CHILD1",  CFG_NODE_ATTR_CHILD1  },
            { "CFG_NODE_ATTR_CHILDL",  CFG_NODE_ATTR_CHILDL  },
            { "CFG_NODE_ATTR_CHILDS",  CFG_NODE_ATTR_CHILDS  },
            { "CFG_NODE_ATTR_NODES",   CFG_NODE_ATTR_NODES   },
            { "CFG_NODE_ATTR_DEPTH",   CFG_NODE_ATTR_DEPTH   },
            { "CFG_NODE_ATTR_SRCNAME", CFG_NODE_ATTR_SRCNAME },
            { "CFG_NODE_ATTR_SRCPOS",  CFG_NODE_ATTR_SRCPOS  },
            { "CFG_NODE_ATTR_TYPE",    CFG_NODE_ATTR_TYPE    },
            { "CFG_NODE_ATTR_TOKEN",   CFG_NODE_ATTR_TOKEN   },
            { "CFG_NODE_ATTR_DATA",    CFG_NODE_ATTR_DATA    },
            { "CFG_DATA_TYPE_PTR",     CFG_DATA_TYPE_PTR     },
            { "CFG_DATA_TYPE_STR",     CFG_DATA_TYPE_STR     },
            { "CFG_DATA_TYPE_INT",     CFG_DATA_TYPE_INT     },
            { "CFG_DATA_TYPE_FLT",     CFG_DATA_TYPE_FLT     },
            { "CFG_DATA_CTRL_CLONE",   CFG_DATA_CTRL_CLONE   },
            { "CFG_DATA_CTRL_DESTROY", CFG_DATA_CTRL_DESTROY },
            { "CFG_DATA_ATTR_TYPE",    CFG_DATA_ATTR_TYPE    },
            { "CFG_DATA_ATTR_VALUE",   CFG_DATA_ATTR_VALUE   },
            { "CFG_DATA_ATTR_CTRL",    CFG_DATA_ATTR_CTRL    }
        };
    INPUT:
        SV         *sv;
        const char *s = SvPV(sv, len);
    PPCODE:
        for (i = 0; i < sizeof(constant_table)/sizeof(constant_table[0]); i++) {
            if (strcmp(s, constant_table[i].name) == 0) {
                EXTEND(SP, 1);
                PUSHs(&PL_sv_undef);
                PUSHi(constant_table[i].value);
                break;
            }
        }
        if (i == sizeof(constant_table)/sizeof(constant_table[0])) {
            sv = sv_2mortal(newSVpvf("unknown contant OSSP::cfg::%s", s));
            PUSHs(sv);
        }

cfg_rc_t
cfg_create(cfg)
    PROTOTYPE:
        $
    INPUT:
        cfg_t *&cfg = NO_INIT
    CODE:
        RETVAL = cfg_create(&cfg);
    OUTPUT:
        cfg
        RETVAL

cfg_rc_t
cfg_destroy(cfg)
    PROTOTYPE:
        $
    INPUT:
        cfg_t *cfg
    CODE:
        RETVAL = cfg_destroy(cfg);
    OUTPUT:
        RETVAL

cfg_rc_t
cfg_error(cfg,rc,error)
    PROTOTYPE:
        $$$
    INPUT:
        cfg_t *cfg
        cfg_rc_t rc
        char *&error = NO_INIT
    CODE:
        RETVAL = cfg_error(cfg, rc, &error);
    OUTPUT:
        error
        RETVAL

long
cfg_version()
    PROTOTYPE:
    INPUT:
    CODE:
        RETVAL = cfg_version();
    OUTPUT:
        RETVAL

cfg_rc_t
cfg_import(cfg,node,fmt,in_ptr,in_len)
    PROTOTYPE:
        $$$$$
    INPUT:
        cfg_t *cfg
        cfg_node_t *node
        cfg_fmt_t fmt
        const char *in_ptr
        size_t in_len
    CODE:
        if (ST(4) == &PL_sv_undef)
            in_len = sv_len(ST(3));
        RETVAL = cfg_import(cfg, node, fmt, in_ptr, in_len);
    OUTPUT:
        RETVAL

cfg_rc_t
cfg_export(cfg,node,fmt,ex_ptr,ex_len)
    PROTOTYPE:
        $$$$$
    INPUT:
        cfg_t *cfg
        cfg_node_t *node
        cfg_fmt_t fmt
        char *&ex_ptr = NO_INIT
        size_t ex_len
    CODE:
        RETVAL = cfg_export(cfg, node, fmt, &ex_ptr, ex_len);
    OUTPUT:
        ex_ptr
        RETVAL

cfg_rc_t
cfg_node_create(cfg,node)
    PROTOTYPE:
        $$
    INPUT:
        cfg_t *cfg
        cfg_node_t *&node = NO_INIT
    CODE:
        RETVAL = cfg_node_create(cfg, &node);
    OUTPUT:
        node
        RETVAL

cfg_rc_t
cfg_node_destroy(cfg,node)
    PROTOTYPE:
        $$
    INPUT:
        cfg_t *cfg
        cfg_node_t *node
    CODE:
        RETVAL = cfg_node_destroy(cfg, node);
    OUTPUT:
        RETVAL

cfg_rc_t
cfg_node_clone(cfg,node,node2)
    PROTOTYPE:
        $$$
    INPUT:
        cfg_t *cfg
        cfg_node_t *node
        cfg_node_t *&node2 = NO_INIT
    CODE:
        RETVAL = cfg_node_clone(cfg, node, &node2);
    OUTPUT:
        node2
        RETVAL

cfg_rc_t
cfg_node_set(cfg,node,attr,va_arg1)
    CASE: (   (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_PARENT \
           || (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_LBROTH \
           || (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_RBROTH \
           || (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_CHILD1 \
           || (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_CHILDL  )
        INPUT:
            cfg_t *cfg
            cfg_node_t *node
            cfg_node_attr_t attr
            cfg_node_t *va_arg1
        CODE:
            RETVAL = cfg_node_set(cfg, node, attr, va_arg1);
        OUTPUT:
            RETVAL
    CASE: (   (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_CHILDS \
           || (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_NODES  \
           || (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_DEPTH  \
           || (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_SRCPOS  )
        INPUT:
            cfg_t *cfg
            cfg_node_t *node
            cfg_node_attr_t attr
            int va_arg1
        CODE:
            RETVAL = cfg_node_set(cfg, node, attr, va_arg1);
        OUTPUT:
            RETVAL
    CASE: (   (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_SRCNAME \
           || (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_TOKEN    )
        INPUT:
            cfg_t *cfg
            cfg_node_t *node
            cfg_node_attr_t attr
            char *va_arg1
        CODE:
            RETVAL = cfg_node_set(cfg, node, attr|CFG_ATTR_COPY, va_arg1);
        OUTPUT:
            RETVAL
    CASE: ((cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_TYPE)
        INPUT:
            cfg_t *cfg
            cfg_node_t *node
            cfg_node_attr_t attr
            cfg_node_type_t va_arg1
        CODE:
            RETVAL = cfg_node_set(cfg, node, attr, va_arg1);
        OUTPUT:
            RETVAL
    CASE: ((cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_DATA)
        INPUT:
            cfg_t *cfg
            cfg_node_t *node
            cfg_node_attr_t attr
            cfg_data_t *va_arg1
        CODE:
            RETVAL = cfg_node_set(cfg, node, attr, va_arg1);
        OUTPUT:
            RETVAL
    CASE: 
        PROTOTYPE:
            $$$;$
        INPUT:
            cfg_t *cfg
            cfg_node_t *node
            cfg_node_attr_t attr
        CODE:
            RETVAL = cfg_node_set(cfg, node, attr);
        OUTPUT:
            RETVAL

cfg_rc_t
cfg_node_get(cfg,node,attr,va_arg1)
    CASE: (   (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_PARENT \
           || (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_LBROTH \
           || (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_RBROTH \
           || (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_CHILD1 \
           || (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_CHILDL  )
        INPUT:
            cfg_t *cfg
            cfg_node_t *node
            cfg_node_attr_t attr
            cfg_node_t *&va_arg1 = NO_INIT
        CODE:
            RETVAL = cfg_node_get(cfg, node, attr, &va_arg1);
        OUTPUT:
            va_arg1
            RETVAL
    CASE: (   (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_CHILDS \
           || (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_NODES  \
           || (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_DEPTH  \
           || (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_SRCPOS  )
        INPUT:
            cfg_t *cfg
            cfg_node_t *node
            cfg_node_attr_t attr
            int &va_arg1 = NO_INIT
        CODE:
            RETVAL = cfg_node_get(cfg, node, attr, &va_arg1);
        OUTPUT:
            va_arg1
            RETVAL
    CASE: (   (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_SRCNAME \
           || (cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_TOKEN    )
        INPUT:
            cfg_t *cfg
            cfg_node_t *node
            cfg_node_attr_t attr
            char *&va_arg1 = NO_INIT
        CODE:
            RETVAL = cfg_node_get(cfg, node, attr|CFG_ATTR_COPY, &va_arg1);
        OUTPUT:
            va_arg1
            RETVAL
    CASE: ((cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_TYPE)
        INPUT:
            cfg_t *cfg
            cfg_node_t *node
            cfg_node_attr_t attr
            cfg_node_type_t &va_arg1 = NO_INIT
        CODE:
            RETVAL = cfg_node_get(cfg, node, attr, &va_arg1);
        OUTPUT:
            va_arg1
            RETVAL
    CASE: ((cfg_node_attr_t)SvIV(ST(2)) == CFG_NODE_ATTR_DATA)
        INPUT:
            cfg_t *cfg
            cfg_node_t *node
            cfg_node_attr_t attr
            cfg_data_t *&va_arg1 = NO_INIT
        CODE:
            RETVAL = cfg_node_get(cfg, node, attr, &va_arg1);
        OUTPUT:
            va_arg1
            RETVAL
    CASE: 
        PROTOTYPE:
            $$$;$
        INPUT:
            cfg_t *cfg
            cfg_node_t *node
            cfg_node_attr_t attr
        CODE:
            RETVAL = cfg_node_get(cfg, node, attr);
        OUTPUT:
            RETVAL

cfg_rc_t
cfg_node_root(cfg,node,node_old)
    PROTOTYPE:
        $$
    INPUT:
        cfg_t *cfg
        cfg_node_t *node
        cfg_node_t *&node_old = NO_INIT
    CODE:
        RETVAL = cfg_node_root(cfg, node, &node_old);
    OUTPUT:
        node_old
        RETVAL

cfg_rc_t
cfg_node_select(cfg,node,result,spec)
    PROTOTYPE:
        $$$$
    INPUT:
        cfg_t *cfg
        cfg_node_t *node
        SV *&result = NO_INIT
        const char *spec
    PREINIT:
        cfg_node_t **r;
    CODE:
        /* FIXME: perhaps use sv_vsetpvfn() to fully emulate C API? */
        RETVAL = cfg_node_select(cfg, node, &r, "%s", spec);
        if (RETVAL == CFG_OK) {
            /* translate C array into Perl array */
            int i;
            AV *av = newAV();
            for (i = 0; r[i] != NULL; i++)
                av_push(av, newSV(PTR2IV(r[i])));
            free(r);
            result = newRV_noinc((SV *)av);
        }
        else
            result = &PL_sv_undef;
    OUTPUT:
        result
        RETVAL

cfg_rc_t
cfg_node_find(cfg,node,cb_fct_cmp,cb_ctx_cmp,cont)
    PROTOTYPE:
        $$$$$
    INPUT:
        cfg_t *cfg
        cfg_node_t *node
        SV *cb_fct_cmp
        SV *cb_ctx_cmp
        cfg_node_t *&cont = NO_INIT
    PREINIT:
        cb_ctx_t ctx_cmp;
    CODE:
        ctx_cmp.fct = cb_fct_cmp;
        ctx_cmp.ctx = cb_ctx_cmp;
        RETVAL = cfg_node_find(cfg, node, cb_fct, &ctx_cmp, &cont);
    OUTPUT:
        cont
        RETVAL

cfg_rc_t
cfg_node_apply(cfg,node,cb_fct_cmp,cb_ctx_cmp,cb_fct_cb,cb_ctx_cb)
    PROTOTYPE:
        $$$$$$
    INPUT:
        cfg_t *cfg
        cfg_node_t *node
        SV *cb_fct_cmp
        SV *cb_ctx_cmp
        SV *cb_fct_cb
        SV *cb_ctx_cb
    PREINIT:
        cb_ctx_t ctx_cmp;
        cb_ctx_t ctx_cb;
    CODE:
        ctx_cmp.fct = cb_fct_cmp;
        ctx_cmp.ctx = cb_ctx_cmp;
        ctx_cb.fct  = cb_fct_cb;
        ctx_cb.ctx  = cb_ctx_cb;
        RETVAL = cfg_node_apply(cfg, node, cb_fct, &ctx_cmp, cb_fct, &ctx_cb);
    OUTPUT:
        RETVAL

cfg_rc_t
cfg_node_cmp(cfg,node,token)
    PROTOTYPE:
        $$$
    INPUT:
        cfg_t *cfg
        cfg_node_t *node
        char *token
    CODE:
        RETVAL = cfg_node_cmp(cfg, node, (void *)token);
    OUTPUT:
        RETVAL

cfg_rc_t
cfg_node_link(cfg,node,id,node2)
    PROTOTYPE:
        $$$$
    INPUT:
        cfg_t *cfg
        cfg_node_t *node
        cfg_node_attr_t id
        cfg_node_t *node2
    CODE:
        RETVAL = cfg_node_link(cfg, node, id, node2);
    OUTPUT:
        RETVAL

cfg_rc_t
cfg_node_unlink(cfg,node)
    PROTOTYPE:
        $$
    INPUT:
        cfg_t *cfg
        cfg_node_t *node
    CODE:
        RETVAL = cfg_node_unlink(cfg, node);
    OUTPUT:
        RETVAL

cfg_rc_t
cfg_data_set(data,attr,va_arg1)
    CASE: (cfg_data_attr_t)SvIV(ST(1)) == CFG_DATA_ATTR_TYPE
        PROTOTYPE:
            $$$
        INPUT:
            cfg_data_t *data
            cfg_data_attr_t attr
            cfg_data_type_t va_arg1
        CODE:
            RETVAL = cfg_data_set(data, attr, va_arg1);
        OUTPUT:
            RETVAL
    CASE: (cfg_data_attr_t)SvIV(ST(1)) == CFG_DATA_ATTR_VALUE
        INPUT:
            cfg_data_t *data
            cfg_data_attr_t attr
        PREINIT:
            cfg_data_type_t type;
        CODE:
            if ((RETVAL = cfg_data_get(data, CFG_DATA_ATTR_TYPE, &type)) == CFG_OK) {
                switch (type) {
                    case CFG_DATA_TYPE_PTR: {
                        void *va_arg1 = INT2PTR(cfg_node_t *, SvIV((SV*)SvRV(ST(2))));
                        RETVAL = cfg_data_set(data, attr, va_arg1);
                        break;
                    }
                    case CFG_DATA_TYPE_STR: {
                        char *va_arg1 = SvPV_nolen(ST(2));
                        RETVAL = cfg_data_set(data, attr, va_arg1);
                        break;
                    }
                    case CFG_DATA_TYPE_INT: {
                        int va_arg1 = SvIV(ST(2));
                        RETVAL = cfg_data_set(data, attr, va_arg1);
                        break;
                    }
                    case CFG_DATA_TYPE_FLT: {
                        double va_arg1 = SvNV(ST(2));
                        RETVAL = cfg_data_set(data, attr, va_arg1);
                        break;
                    }
                }
            }
        OUTPUT:
            RETVAL
    CASE: (cfg_data_attr_t)SvIV(ST(1)) == CFG_DATA_ATTR_CTRL
        INPUT:
            cfg_data_t *data
            cfg_data_attr_t attr
            cfg_data_cb_t va_arg1
        CODE:
            RETVAL = cfg_data_set(data, attr, va_arg1);
        OUTPUT:
            RETVAL

cfg_rc_t
cfg_data_get(data,attr,va_arg1)
    CASE: (cfg_data_attr_t)SvIV(ST(1)) == CFG_DATA_ATTR_TYPE
        PROTOTYPE:
            $$$
        INPUT:
            cfg_data_t *data
            cfg_data_attr_t attr
            cfg_data_type_t &va_arg1 = NO_INIT
        CODE:
            RETVAL = cfg_data_get(data, attr, &va_arg1);
        OUTPUT:
            va_arg1
            RETVAL
    CASE: (cfg_data_attr_t)SvIV(ST(1)) == CFG_DATA_ATTR_VALUE
        INPUT:
            cfg_data_t *data
            cfg_data_attr_t attr
            SV *va_arg1
        PREINIT:
            cfg_data_type_t type;
        CODE:
            if ((RETVAL = cfg_data_get(data, CFG_DATA_ATTR_TYPE, &type)) == CFG_OK) {
                switch (type) {
                    case CFG_DATA_TYPE_PTR: {
                        void *arg;
                        RETVAL = cfg_data_get(data, attr, &arg);
                        sv_setiv(va_arg1, PTR2IV(arg));
                        break;
                    }
                    case CFG_DATA_TYPE_STR: {
                        char *arg;
                        RETVAL = cfg_data_set(data, attr, &arg);
                        sv_setpv(va_arg1, arg);
                        break;
                    }
                    case CFG_DATA_TYPE_INT: {
                        int arg;
                        RETVAL = cfg_data_set(data, attr, &arg);
                        sv_setiv(va_arg1, arg);
                        break;
                    }
                    case CFG_DATA_TYPE_FLT: {
                        double arg;
                        RETVAL = cfg_data_set(data, attr, &arg);
                        sv_setnv(va_arg1, arg);
                        break;
                    }
                }
            }
        OUTPUT:
            va_arg1
            RETVAL
    CASE: (cfg_data_attr_t)SvIV(ST(1)) == CFG_DATA_ATTR_CTRL
        INPUT:
            cfg_data_t *data
            cfg_data_attr_t attr
            cfg_data_cb_t &va_arg1 = NO_INIT
        CODE:
            RETVAL = cfg_data_set(data, attr, &va_arg1);
        OUTPUT:
            va_arg1
            RETVAL

cfg_rc_t
cfg_data_ctrl(data,ctrl,va_arg1)
    CASE: (cfg_data_ctrl_t)SvIV(ST(1)) == CFG_DATA_CTRL_CLONE
        PROTOTYPE:
            $$;$
        INPUT:
            cfg_data_t *data
            cfg_data_ctrl_t ctrl
            cfg_data_t *&va_arg1 = NO_INIT
        CODE:
            RETVAL = cfg_data_ctrl(data, ctrl, &va_arg1);
        OUTPUT:
            va_arg1
            RETVAL
    CASE: (cfg_data_attr_t)SvIV(ST(1)) == CFG_DATA_CTRL_DESTROY
        INPUT:
            cfg_data_t *data
            cfg_data_ctrl_t ctrl
        CODE:
            RETVAL = cfg_data_ctrl(data, ctrl);
        OUTPUT:
            RETVAL
    CASE:
        INPUT:
            cfg_data_t *data
            cfg_data_ctrl_t ctrl
        CODE:
            RETVAL = cfg_data_set(data, ctrl);
        OUTPUT:
            RETVAL


CVSTrac 2.0.1