varnish-cache/lib/libvcc/vcc_backend_util.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
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in the
16
 *    documentation and/or other materials provided with the distribution.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
 *
30
 */
31
32
#include "config.h"
33
34
#include <stdarg.h>
35
#include <string.h>
36
37
#include "vcc_compile.h"
38
39
/*--------------------------------------------------------------------
40
 * Helper functions to complain about duplicate and missing fields
41
 *
42
 * XXX: idea: add groups to check for exclusivity, such that
43
 * XXX:    ("!foo", "?bar", "!{", "this", "that", "}", NULL)
44
 * XXX: means exactly one of "this" or "that", and
45
 * XXX:    ("!foo", "?bar", "?{", "this", "that", "}", NULL)
46
 * XXX: means at most one of "this" or "that".
47
 */
48
49
struct fld_spec {
50
        const char      *name;
51
        struct token    *found;
52
};
53
54
static void
55 57360
vcc_ResetFldSpec(struct fld_spec *f)
56
{
57
58 906480
        for (; f->name != NULL; f++)
59 849120
                f->found = NULL;
60 57360
}
61
62
struct fld_spec *
63 57360
vcc_FldSpec(struct vcc *tl, const char *first, ...)
64
{
65
        struct fld_spec f[100], *r;
66 57360
        int n = 0;
67
        va_list ap;
68
        const char *p;
69
70 57360
        f[n++].name = first;
71 57360
        va_start(ap, first);
72 849120
        while (1) {
73 849120
                p = va_arg(ap, const char *);
74 849120
                if (p == NULL)
75 57360
                        break;
76 791760
                f[n++].name = p;
77 791760
                assert(n < 100);
78
        }
79 57360
        va_end(ap);
80 57360
        f[n++].name = NULL;
81
82 57360
        vcc_ResetFldSpec(f);
83
84 57360
        r = TlAlloc(tl, sizeof *r * n);
85 57360
        memcpy(r, f, n * sizeof *r);
86 57360
        return (r);
87
}
88
89
void
90 104240
vcc_IsField(struct vcc *tl, const struct token **t, struct fld_spec *fs)
91
{
92
        struct token *t_field;
93
94 104240
        SkipToken(tl, '.');
95 104240
        ExpectErr(tl, ID);
96 104240
        t_field = tl->t;
97 104240
        *t = t_field;
98 104240
        vcc_NextToken(tl);
99 104240
        SkipToken(tl, '=');
100
101 198320
        for (; fs->name != NULL; fs++) {
102 198280
                if (!vcc_IdIs(t_field, fs->name + 1))
103 94080
                        continue;
104 104200
                if (fs->found == NULL) {
105 104160
                        fs->found = t_field;
106 104160
                        return;
107
                }
108 40
                VSB_cat(tl->sb, "Field ");
109 40
                vcc_ErrToken(tl, t_field);
110 40
                VSB_cat(tl->sb, " redefined at:\n");
111 40
                vcc_ErrWhere(tl, t_field);
112 40
                VSB_cat(tl->sb, "\nFirst defined at:\n");
113 40
                vcc_ErrWhere(tl, fs->found);
114 40
                return;
115
        }
116 40
        VSB_cat(tl->sb, "Unknown field: ");
117 40
        vcc_ErrToken(tl, t_field);
118 40
        VSB_cat(tl->sb, " at\n");
119 40
        vcc_ErrWhere(tl, t_field);
120 104240
}
121
122
void
123 54760
vcc_FieldsOk(struct vcc *tl, const struct fld_spec *fs)
124
{
125
126 876160
        for (; fs->name != NULL; fs++) {
127 821400
                if (*fs->name == '!' && fs->found == NULL) {
128 0
                        VSB_printf(tl->sb,
129 0
                            "Mandatory field '%s' missing.\n", fs->name + 1);
130 0
                        tl->err = 1;
131 0
                }
132 821400
        }
133 54760
}