varnish-cache/lib/libvcc/vcc_types.c
0
/*-
1
 * Copyright (c) 2006 Verdens Gang AS
2
 * Copyright (c) 2006-2011 Varnish Software AS
3
 * All rights reserved.
4
 *
5
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6
 *
7
 * SPDX-License-Identifier: BSD-2-Clause
8 334004
 *
9 329505
 * Redistribution and use in source and binary forms, with or without
10 315920
 * modification, are permitted provided that the following conditions
11 297924
 * are met:
12 297814
 * 1. Redistributions of source code must retain the above copyright
13 267102
 *    notice, this list of conditions and the following disclaimer.
14 260788
 * 2. Redistributions in binary form must reproduce the above copyright
15 250217
 *    notice, this list of conditions and the following disclaimer in the
16 229372
 *    documentation and/or other materials provided with the distribution.
17 229064
 *
18 228723
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 228723
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 206448
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 199683
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22 199309
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 187363
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 185669
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 184613
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 174196
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 108438
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 108438
 * SUCH DAMAGE.
29 105270
 *
30 98285
 */
31 98285
32
#include "config.h"
33
34
#include <string.h>
35
36
#include "vcc_compile.h"
37
38
/*
39
 * A type attribute is information already existing, requiring no processing
40
 * or resource usage.
41
 *
42
 * A type method is a call and may do significant processing, change things,
43
 * eat workspace etc.
44
 *
45
 * XXX: type methods might move in a more comprehensive direction.
46
 */
