Annotation of embedaddon/libpdel/tmpl/tmpl_ctx.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 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>