Annotation of embedaddon/libpdel/tmpl/tmpl_vars.c, revision 1.1.1.1

1.1       misho       1: 
                      2: /*
                      3:  * Copyright (c) 2001-2002 Packet Design, LLC.
                      4:  * All rights reserved.
                      5:  * 
                      6:  * Subject to the following obligations and disclaimer of warranty,
                      7:  * use and redistribution of this software, in source or object code
                      8:  * forms, with or without modifications are expressly permitted by
                      9:  * Packet Design; provided, however, that:
                     10:  * 
                     11:  *    (i)  Any and all reproductions of the source or object code
                     12:  *         must include the copyright notice above and the following
                     13:  *         disclaimer of warranties; and
                     14:  *    (ii) No rights are granted, in any manner or form, to use
                     15:  *         Packet Design trademarks, including the mark "PACKET DESIGN"
                     16:  *         on advertising, endorsements, or otherwise except as such
                     17:  *         appears in the above copyright notice or in the software.
                     18:  * 
                     19:  * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
                     20:  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
                     21:  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
                     22:  * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
                     23:  * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
                     24:  * OR NON-INFRINGEMENT.  PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
                     25:  * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
                     26:  * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
                     27:  * RELIABILITY OR OTHERWISE.  IN NO EVENT SHALL PACKET DESIGN BE
                     28:  * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
                     29:  * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
                     30:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
                     31:  * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
                     32:  * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
                     33:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     34:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
                     35:  * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
                     36:  * THE POSSIBILITY OF SUCH DAMAGE.
                     37:  *
                     38:  * Author: Archie Cobbs <archie@freebsd.org>
                     39:  */
                     40: 
                     41: #include "tmpl_internal.h"
                     42: 
                     43: /*
                     44:  * Internal functions
                     45:  */
                     46: static int     tmpl_var_cmp(const void *v1, const void *v2);
                     47: static int     tmpl_func_cmp(const void *v1, const void *v2);
                     48: static struct  tmpl_elem *tmpl_copy_elems(const char *mtype,
                     49:                        const struct tmpl_elem *oelems, int count);
                     50: static int     tmpl_copy_call(const char *mtype,
                     51:                        const struct func_call *ocall, struct func_call *call);
                     52: 
                     53: /*
                     54:  * Get a variable.
                     55:  */
                     56: const char *
                     57: tmpl_ctx_get_var(struct tmpl_ctx *ctx, const char *name)
                     58: {
                     59:        int i;
                     60: 
                     61:        if ((i = _tmpl_find_var(ctx, name)) == -1) {
                     62:                errno = ENOENT;
                     63:                return (NULL);
                     64:        }
                     65:        return (ctx->vars[i].value);
                     66: }
                     67: 
                     68: /*
                     69:  * Set a variable.
                     70:  */
                     71: int
                     72: tmpl_ctx_set_var(struct tmpl_ctx *ctx, const char *name, const char *value)
                     73: {
                     74:        char *new_value;
                     75:        char *new_name;
                     76:        void *mem;
                     77:        int i;
                     78: 
                     79:        if ((new_value = STRDUP(ctx->mtype, value)) == NULL)
                     80:                return (-1);
                     81:        if ((i = _tmpl_find_var(ctx, name)) != -1) {
                     82:                struct exec_var *const var = &ctx->vars[i];
                     83: 
                     84:                FREE(ctx->mtype, var->value);
                     85:                var->value = new_value;
                     86:                return (0);
                     87:        }
                     88:        if ((new_name = STRDUP(ctx->mtype, name)) == NULL) {
                     89:                FREE(ctx->mtype, new_value);
                     90:                return (-1);
                     91:        }
                     92:        if ((mem = REALLOC(ctx->mtype, ctx->vars,
                     93:            (ctx->num_vars + 1) * sizeof(*ctx->vars))) == NULL) {
                     94:                FREE(ctx->mtype, new_name);
                     95:                FREE(ctx->mtype, new_value);
                     96:                return (-1);
                     97:        }
                     98:        ctx->vars = mem;
                     99:        ctx->vars[ctx->num_vars].name = new_name;
                    100:        ctx->vars[ctx->num_vars].value = new_value;
                    101:        ctx->num_vars++;
                    102:        mergesort(ctx->vars, ctx->num_vars, sizeof(*ctx->vars), tmpl_var_cmp);
                    103:        return (0);
                    104: }
                    105: 
                    106: int
                    107: _tmpl_find_var(struct tmpl_ctx *ctx, const char *name)
                    108: {
                    109:        struct exec_var key;
                    110:        struct exec_var *var;
                    111: 
                    112:        key.name = (char *)name;
                    113:        if ((var = bsearch(&key, ctx->vars,
                    114:            ctx->num_vars, sizeof(*ctx->vars), tmpl_var_cmp)) == NULL)
                    115:                return (-1);
                    116:        return (var - ctx->vars);
                    117: }
                    118: 
                    119: int
                    120: _tmpl_find_func(struct tmpl_ctx *ctx, const char *name)
                    121: {
                    122:        struct exec_func key;
                    123:        struct exec_func *func;
                    124: 
                    125:        key.name = (char *)name;
                    126:        if ((func = bsearch(&key, ctx->funcs,
                    127:            ctx->num_funcs, sizeof(*ctx->funcs), tmpl_func_cmp)) == NULL)
                    128:                return (-1);
                    129:        return (func - ctx->funcs);
                    130: }
                    131: 
                    132: int
                    133: _tmpl_set_func(struct tmpl_ctx *ctx, const char *name,
                    134:        const struct tmpl_elem *oelems, int nelems)
                    135: {
                    136:        struct tmpl_elem *elems;
                    137:        char *new_name;
                    138:        void *eblock;
                    139:        size_t bsize;
                    140:        void *mem;
                    141:        int i;
                    142: 
                    143:        /* Copy function elements */
                    144:        if ((elems = tmpl_copy_elems(ctx->mtype, oelems, nelems)) == NULL)
                    145:                return (-1);
                    146: 
                    147:        /* Allocate and fill in compacted memory block */
                    148:        bsize = nelems * sizeof(*elems);
                    149:        _tmpl_compact_elems(ctx->mtype, elems, nelems, NULL, &bsize);
                    150:        if ((eblock = MALLOC(ctx->mtype, bsize)) == NULL) {
                    151:                _tmpl_free_elems(ctx->mtype, NULL, elems, nelems);
                    152:                return (-1);
                    153:        }
                    154:        bsize = 0;
                    155:        _tmpl_compact(ctx->mtype,
                    156:            eblock, &elems, nelems * sizeof(*elems), &bsize);
                    157:        _tmpl_compact_elems(ctx->mtype, elems, nelems, eblock, &bsize);
                    158: 
                    159:        /* See if function is already defined */
                    160:        if ((i = _tmpl_find_func(ctx, name)) != -1) {
                    161:                struct exec_func *const func = &ctx->funcs[i];
                    162: 
                    163:                _tmpl_free_elems(ctx->mtype, func->eblock,
                    164:                    func->elems, func->num_elems);
                    165:                func->elems = eblock;
                    166:                func->num_elems = nelems;
                    167:                func->eblock = eblock;
                    168:                return (0);
                    169:        }
                    170: 
                    171:        /* Copy function name */
                    172:        if ((new_name = STRDUP(ctx->mtype, name)) == NULL) {
                    173:                FREE(ctx->mtype, eblock);
                    174:                return (-1);
                    175:        }
                    176: 
                    177:        /* Add new function to list */
                    178:        if ((mem = REALLOC(ctx->mtype, ctx->funcs,
                    179:            (ctx->num_funcs + 1) * sizeof(*ctx->funcs))) == NULL) {
                    180:                FREE(ctx->mtype, new_name);
                    181:                FREE(ctx->mtype, eblock);
                    182:                return (-1);
                    183:        }
                    184:        ctx->funcs = mem;
                    185:        ctx->funcs[ctx->num_funcs].name = new_name;
                    186:        ctx->funcs[ctx->num_funcs].elems = eblock;
                    187:        ctx->funcs[ctx->num_funcs].num_elems = nelems;
                    188:        ctx->funcs[ctx->num_funcs].eblock = eblock;
                    189:        ctx->num_funcs++;
                    190:        mergesort(ctx->funcs,
                    191:            ctx->num_funcs, sizeof(*ctx->funcs), tmpl_func_cmp);
                    192:        return (0);
                    193: }
                    194: 
                    195: static int
                    196: tmpl_var_cmp(const void *v1, const void *v2)
                    197: {
                    198:        const struct exec_var *const var1 = v1;
                    199:        const struct exec_var *const var2 = v2;
                    200: 
                    201:        return (strcmp(var1->name, var2->name));
                    202: }
                    203: 
                    204: static int
                    205: tmpl_func_cmp(const void *v1, const void *v2)
                    206: {
                    207:        const struct exec_func *const func1 = v1;
                    208:        const struct exec_func *const func2 = v2;
                    209: 
                    210:        return (strcmp(func1->name, func2->name));
                    211: }
                    212: 
                    213: /*
                    214:  * Copy a range of elements into a new array.
                    215:  */
                    216: static struct tmpl_elem *
                    217: tmpl_copy_elems(const char *mtype, const struct tmpl_elem *oelems, int count)
                    218: {
                    219:        struct tmpl_elem *elems;
                    220:        int i;
                    221: 
                    222:        if ((elems = MALLOC(mtype, count * sizeof(*elems))) == NULL)
                    223:                return (NULL);
                    224:        memset(elems, 0, count * sizeof(*elems));
                    225:        for (i = 0; i < count; i++) {
                    226:                const struct tmpl_elem *const oe = &oelems[i];
                    227:                struct tmpl_elem *const e = &elems[i];
                    228: 
                    229:                e->len = oe->len;
                    230:                e->flags = (oe->flags & ~TMPL_ELEM_MMAP_TEXT);
                    231:                if (oe->text != NULL) {
                    232:                        if ((e->text = MALLOC(mtype, e->len)) == NULL)
                    233:                                goto fail;
                    234:                        memcpy(e->text, oe->text, e->len);
                    235:                } else if (tmpl_copy_call(mtype, &oe->call, &e->call) == -1)
                    236:                        goto fail;
                    237:                e->u = oe->u;
                    238:        }
                    239:        return (elems);
                    240: 
                    241: fail:
                    242:        _tmpl_free_elems(mtype, NULL, elems, count);
                    243:        return (NULL);
                    244: }
                    245: 
                    246: /*
                    247:  * Copy a function call.
                    248:  */
                    249: static int
                    250: tmpl_copy_call(const char *mtype,
                    251:        const struct func_call *ocall, struct func_call *call)
                    252: {
                    253:        int i;
                    254: 
                    255:        memset(call, 0, sizeof(*call));
                    256:        call->type = ocall->type;
                    257:        call->handler = ocall->handler;
                    258:        if ((call->funcname = STRDUP(mtype, ocall->funcname)) == NULL)
                    259:                goto fail;
                    260:        if ((call->args = MALLOC(mtype,
                    261:            ocall->nargs * sizeof(*call->args))) == NULL)
                    262:                goto fail;
                    263:        memset(call->args, 0, ocall->nargs * sizeof(*call->args));
                    264:        call->nargs = ocall->nargs;
                    265:        for (i = 0; i < ocall->nargs; i++) {
                    266:                struct func_arg *const oa = &ocall->args[i];
                    267:                struct func_arg *const a = &call->args[i];
                    268: 
                    269:                if ((a->is_literal = oa->is_literal)) {
                    270:                        if ((a->u.literal = STRDUP(mtype,
                    271:                            oa->u.literal)) == NULL)
                    272:                                goto fail;
                    273:                } else if (tmpl_copy_call(mtype, &oa->u.call, &a->u.call) == -1)
                    274:                        goto fail;
                    275:        }
                    276:        return (0);
                    277: 
                    278: fail:
                    279:        _tmpl_free_call(mtype, call);
                    280:        return (-1);
                    281: }
                    282: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>