47
struct vcc_method {
48
        unsigned                magic;
49
#define VCC_METHOD_MAGIC        0x594108cd
50
        vcc_type_t              type;
51
        const char              *name;
52
        const char              *impl;
53
        int                     func;
54
};
55
56
const struct type ACL[1] = {{
57
        .magic =                TYPE_MAGIC,
58
        .name =                 "ACL",
59
        .global_pfx =           "vrt_acl",
60
        .tostring =             "((\v1)->name)",
61
}};
62
63
static const struct vcc_method backend_methods[] = {
64
        { VCC_METHOD_MAGIC, BACKEND, "resolve",
65
            "VRT_DirectorResolve(ctx, \v1)", 1 },
66
        { VCC_METHOD_MAGIC, NULL },
67
};
68
69
static struct symbol default_backend[1] = {{
70
        .magic =                SYMBOL_MAGIC,
71
        .name =                 "default",
72
        .lorev =                VCL_LOW,
73
        .hirev =                VCL_HIGH,
74
        .kind =                 SYM_BACKEND,
75
        .type =                 DEFAULT,
76
        .rname =                "*(VCL_conf.default_director)",
77
}};
78
79
const struct type BACKEND[1] = {{
80
        .magic =                TYPE_MAGIC,
81
        .name =                 "BACKEND",
82
        .methods =              backend_methods,
83
        .global_pfx =           "vgc_backend",
84
        .tostring =             "VRT_BACKEND_string(\v1)",
85
        .default_sym =          default_backend,
86
}};
87
88
const struct type BLOB[1] = {{
89
        .magic =                TYPE_MAGIC,
90
        .name =                 "BLOB",
91
        .bodyform =             1,
92
        .tostring =             "VRT_BLOB_string(ctx, \v1)",
93
}};
94
95
const struct type BODY[1] = {{
96
        .magic =                TYPE_MAGIC,
97
        .name =                 "BODY",
98
        .noindent =             1,
99
}};
100
101
const struct type BOOL[1] = {{
102
        .magic =                TYPE_MAGIC,
103
        .name =                 "BOOL",
104
        .tostring =             "VRT_BOOL_string(\v1)",
105
}};
106
107
const struct type BYTES[1] = {{
108
        .magic =                TYPE_MAGIC,
109
        .name =                 "BYTES",
110
        .tostring =             "VRT_INT_string(ctx, \v1)",
111
        .multype =              REAL,   // XXX: wrong
112
}};
113
114
const struct type DEFAULT[1] = {{
115
        .magic =                TYPE_MAGIC,
116
        .name =                 "DEFAULT",
117
}};
118
119
const struct type DURATION[1] = {{
120
        .magic =                TYPE_MAGIC,
121
        .name =                 "DURATION",
122
        .tostring =             "VRT_REAL_string(ctx, \v1)", // XXX 's' suff?
123
        .multype =              REAL,
124
}};
125
126
const struct type ENUM[1] = {{
127
        .magic =                TYPE_MAGIC,
128
        .name =                 "ENUM",
129
        .tostring =             "",
130
}};
131
132
const struct type HEADER[1] = {{
133
        .magic =                TYPE_MAGIC,
134
        .name =                 "HEADER",
135
        .tostring =             "VRT_GetHdr(ctx, \v1)",
136
}};
137
138
const struct type HTTP[1] = {{
139
        .magic =                TYPE_MAGIC,
140
        .name =                 "HTTP",
141
}};
142
143
const struct type INSTANCE[1] = {{
144
        .magic =                TYPE_MAGIC,
145
        .name =                 "INSTANCE",
146
        .global_pfx =           "vo",
147
}};
148
149
const struct type INT[1] = {{
150
        .magic =                TYPE_MAGIC,
151
        .name =                 "INT",
152
        .multype =              INT,
153
        .tostring =             "VRT_INT_string(ctx, \v1)",
154
}};
155
156
const struct type IP[1] = {{
157
        .magic =                TYPE_MAGIC,
158
        .name =                 "IP",
159
        .tostring =             "VRT_IP_string(ctx, \v1)",
160
}};
161
162
static struct symbol default_probe[1] = {{
163
        .magic =                SYMBOL_MAGIC,
164
        .name =                 "default",
165
        .lorev =                VCL_LOW,
166
        .hirev =                VCL_HIGH,
167
        .kind =                 SYM_PROBE,
168
        .type =                 DEFAULT,
169
        .rname =                "vgc_probe_default",
170
}};
171
172
const struct type PROBE[1] = {{
173
        .magic =                TYPE_MAGIC,
174
        .name =                 "PROBE",
175
        .global_pfx =           "vgc_probe",
176
        .tostring =             "VRT_PROBE_string(\v1)",
177
        .default_sym =          default_probe,
178
}};
179
180
const struct type REAL[1] = {{
181
        .magic =                TYPE_MAGIC,
182
        .name =                 "REAL",
183
        .tostring =             "VRT_REAL_string(ctx, \v1)",
184
        .multype =              REAL,
185
}};
186
187
const struct type REGEX[1] = {{
188
        .magic =                TYPE_MAGIC,
189
        .name =                 "REGEX",
190
}};
191
192
static const struct vcc_method stevedore_methods[] = {
193
#define VRTSTVVAR(nm, vtype, ctype, dval) \
194
        { VCC_METHOD_MAGIC, vtype, #nm, "VRT_stevedore_" #nm "(\v1)", 0},
195
#include "tbl/vrt_stv_var.h"
196
        { VCC_METHOD_MAGIC, NULL },
197
};
198
199
const struct type STEVEDORE[1] = {{
200
        .magic =                TYPE_MAGIC,
201
        .name =                 "STEVEDORE",
202
        .methods =              stevedore_methods,
203
        .tostring =             "VRT_STEVEDORE_string(\v1)",
204
}};
205
206
const struct type STRING[1] = {{
207
        .magic =                TYPE_MAGIC,
208
        .name =                 "STRING",
209
        .stringform =           1,
210
}};
211
212
const struct type STRANDS[1] = {{
213
        .magic =                TYPE_MAGIC,
214
        .name =                 "STRANDS",
215
        .stringform =           1,
216
        .tostring =             "VRT_STRANDS_string(ctx,\v+\n\v1\v-\n)",
217
}};
218
219
static const struct vcc_method strings_methods[] = {
220
        { VCC_METHOD_MAGIC, STRING, "upper",
221
            "VRT_UpperLowerStrands(ctx, \vT, 1)", 1 },
222
        { VCC_METHOD_MAGIC, STRING, "lower",
223
            "VRT_UpperLowerStrands(ctx, \vT, 0)", 1 },
224
        { VCC_METHOD_MAGIC, NULL },
225
};
226
227
const struct type STRINGS[1] = {{
228
        .magic =                TYPE_MAGIC,
229
        .name =                 "STRINGS",
230
        .methods =              strings_methods,
231
        .bodyform =             1,
232
        .tostring =             "",
233
}};
234
235
const struct type SUB[1] = {{
236
        .magic =                TYPE_MAGIC,
237
        .name =                 "SUB",
238
        .global_pfx =           "VGC_function",
239
}};
240
241
const struct type TIME[1] = {{
242
        .magic =                TYPE_MAGIC,
243
        .name =                 "TIME",
244
        .tostring =             "VRT_TIME_string(ctx, \v1)",
245
}};
246
247
const struct type VCL[1] = {{
248
        .magic =                TYPE_MAGIC,
249
        .name =                 "VCL",
250
}};
251
252
const struct type VOID[1] = {{
253
        .magic =                TYPE_MAGIC,
254
        .name =                 "VOID",
255
}};
256
257
vcc_type_t
258 334004
VCC_Type(const char *p)
259
{
260
261
#define VCC_TYPE(UC, lc)        if (!strcmp(p, #UC)) return (UC);
262
#include "vcc_types.h"
263
        return (NULL);
264
}
265
266
static void
267 827640
vcc_type_init(struct vcc *tl, vcc_type_t type)
268
{
269
        const struct vcc_method *vm;
270
        struct symbol *sym;
271
        struct vsb *buf;
272
273
        /* NB: Don't bother even creating a type symbol if there are no
274
         * methods attached to it.
275
         */
276 827640
        if (type->methods == NULL)
277 724185
                return;
278
279 103455
        buf = VSB_new_auto();
280 103455
        AN(buf);
281 103455
        AN(VCC_MkSym(tl, type->name, SYM_TYPE, SYM_NONE, VCL_LOW, VCL_HIGH));
282
283 310365
        for (vm = type->methods; vm->type != NULL; vm++) {
284 206910
                VSB_printf(buf, "%s.%s", type->name, vm->name);
285 206910
                AZ(VSB_finish(buf));
286 206910
                sym = VCC_MkSym(tl, VSB_data(buf), SYM_TYPE, SYM_METHOD,
287
                    VCL_LOW, VCL_HIGH);
288 206910
                VSB_clear(buf);
289 206910
                if (tl->err)
290 0
                        break;
291 206910
                AN(sym);
292 206910
                sym->type = vm->type;
293 206910
                sym->eval = vcc_Eval_TypeMethod;
294 206910
                sym->eval_priv = vm;
295 206910
        }
296
297 103455
        VSB_destroy(&buf);
298 827640
}
299
300
const char *
301 32054
VCC_Type_EvalMethod(struct vcc *tl, const struct symbol *sym)
302
{
303
        const struct vcc_method *vm;
304
305 32054
        AN(sym);
306 32054
        AN(sym->kind == SYM_METHOD);
307 32054
        CAST_OBJ_NOTNULL(vm, sym->eval_priv, VCC_METHOD_MAGIC);
308
309 32054
        vcc_NextToken(tl);
310 32054
        if (vm->func) {
311 31955
                Expect(tl, '(');
312 31955
                if (tl->err)
313 0
                        return (NULL);
314 31955
                vcc_NextToken(tl);
315 31955
                Expect(tl, ')');
316 31955
                if (tl->err)
317 0
                        return (NULL);
318 31955
                vcc_NextToken(tl);
319 31955
        }
320
321 32054
        return (vm->impl);
322 32054
}
323
324
void
325 34485
vcc_Type_Init(struct vcc *tl)
326
{
327
328
#define VCC_TYPE(UC, lc)        vcc_type_init(tl, UC);
329
#include "vcc_types.h"
330
}