Annotation of embedaddon/libpdel/tmpl/tmpl_vars.c, revision 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>