varnish-cache/lib/libvcc/vcc_symb.c
1
/*-
2
 * Copyright (c) 2010 Varnish Software AS
3
 * All rights reserved.
4
 *
5
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
20
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
 * SUCH DAMAGE.
27
 */
28
29
#include "config.h"
30
31
#include <ctype.h>
32
#include <stdarg.h>
33
#include <stdlib.h>
34
#include <string.h>
35
36
#include "vcc_compile.h"
37
38
#include "vct.h"
39
40
/*--------------------------------------------------------------------*/
41
42
enum symkind
43 36638
VCC_HandleKind(vcc_type_t fmt)
44
{
45 36638
        if (fmt == ACL)         return(SYM_ACL);
46 36576
        if (fmt == BACKEND)     return(SYM_BACKEND);
47 34462
        if (fmt == PROBE)       return(SYM_PROBE);
48 34442
        if (fmt == STEVEDORE)   return(SYM_STEVEDORE);
49 34427
        if (fmt == SUB)         return(SYM_SUB);
50 34398
        if (fmt == INSTANCE)    return(SYM_INSTANCE);
51 34162
        return(SYM_NONE);
52
}
53
54
const char *
55 100802
VCC_SymKind(struct vcc *tl, const struct symbol *s)
56
{
57 100802
        switch (s->kind) {
58
#define VCC_SYMB(uu, ll)        case SYM_##uu: return(#ll);
59
#include "tbl/symbol_kind.h"
60
        default:
61 0
                ErrInternal(tl);
62 0
                VSB_printf(tl->sb, "Symbol Kind 0x%x\n", s->kind);
63 0
                return("INTERNALERROR");
64
        }
65
}
66
67
void
68 10851
VCC_PrintCName(struct vsb *vsb, const char *b, const char *e)
69
{
70
71 10851
        AN(vsb);
72 10851
        AN(b);
73
74 10851
        if (e == NULL)
75 1134
                e = strchr(b, '\0');
76 10851
        assert(b < e);
77
78 110590
        for (; b < e; b++)
79 99739
                if (vct_isalnum(*b))
80 94115
                        VSB_putc(vsb, *b);
81
                else
82 5624
                        VSB_printf(vsb, "_%02x_", *b);
83 10851
}
84
85
static struct symbol *
86 119466
vcc_new_symbol(struct vcc *tl, const char *b, const char *e)
87
{
88
        struct symbol *sym;
89
90 119466
        AN(b);
91 119466
        if (e == NULL)
92 906
                e = strchr(b, '\0');
93 119466
        AN(e);
94 119466
        assert(e > b);
95 119466
        sym = TlAlloc(tl, sizeof *sym);
96 119466
        INIT_OBJ(sym, SYMBOL_MAGIC);
97 119466
        AN(sym);
98 119466
        sym->name = TlAlloc(tl, (e - b) + 1L);
99 119466
        AN(sym->name);
100 119466
        memcpy(sym->name, b, (e - b));
101 119466
        sym->name[e - b] = '\0';
102 119466
        sym->nlen = e - b;
103 119466
        VTAILQ_INIT(&sym->children);
104 119466
        return (sym);
105
}
106
107
struct symbol *
108 343162
VCC_Symbol(struct vcc *tl, struct symbol *parent,
109
    const char *b, const char *e, enum symkind kind, int create)
110
{
111
        const char *q;
112 343162
        struct symbol *sym, *sym2 = NULL;
113
        size_t l;
114
        int i;
115
116 343162
        if (tl->symbols == NULL)
117 906
                tl->symbols = vcc_new_symbol(tl, "<root>", NULL);
118 343162
        if (parent == NULL)
119 181901
                parent = tl->symbols;
120
121 343162
        AN(b);
122 343162
        assert(e == NULL || b < e);
123 343162
        if (e == NULL)
124 101416
                e = strchr(b, '\0');
125 343162
        assert(e > b);
126 343162
        if (e[-1] == '.')
127 5430
                e--;
128 343162
        assert(e > b);
129
130 343162
        q = strchr(b, '.');
131 343162
        if (q == NULL || q > e)
132 195904
                q = e;
133 343162
        l = q - b;
134 343162
        assert(l > 0);
135
136 2801867
        VTAILQ_FOREACH(sym, &parent->children, list) {
137 2702318
                i = strncasecmp(sym->name, b, l);
138 2702318
                if (i < 0)
139 2458618
                        continue;
140 243700
                if (i > 0 || l < sym->nlen) {
141 30155
                        sym2 = sym;
142 30155
                        sym = NULL;
143 30155
                        break;
144
                }
145 213545
                if (l > sym->nlen)
146 0
                        continue;
147 213545
                if (q < e)
148 135491
                        break;
149 121493
                if (kind != SYM_NONE && sym->kind != SYM_NONE &&
150 43439
                    kind != sym->kind)
151 81
                        continue;
152 77973
                if (kind == SYM_NONE && sym->kind == kind)
153 6
                        continue;
154 77967
                break;
155
        }
156 343162
        if (sym == NULL && create == 0 && parent->wildcard != NULL) {
157 9718
                AN(parent->wildcard);
158 9718
                parent->wildcard(tl, parent, b, e);
159 9718
                if (tl->err)
160 1
                        return (NULL);
161 9717
                return (VCC_Symbol(tl, parent, b, e, kind, -1));
162
        }
163 333444
        if (sym == NULL && create < 1)
164 1426
                return (sym);
165 332018
        if (sym == NULL) {
166 118560
                sym = vcc_new_symbol(tl, b, q);
167 118560
                sym->parent = parent;
168 118560
                if (sym2 != NULL)
169 25268
                        VTAILQ_INSERT_BEFORE(sym2, sym, list);
170
                else
171 93292
                        VTAILQ_INSERT_TAIL(&parent->children, sym, list);
172 118560
                if (q == e)
173 112224
                        sym->kind = kind;
174
        }
175 332018
        if (q == e)
176 190191
                return (sym);
177 141827
        assert(*q == '.');
178 141827
        return (VCC_Symbol(tl, sym, ++q, e, kind, create));
179
}
180
181
static void
182 511847
vcc_walksymbols(struct vcc *tl, const struct symbol *root,
183
    symwalk_f *func, enum symkind kind)
