File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libpdel / tmpl / tmpl_vars.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:25:53 2012 UTC (13 years, 1 month ago) by misho
Branches: libpdel, MAIN
CVS tags: v0_5_3, HEAD
libpdel

    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>