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>