]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/mkesdb/yacc.y
Optionally bind ktls threads to NUMA domains
[FreeBSD/FreeBSD.git] / usr.bin / mkesdb / yacc.y
1 /* $FreeBSD$ */
2 /* $NetBSD: yacc.y,v 1.4 2005/06/02 02:09:25 lukem Exp $        */
3
4 %{
5 /*-
6  * SPDX-License-Identifier: BSD-2-Clause
7  *
8  * Copyright (c)2003 Citrus Project,
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32
33 #include <sys/cdefs.h>
34 #include <sys/types.h>
35 #include <sys/queue.h>
36
37 #include <assert.h>
38 #include <err.h>
39 #include <errno.h>
40 #include <limits.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <unistd.h>
45
46 #include "citrus_namespace.h"
47 #include "citrus_types.h"
48 #include "citrus_region.h"
49 #include "citrus_esdb_file.h"
50 #include "citrus_db_hash.h"
51 #include "citrus_db_factory.h"
52 #include "citrus_lookup_factory.h"
53
54 #include "ldef.h"
55
56 extern FILE                     *yyin;
57
58 static struct named_csid_list    named_csids;
59 static char                     *encoding, *name, *output = NULL, *variable;
60 static u_int32_t                 invalid;
61 static int                       debug = 0, num_csids = 0, use_invalid = 0;
62
63 static void      dump_file(void);
64 static void      register_named_csid(char *, u_int32_t);
65 static void      set_invalid(u_int32_t);
66 static void      set_prop_string(const char *, char **, char **);
67 %}
68 %union {
69         u_int32_t       i_value;
70         char            *s_value;
71 }
72
73 %token                  R_NAME R_ENCODING R_VARIABLE R_DEFCSID R_INVALID
74 %token                  R_LN
75 %token <i_value>        L_IMM
76 %token <s_value>        L_STRING
77
78 %%
79
80 file            : property
81                 { dump_file(); }
82
83 property        : /* empty */
84                 | property R_LN
85                 | property name R_LN
86                 | property encoding R_LN
87                 | property variable R_LN
88                 | property defcsid R_LN
89                 | property invalid R_LN
90
91 name            : R_NAME L_STRING
92                 {
93                         set_prop_string("NAME", &name, &$2);
94                 }
95
96 encoding        : R_ENCODING L_STRING
97                 {
98                         set_prop_string("ENCODING", &encoding, &$2);
99                 }
100 variable        : R_VARIABLE L_STRING
101                 {
102                         set_prop_string("VARIABLE", &variable, &$2);
103                 }
104 defcsid         : R_DEFCSID L_STRING L_IMM
105                 {
106                         register_named_csid($2, $3);
107                         $2 = NULL;
108                 }
109 invalid         : R_INVALID L_IMM
110                 {
111                         set_invalid($2);
112                 }
113 %%
114
115 int
116 yyerror(const char *s)
117 {
118
119         fprintf(stderr, "%s in %d\n", s, linenumber);
120
121         return (0);
122 }
123
124 #define CHKERR(ret, func, a)                                            \
125 do {                                                                    \
126         ret = func a;                                                   \
127         if (ret)                                                        \
128                 errx(EXIT_FAILURE, "%s: %s", #func, strerror(ret));     \
129 } while (/*CONSTCOND*/0)
130 static void
131 dump_file(void)
132 {
133         struct _db_factory *df;
134         struct _region data;
135         struct named_csid *csid;
136         FILE *fp;
137         char buf[100];
138         void *serialized;
139         size_t size;
140         int i, ret;
141
142         ret = 0;
143         if (!name) {
144                 fprintf(stderr, "NAME is mandatory.\n");
145                 ret = 1;
146         }
147         if (!encoding) {
148                 fprintf(stderr, "ENCODING is mandatory.\n");
149                 ret = 1;
150         }
151         if (ret)
152                 exit(1);
153
154         /*
155          * build database
156          */
157         CHKERR(ret, _db_factory_create, (&df, _db_hash_std, NULL));
158
159         /* store version */
160         CHKERR(ret, _db_factory_add32_by_s, (df, _CITRUS_ESDB_SYM_VERSION,
161             _CITRUS_ESDB_VERSION));
162
163         /* store encoding */
164         CHKERR(ret, _db_factory_addstr_by_s, (df, _CITRUS_ESDB_SYM_ENCODING,
165             encoding));
166
167         /* store variable */
168         if (variable)
169                 CHKERR(ret, _db_factory_addstr_by_s,
170                     (df, _CITRUS_ESDB_SYM_VARIABLE, variable));
171
172         /* store invalid */
173         if (use_invalid)
174                 CHKERR(ret, _db_factory_add32_by_s, (df,
175                     _CITRUS_ESDB_SYM_INVALID, invalid));
176
177         /* store num of charsets */
178         CHKERR(ret, _db_factory_add32_by_s, (df, _CITRUS_ESDB_SYM_NUM_CHARSETS,
179             num_csids));
180         i = 0;
181         STAILQ_FOREACH(csid, &named_csids, ci_entry) {
182                 snprintf(buf, sizeof(buf), _CITRUS_ESDB_SYM_CSNAME_PREFIX "%d",
183                     i);
184                 CHKERR(ret, _db_factory_addstr_by_s,
185                     (df, buf, csid->ci_symbol));
186                 snprintf(buf, sizeof(buf), _CITRUS_ESDB_SYM_CSID_PREFIX "%d",
187                     i);
188                 CHKERR(ret, _db_factory_add32_by_s, (df, buf, csid->ci_csid));
189                 i++;
190         }
191
192         /*
193          * dump database to file
194          */
195         fp = output ? fopen(output, "wb") : stdout;
196         if (fp == NULL) {
197                 perror("fopen");
198                 exit(1);
199         }
200
201         /* dump database body */
202         size = _db_factory_calc_size(df);
203         serialized = malloc(size);
204         _region_init(&data, serialized, size);
205         CHKERR(ret, _db_factory_serialize, (df, _CITRUS_ESDB_MAGIC, &data));
206         if (fwrite(serialized, size, 1, fp) != 1)
207                 err(EXIT_FAILURE, "fwrite");
208
209         fclose(fp);
210 }
211
212 static void
213 set_prop_string(const char *res, char **store, char **data)
214 {
215         char buf[256];
216
217         if (*store) {
218                 snprintf(buf, sizeof(buf),
219                     "%s is duplicated. ignored the one", res);
220                 yyerror(buf);
221                 return;
222         }
223
224         *store = *data;
225         *data = NULL;
226 }
227
228 static void
229 set_invalid(u_int32_t inv)
230 {
231
232         invalid = inv;
233         use_invalid = 1;
234 }
235
236 static void
237 register_named_csid(char *sym, u_int32_t val)
238 {
239         struct named_csid *csid;
240
241         STAILQ_FOREACH(csid, &named_csids, ci_entry) {
242                 if (strcmp(csid->ci_symbol, sym) == 0) {
243                         yyerror("multiply defined CSID");
244                         exit(1);
245                 }
246         }
247
248         csid = malloc(sizeof(*csid));
249         if (csid == NULL) {
250                 perror("malloc");
251                 exit(1);
252         }
253         csid->ci_symbol = sym;
254         csid->ci_csid = val;
255         STAILQ_INSERT_TAIL(&named_csids, csid, ci_entry);
256         num_csids++;
257 }
258
259 static void
260 do_mkdb(FILE *in)
261 {
262         FILE *out;
263         int ret;
264
265         /* dump DB to file */
266         out = output ? fopen(output, "wb") : stdout;
267         if (out == NULL)
268                 err(EXIT_FAILURE, "fopen");
269
270         ret = _lookup_factory_convert(out, in);
271         fclose(out);
272         if (ret && output)
273                 unlink(output); /* dump failure */
274         if (ret)
275                 errx(EXIT_FAILURE, "%s\n", strerror(ret));
276 }
277
278 static void
279 usage(void)
280 {
281         errx(EXIT_FAILURE,
282             "usage:\n"
283             "\t%s [-d] [-o outfile] [infile]\n"
284             "\t%s -m [-d] [-o outfile] [infile]",
285             getprogname(), getprogname());
286 }
287
288 int
289 main(int argc, char **argv)
290 {
291         FILE *in = NULL;
292         int ch, mkdb = 0;
293
294         while ((ch = getopt(argc, argv, "do:m")) != EOF) {
295                 switch (ch) {
296                 case 'd':
297                         debug = 1;
298                         break;
299                 case 'o':
300                         output = strdup(optarg);
301                         break;
302                 case 'm':
303                         mkdb = 1;
304                         break;
305                 default:
306                         usage();
307                 }
308         }
309
310         argc -= optind;
311         argv += optind;
312         switch (argc) {
313         case 0:
314                 in = stdin;
315                 break;
316         case 1:
317                 in = fopen(argv[0], "r");
318                 if (!in)
319                         err(EXIT_FAILURE, "%s", argv[0]);
320                 break;
321         default:
322                 usage();
323         }
324
325         if (mkdb)
326                 do_mkdb(in);
327         else {
328                 STAILQ_INIT(&named_csids);
329                 yyin = in;
330                 yyparse();
331         }
332
333         return (0);
334 }