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 1182600
 *
9 1167120
 * Redistribution and use in source and binary forms, with or without
10 1118800
 * modification, are permitted provided that the following conditions
11 1054600
 * are met:
12 1054600
 * 1. Redistributions of source code must retain the above copyright
13 946240
 *    notice, this list of conditions and the following disclaimer.
14 924800
 * 2. Redistributions in binary form must reproduce the above copyright
15 888280
 *    notice, this list of conditions and the following disclaimer in the
16 812960
 *    documentation and/or other materials provided with the distribution.
17 812240
 *
18 811400
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 811400
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 718080
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 694760
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22 693800
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 644600
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 639000
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 635760
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 598920
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 366520
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 366520
 * SUCH DAMAGE.
29 355800
 *
30 324320
 */
31 324320
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
        .default_sym =          default_probe,
177
}};
178
179
const struct type REAL[1] = {{
180
        .magic =                TYPE_MAGIC,
181
        .name =                 "REAL",
182
        .tostring =             "VRT_REAL_string(ctx, \v1)",
183
        .multype =              REAL,
184
}};
185
186
const struct type REGEX[1] = {{
187
        .magic =                TYPE_MAGIC,
188
        .name =                 "REGEX",
189
}};
190
191
static const struct vcc_method stevedore_methods[] = {
192
#define VRTSTVVAR(nm, vtype, ctype, dval) \
193
        { VCC_METHOD_MAGIC, vtype, #nm, "VRT_stevedore_" #nm "(\v1)", 0},
194
#include "tbl/vrt_stv_var.h"
195
        { VCC_METHOD_MAGIC, NULL },
196
};
197
198
const struct type STEVEDORE[1] = {{
199
        .magic =                TYPE_MAGIC,
200
        .name =                 "STEVEDORE",
201
        .methods =              stevedore_methods,
202
        .tostring =             "VRT_STEVEDORE_string(\v1)",
203
}};
204
205
const struct type STRING[1] = {{
206
        .magic =                TYPE_MAGIC,
207
        .name =                 "STRING",
208
        .stringform =           1,
209
}};
210
211
const struct type STRANDS[1] = {{
212
        .magic =                TYPE_MAGIC,
213
        .name =                 "STRANDS",
214
        .stringform =           1,
215
        .tostring =             "VRT_STRANDS_string(ctx,\v+\n\v1\v-\n)",
216
}};
217
218
static const struct vcc_method strings_methods[] = {
219
        { VCC_METHOD_MAGIC, STRING, "upper",
220
            "VRT_UpperLowerStrands(ctx, \vT, 1)", 1 },
221
        { VCC_METHOD_MAGIC, STRING, "lower",
222
            "VRT_UpperLowerStrands(ctx, \vT, 0)", 1 },
223
        { VCC_METHOD_MAGIC, NULL },
224
};
225
226
const struct type STRINGS[1] = {{
227
        .magic =                TYPE_MAGIC,
228
        .name =                 "STRINGS",
229
        .methods =              strings_methods,
230
        .bodyform =             1,
231
        .tostring =             "",
232
}};
233
234
const struct type SUB[1] = {{
235
        .magic =                TYPE_MAGIC,
236
        .name =                 "SUB",
237
        .global_pfx =           "VGC_function",
238
}};
239
240
const struct type TIME[1] = {{
241
        .magic =                TYPE_MAGIC,
242
        .name =                 "TIME",
243
        .tostring =             "VRT_TIME_string(ctx, \v1)",
244
}};
245
246
const struct type VCL[1] = {{
247
        .magic =                TYPE_MAGIC,
248
        .name =                 "VCL",
249
}};
250
251
const struct type VOID[1] = {{
252
        .magic =                TYPE_MAGIC,
253
        .name =                 "VOID",
254
}};
255
256
vcc_type_t
257 1182600
VCC_Type(const char *p)
258
{
259
260
#define VCC_TYPE(UC, lc)        if (!strcmp(p, #UC)) return (UC);
261
#include "vcc_types.h"
262
        return (NULL);
263
}
264
265
static void
266 2875200
vcc_type_init(struct vcc *tl, vcc_type_t type)
267
{
268
        const struct vcc_method *vm;
269
        struct symbol *sym;
270
        struct vsb *buf;
271
272
        /* NB: Don't bother even creating a type symbol if there are no
273
         * methods attached to it.
274
         */
275 2875200
        if (type->methods == NULL)
276 2515800
                return;
277
278 359400
        buf = VSB_new_auto();
279 359400
        AN(buf);
280 359400
        AN(VCC_MkSym(tl, type->name, SYM_TYPE, SYM_NONE, VCL_LOW, VCL_HIGH));
281
282 1078200
        for (vm = type->methods; vm->type != NULL; vm++) {
283 718800
                VSB_printf(buf, "%s.%s", type->name, vm->name);
284 718800
                AZ(VSB_finish(buf));
285 718800
                sym = VCC_MkSym(tl, VSB_data(buf), SYM_TYPE, SYM_METHOD,
286
                    VCL_LOW, VCL_HIGH);
287 718800
                VSB_clear(buf);
288 718800
                if (tl->err)
289 0
                        break;
290 718800
                AN(sym);
291 718800
                sym->type = vm->type;
292 718800
                sym->eval = vcc_Eval_TypeMethod;
293 718800
                sym->eval_priv = vm;
294 718800
        }
295
296 359400
        VSB_destroy(&buf);
297 2875200
}
298
299
const char *
300 111400
VCC_Type_EvalMethod(struct vcc *tl, const struct symbol *sym)
301
{
302
        const struct vcc_method *vm;
303
304 111400
        AN(sym);
305 111400
        AN(sym->kind == SYM_METHOD);
306 111400
        CAST_OBJ_NOTNULL(vm, sym->eval_priv, VCC_METHOD_MAGIC);
307
308 111400
        vcc_NextToken(tl);
309 111400
        if (vm->func) {
310 111040
                Expect(tl, '(');
311 111040
                if (tl->err)
312 0
                        return (NULL);
313 111040
                vcc_NextToken(tl);
314 111040
                Expect(tl, ')');
315 111040
                if (tl->err)
316 0
                        return (NULL);
317 111040
                vcc_NextToken(tl);
318 111040
        }
319
320 111400
        return (vm->impl);
321 111400
}
322
323
void
324 119800
vcc_Type_Init(struct vcc *tl)
325
{
326
327
#define VCC_TYPE(UC, lc)        vcc_type_init(tl, UC);
328
#include "vcc_types.h"
329
}