184
{
185
        struct symbol *sym;
186
187 1019883
        VTAILQ_FOREACH(sym, &root->children, list) {
188 508051
                if (kind == SYM_NONE || kind == sym->kind)
189 235024
                        func(tl, sym);
190 1019898
                ERRCHK(tl);
191 508036
                vcc_walksymbols(tl, sym, func, kind);
192
        }
193
}
194
195
void
196 3811
VCC_WalkSymbols(struct vcc *tl, symwalk_f *func, enum symkind kind)
197
{
198
199 3811
        vcc_walksymbols(tl, tl->symbols, func, kind);
200 3811
}
201
202
void
203 1119
VCC_GlobalSymbol(struct symbol *sym, vcc_type_t fmt, const char *pfx)
204
{
205
        struct vsb *vsb;
206
207 1119
        CHECK_OBJ_NOTNULL(sym, SYMBOL_MAGIC);
208 1119
        AN(pfx);
209
210 1119
        vsb = VSB_new_auto();
211 1119
        AN(vsb);
212 1119
        VSB_printf(vsb, "%s_", pfx);
213 1119
        VCC_PrintCName(vsb, sym->name, NULL);
214 1119
        AZ(VSB_finish(vsb));
215 1119
        REPLACE(sym->rname, VSB_data(vsb));
216 1119
        AN(sym->rname);
217 1119
        VSB_destroy(&vsb);
218
219 1119
        sym->fmt = fmt;
220 1119
        sym->kind = VCC_HandleKind(sym->fmt);
221 1119
        if (sym->kind != SYM_NONE)
222 1119
                sym->eval = vcc_Eval_Handle;
223
        else
224 0
                WRONG("Wrong kind of global symbol");
225
226
#define VCL_MET_MAC(l,u,t,b)   sym->r_methods |= VCL_MET_##u;
227
#include "tbl/vcl_returns.h"
228 1119
}
229
230
struct symbol *
231 1084
VCC_HandleSymbol(struct vcc *tl, const struct token *tk, vcc_type_t fmt,
232
    const char *pfx)
233
{
234
        struct symbol *sym;
235
        enum symkind kind;
236
        const char *p;
237
238 1084
        kind = VCC_HandleKind(fmt);
239 1084
        assert(kind != SYM_NONE);
240
241 1084
        sym = VCC_SymbolTok(tl, NULL, tk, SYM_NONE, 0);
242 1084
        if (sym != NULL && sym->def_b != NULL && kind == sym->kind) {
243 3
                p = VCC_SymKind(tl, sym);
244 9
                VSB_printf(tl->sb, "%c%s '%.*s' redefined.\n",
245 6
                    toupper(*p), p + 1, PF(tk));
246 3
                vcc_ErrWhere(tl, tk);
247 3
                VSB_printf(tl->sb, "First definition:\n");
248 3
                AN(sym->def_b);
249 3
                vcc_ErrWhere(tl, sym->def_b);
250 3
                return (sym);
251 1081
        } else if (sym != NULL && sym->def_b != NULL) {
252 2
                VSB_printf(tl->sb, "Name '%.*s' already defined.\n", PF(tk));
253 2
                vcc_ErrWhere(tl, tk);
254 2
                VSB_printf(tl->sb, "First definition:\n");
255 2
                AN(sym->def_b);
256 2
                vcc_ErrWhere(tl, sym->def_b);
257 2
                return (sym);
258 1079
        } else if (sym != NULL && sym->kind != kind) {
259 2
                VSB_printf(tl->sb,
260
                    "Name %.*s must have type '%s'.\n",
261 1
                    PF(tk), VCC_SymKind(tl, sym));
262 1
                vcc_ErrWhere(tl, tk);
263 1
                return (sym);
264
        }
265 1078
        if (sym == NULL)
266 1077
                sym = VCC_SymbolTok(tl, NULL, tk, kind, 1);
267 1078
        AN(sym);
268 1078
        AZ(sym->ndef);
269 1078
        VCC_GlobalSymbol(sym, fmt, pfx);
270 1078
        sym->ndef = 1;
271 1078
        if (sym->def_b == NULL)
272 1078
                sym->def_b = tk;
273 1078
        return (sym);
274
}