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