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>