File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libpdel / tmpl / tmpl_ctx.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 (12 years, 4 months 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 void	tmpl_free_vars(struct tmpl_ctx *ctx);
   47: static void	tmpl_free_funcs(struct tmpl_ctx *ctx);
   48: static int	tmpl_userfunc_cmp(const void *v1, const void *v2);
   49: 
   50: /*
   51:  * Create a template context.
   52:  */
   53: struct tmpl_ctx *
   54: tmpl_ctx_create(void *arg, const char *mtype,
   55: 	tmpl_handler_t *handler, tmpl_errfmtr_t *errfmtr)
   56: {
   57: 	struct tmpl_ctx *ctx;
   58: 
   59: 	/* Initialize template file */
   60: 	if ((ctx = MALLOC(mtype, sizeof(*ctx))) == NULL)
   61: 		return (NULL);
   62: 	memset(ctx, 0, sizeof(*ctx));
   63: 	if (mtype != NULL) {
   64: 		strlcpy(ctx->mtype_buf, mtype, sizeof(ctx->mtype_buf));
   65: 		ctx->mtype = ctx->mtype_buf;
   66: 	}
   67: 	ctx->arg = arg;
   68: 	ctx->handler = handler;
   69: 	ctx->errfmtr = errfmtr;
   70: 
   71: 	/* Done */
   72: 	return (ctx);
   73: }
   74: 
   75: /*
   76:  * Get context argument.
   77:  */
   78: void *
   79: tmpl_ctx_get_arg(struct tmpl_ctx *ctx)
   80: {
   81: 	return (ctx->arg);
   82: }
   83:         
   84: /*
   85:  * Get context memory type.
   86:  */
   87: const char *
   88: tmpl_ctx_get_mtype(struct tmpl_ctx *ctx)
   89: {
   90: 	return (ctx->mtype);
   91: }
   92: 
   93: /*
   94:  * Handler for handling a fixed list of user functions.
   95:  */
   96: char *
   97: tmpl_list_handler(struct tmpl_ctx *ctx, const struct tmpl_func *userfuncs,
   98: 	u_int uflen, char **errmsgp, int ac, char **av)
   99: {
  100: 	const char *const mtype = tmpl_ctx_get_mtype(ctx);
  101: 	struct tmpl_func key;
  102: 	struct tmpl_func *f;
  103: 	char buf[256];
  104: 	char *s;
  105: 	int i;
  106: 
  107: 	/* If no userfunc's supplied, bail */
  108: 	if (userfuncs == NULL) {
  109: 		*errmsgp = STRDUP(mtype, "unknown template function");
  110: 		goto error;
  111: 	}
  112: 
  113: 	/* Find function in user-supplied list */
  114: 	key.name = av[0];
  115: 	if ((f = bsearch(&key, userfuncs, uflen,
  116: 	    sizeof(*userfuncs), tmpl_userfunc_cmp)) == NULL) {
  117: 		*errmsgp = STRDUP(mtype, "unknown template function");
  118: 		goto error;
  119: 	}
  120: 
  121: 	/* Check number of arguments */
  122: 	if (ac - 1 < f->min_args) {
  123: 		ASPRINTF(mtype, errmsgp,
  124: 		    "at %s %d argument%s %s for \"@%s\"",
  125: 		    "least", f->min_args, f->min_args == 1 ? "" : "s",
  126: 		    "required", f->name);
  127: 		goto error;
  128: 	}
  129: 	if (ac - 1 > f->max_args) {
  130: 		ASPRINTF(mtype, errmsgp,
  131: 		    "at %s %d argument%s %s for \"@%s\"",
  132: 		    "most", f->max_args, f->max_args == 1 ? "" : "s",
  133: 		    "allowed", f->name);
  134: 		goto error;
  135: 	}
  136: 
  137: 	/* Invoke handler */
  138: 	if ((s = (*f->handler)(ctx, errmsgp, ac, av)) != NULL)
  139: 		return (s);
  140: 
  141: error:
  142: 	/* Handle errors by showing the function that generated the error */
  143: 	snprintf(buf, sizeof(buf), "@%s(", av[0]);
  144: 	for (i = 1; i < ac; i++) {
  145: 		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
  146: 		    "%s%s", (i > 1) ? ", " : "", av[i]);
  147: 	}
  148: 	snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "): %s",
  149: 	    (*errmsgp != NULL) ? *errmsgp : strerror(errno));
  150: 	if (*errmsgp != NULL)
  151: 		FREE(mtype, *errmsgp);
  152: 	*errmsgp = STRDUP(mtype, buf);
  153: 	return (NULL);
  154: }
  155: 
  156: /*
  157:  * Destroy a template context.
  158:  */
  159: void
  160: tmpl_ctx_destroy(struct tmpl_ctx **ctxp)
  161: {
  162: 	struct tmpl_ctx *const ctx = *ctxp;
  163: 
  164: 	/* Sanity check */
  165: 	if (ctx == NULL)
  166: 		return;
  167: 	*ctxp = NULL;
  168: 
  169: 	/* Free run-time state */
  170: 	tmpl_ctx_reset(ctx);
  171: 
  172: 	/* Free context */
  173: 	FREE(ctx->mtype, ctx);
  174: }
  175: 
  176: /*
  177:  * Do the things we need in order to reset a template context.
  178:  */
  179: void
  180: tmpl_ctx_reset(struct tmpl_ctx *ctx)
  181: {
  182: 	tmpl_free_vars(ctx);
  183: 	tmpl_free_funcs(ctx);
  184: }
  185: 
  186: /*
  187:  * Free up the vars part of a template context.
  188:  */
  189: static void
  190: tmpl_free_vars(struct tmpl_ctx *ctx)
  191: {
  192: 	int i;
  193: 
  194: 	/* Free variables */
  195: 	for (i = 0; i < ctx->num_vars; i++) {
  196: 		struct exec_var *const var = &ctx->vars[i];
  197: 
  198: 		FREE(ctx->mtype, var->name);
  199: 		FREE(ctx->mtype, var->value);
  200: 	}
  201: 	FREE(ctx->mtype, ctx->vars);
  202: 
  203: 	ctx->num_vars = 0;
  204: 	ctx->vars = NULL;
  205: }
  206: 
  207: /*
  208:  * Free up the funcs part of a template context.
  209:  */
  210: static void
  211: tmpl_free_funcs(struct tmpl_ctx *ctx)
  212: {
  213: 	int i;
  214: 
  215: 	/* Free run-time functions */
  216: 	for (i = 0; i < ctx->num_funcs; i++)
  217: 		_tmpl_free_func(ctx, &ctx->funcs[i]);
  218: 	FREE(ctx->mtype, ctx->funcs);
  219: 
  220: 	ctx->num_funcs = 0;
  221: 	ctx->funcs = NULL;
  222: }
  223: 
  224: /*
  225:  * Compare two struct tmpl_func's.
  226:  */
  227: static int
  228: tmpl_userfunc_cmp(const void *v1, const void *v2)
  229: {
  230: 	const struct tmpl_func *const f1 = v1;
  231: 	const struct tmpl_func *const f2 = v2;
  232: 
  233: 	return (strcmp(f1->name, f2->name));
  234: }
  235: 

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