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