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