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 35175
vcc_ResetFldSpec(struct fld_spec *f)
56
{
57
58 487950
        for (; f->name != NULL; f++)
59 452775
                f->found = NULL;
60 35175
}
61
62
struct fld_spec *
63 35175
vcc_FldSpec(struct vcc *tl, const char *first, ...)
64
{
65
        struct fld_spec f[100], *r;
66 35175
        int n = 0;
67
        va_list ap;
68
        const char *p;
69
70 35175
        f[n++].name = first;
71 35175
        va_start(ap, first);
72 452775
        while (1) {
73 452775
                p = va_arg(ap, const char *);
74 452775
                if (p == NULL)
75 35175
                        break;
76 417600
                f[n++].name = p;
77 417600
                assert(n < 100);
78
        }
79 35175
        va_end(ap);
80 35175
        f[n++].name = NULL;
81
82 35175
        vcc_ResetFldSpec(f);
83
84 35175
        r = TlAlloc(tl, sizeof *r * n);
85 35175
        memcpy(r, f, n * sizeof *r);
86 35175
        return (r);
87
}
88
89
void
90 63250
vcc_IsField(struct vcc *tl, const struct token **t, struct fld_spec *fs)
91
{
92
        struct token *t_field;
93
94 63250
        SkipToken(tl, '.');
95 63250
        ExpectErr(tl, ID);
96 63250
        t_field = tl->t;
97 63250
        *t = t_field;
98 63250
        vcc_NextToken(tl);
99 63250
        SkipToken(tl, '=');
100
101 115325
        for (; fs->name != NULL; fs++) {
102 115300
                if (!vcc_IdIs(t_field, fs->name + 1))
103 52075
                        continue;
104 63225
                if (fs->found == NULL) {
105 63200
                        fs->found = t_field;
106 63200
                        return;
107
                }
108 25
                VSB_cat(tl->sb, "Field ");
109 25
                vcc_ErrToken(tl, t_field);
110 25
                VSB_cat(tl->sb, " redefined at:\n");
111 25
                vcc_ErrWhere(tl, t_field);
112 25
                VSB_cat(tl->sb, "\nFirst defined at:\n");
113 25
                vcc_ErrWhere(tl, fs->found);
114 25
                return;
115
        }
116 25
        VSB_cat(tl->sb, "Unknown field: ");
117 25
        vcc_ErrToken(tl, t_field);
118 25
        VSB_cat(tl->sb, " at\n");
119 25
        vcc_ErrWhere(tl, t_field);
120 63250
}
121
122
void
123 33600
vcc_FieldsOk(struct vcc *tl, const struct fld_spec *fs)
124
{
125
126 470400
        for (; fs->name != NULL; fs++) {
127 436800
                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 436800
        }
133 33600
}