130e4e410SJoerg Sonnenberger /* $NetBSD: src/usr.bin/mkesdb/yacc.y,v 1.3 2004/01/02 12:09:48 itojun Exp $ */
230e4e410SJoerg Sonnenberger
330e4e410SJoerg Sonnenberger %{
430e4e410SJoerg Sonnenberger /*-
530e4e410SJoerg Sonnenberger * Copyright (c)2003 Citrus Project,
630e4e410SJoerg Sonnenberger * All rights reserved.
730e4e410SJoerg Sonnenberger *
830e4e410SJoerg Sonnenberger * Redistribution and use in source and binary forms, with or without
930e4e410SJoerg Sonnenberger * modification, are permitted provided that the following conditions
1030e4e410SJoerg Sonnenberger * are met:
1130e4e410SJoerg Sonnenberger * 1. Redistributions of source code must retain the above copyright
1230e4e410SJoerg Sonnenberger * notice, this list of conditions and the following disclaimer.
1330e4e410SJoerg Sonnenberger * 2. Redistributions in binary form must reproduce the above copyright
1430e4e410SJoerg Sonnenberger * notice, this list of conditions and the following disclaimer in the
1530e4e410SJoerg Sonnenberger * documentation and/or other materials provided with the distribution.
1630e4e410SJoerg Sonnenberger *
1730e4e410SJoerg Sonnenberger * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1830e4e410SJoerg Sonnenberger * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1930e4e410SJoerg Sonnenberger * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2030e4e410SJoerg Sonnenberger * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2130e4e410SJoerg Sonnenberger * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2230e4e410SJoerg Sonnenberger * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2330e4e410SJoerg Sonnenberger * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2430e4e410SJoerg Sonnenberger * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2530e4e410SJoerg Sonnenberger * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2630e4e410SJoerg Sonnenberger * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2730e4e410SJoerg Sonnenberger * SUCH DAMAGE.
2830e4e410SJoerg Sonnenberger */
2930e4e410SJoerg Sonnenberger
3030e4e410SJoerg Sonnenberger #include <sys/types.h>
3130e4e410SJoerg Sonnenberger #include <sys/queue.h>
3230e4e410SJoerg Sonnenberger #include <assert.h>
3330e4e410SJoerg Sonnenberger #include <err.h>
3430e4e410SJoerg Sonnenberger #include <errno.h>
3530e4e410SJoerg Sonnenberger #include <limits.h>
3630e4e410SJoerg Sonnenberger #include <stdio.h>
3730e4e410SJoerg Sonnenberger #include <stdlib.h>
3830e4e410SJoerg Sonnenberger #include <string.h>
3930e4e410SJoerg Sonnenberger #include <unistd.h>
4030e4e410SJoerg Sonnenberger
4130e4e410SJoerg Sonnenberger #include "citrus_namespace.h"
4230e4e410SJoerg Sonnenberger #include "citrus_types.h"
4330e4e410SJoerg Sonnenberger #include "citrus_region.h"
4430e4e410SJoerg Sonnenberger #include "citrus_esdb_file.h"
4530e4e410SJoerg Sonnenberger #include "citrus_db_hash.h"
4630e4e410SJoerg Sonnenberger #include "citrus_db_factory.h"
4730e4e410SJoerg Sonnenberger #include "citrus_lookup_factory.h"
4830e4e410SJoerg Sonnenberger
4930e4e410SJoerg Sonnenberger #include "ldef.h"
5030e4e410SJoerg Sonnenberger
5130e4e410SJoerg Sonnenberger extern FILE *yyin;
5230e4e410SJoerg Sonnenberger
5330e4e410SJoerg Sonnenberger static int debug = 0, num_csids = 0;
5430e4e410SJoerg Sonnenberger static char *output = NULL;
5530e4e410SJoerg Sonnenberger static char *name, *encoding, *variable;
5630e4e410SJoerg Sonnenberger static uint32_t invalid;
5730e4e410SJoerg Sonnenberger static int use_invalid = 0;
5830e4e410SJoerg Sonnenberger static struct named_csid_list named_csids;
5930e4e410SJoerg Sonnenberger
6030e4e410SJoerg Sonnenberger static void dump_file(void);
6130e4e410SJoerg Sonnenberger static void register_named_csid(char *, uint32_t);
6230e4e410SJoerg Sonnenberger static void set_prop_string(const char *, char **, char **);
6330e4e410SJoerg Sonnenberger static void set_invalid(uint32_t);
64eb74dec6SJohn Marino
65*98d44196SSascha Wildner #if YYPATCH < 20180510
66eb74dec6SJohn Marino int yylex (void);
67*98d44196SSascha Wildner #endif
6830e4e410SJoerg Sonnenberger %}
6930e4e410SJoerg Sonnenberger %union {
7030e4e410SJoerg Sonnenberger uint32_t i_value;
7130e4e410SJoerg Sonnenberger char *s_value;
7230e4e410SJoerg Sonnenberger }
7330e4e410SJoerg Sonnenberger
7430e4e410SJoerg Sonnenberger %token R_NAME R_ENCODING R_VARIABLE R_DEFCSID R_INVALID
7530e4e410SJoerg Sonnenberger %token R_LN
7630e4e410SJoerg Sonnenberger %token <i_value> L_IMM
7730e4e410SJoerg Sonnenberger %token <s_value> L_STRING
7830e4e410SJoerg Sonnenberger
7930e4e410SJoerg Sonnenberger %%
8030e4e410SJoerg Sonnenberger
8130e4e410SJoerg Sonnenberger file : property
8230e4e410SJoerg Sonnenberger { dump_file(); }
8330e4e410SJoerg Sonnenberger
8430e4e410SJoerg Sonnenberger property : /* empty */
8530e4e410SJoerg Sonnenberger | property R_LN
8630e4e410SJoerg Sonnenberger | property name R_LN
8730e4e410SJoerg Sonnenberger | property encoding R_LN
8830e4e410SJoerg Sonnenberger | property variable R_LN
8930e4e410SJoerg Sonnenberger | property defcsid R_LN
9030e4e410SJoerg Sonnenberger | property invalid R_LN
9130e4e410SJoerg Sonnenberger
9230e4e410SJoerg Sonnenberger name : R_NAME L_STRING
9330e4e410SJoerg Sonnenberger {
9430e4e410SJoerg Sonnenberger set_prop_string("NAME", &name, &$2);
9530e4e410SJoerg Sonnenberger }
9630e4e410SJoerg Sonnenberger
9730e4e410SJoerg Sonnenberger encoding : R_ENCODING L_STRING
9830e4e410SJoerg Sonnenberger {
9930e4e410SJoerg Sonnenberger set_prop_string("ENCODING", &encoding, &$2);
10030e4e410SJoerg Sonnenberger }
10130e4e410SJoerg Sonnenberger variable : R_VARIABLE L_STRING
10230e4e410SJoerg Sonnenberger {
10330e4e410SJoerg Sonnenberger set_prop_string("VARIABLE", &variable, &$2);
10430e4e410SJoerg Sonnenberger }
10530e4e410SJoerg Sonnenberger defcsid : R_DEFCSID L_STRING L_IMM
10630e4e410SJoerg Sonnenberger {
10730e4e410SJoerg Sonnenberger register_named_csid($2, $3);
10830e4e410SJoerg Sonnenberger $2 = NULL;
10930e4e410SJoerg Sonnenberger }
11030e4e410SJoerg Sonnenberger invalid : R_INVALID L_IMM
11130e4e410SJoerg Sonnenberger {
11230e4e410SJoerg Sonnenberger set_invalid($2);
11330e4e410SJoerg Sonnenberger }
11430e4e410SJoerg Sonnenberger %%
11530e4e410SJoerg Sonnenberger
11630e4e410SJoerg Sonnenberger int
11730e4e410SJoerg Sonnenberger yyerror(const char *s)
11830e4e410SJoerg Sonnenberger {
119eb74dec6SJohn Marino fprintf(stderr, "%s in %d\n", s, aline_number);
12030e4e410SJoerg Sonnenberger
12130e4e410SJoerg Sonnenberger return (0);
12230e4e410SJoerg Sonnenberger }
12330e4e410SJoerg Sonnenberger
12430e4e410SJoerg Sonnenberger #define CHKERR(ret, func, a) \
12530e4e410SJoerg Sonnenberger do { \
12630e4e410SJoerg Sonnenberger ret = func a; \
12730e4e410SJoerg Sonnenberger if (ret) \
12830e4e410SJoerg Sonnenberger errx(EXIT_FAILURE, "%s: %s", #func, strerror(ret)); \
12930e4e410SJoerg Sonnenberger } while (/*CONSTCOND*/0)
13030e4e410SJoerg Sonnenberger static void
dump_file(void)13130e4e410SJoerg Sonnenberger dump_file(void)
13230e4e410SJoerg Sonnenberger {
13330e4e410SJoerg Sonnenberger int ret;
13430e4e410SJoerg Sonnenberger FILE *fp;
13530e4e410SJoerg Sonnenberger struct _db_factory *df;
13630e4e410SJoerg Sonnenberger struct _region data;
13730e4e410SJoerg Sonnenberger struct named_csid *csid;
13830e4e410SJoerg Sonnenberger char buf[100];
13930e4e410SJoerg Sonnenberger int i;
14030e4e410SJoerg Sonnenberger void *serialized;
14130e4e410SJoerg Sonnenberger size_t size;
14230e4e410SJoerg Sonnenberger
14330e4e410SJoerg Sonnenberger ret = 0;
14430e4e410SJoerg Sonnenberger if (!name) {
14530e4e410SJoerg Sonnenberger fprintf(stderr, "NAME is mandatory.\n");
14630e4e410SJoerg Sonnenberger ret = 1;
14730e4e410SJoerg Sonnenberger }
14830e4e410SJoerg Sonnenberger if (!encoding) {
14930e4e410SJoerg Sonnenberger fprintf(stderr, "ENCODING is mandatory.\n");
15030e4e410SJoerg Sonnenberger ret = 1;
15130e4e410SJoerg Sonnenberger }
15230e4e410SJoerg Sonnenberger if (ret)
15330e4e410SJoerg Sonnenberger exit(1);
15430e4e410SJoerg Sonnenberger
15530e4e410SJoerg Sonnenberger /*
15630e4e410SJoerg Sonnenberger * build database
15730e4e410SJoerg Sonnenberger */
15830e4e410SJoerg Sonnenberger CHKERR(ret, _db_factory_create, (&df, _db_hash_std, NULL));
15930e4e410SJoerg Sonnenberger
16030e4e410SJoerg Sonnenberger /* store version */
16130e4e410SJoerg Sonnenberger CHKERR(ret, _db_factory_add32_by_s, (df, _CITRUS_ESDB_SYM_VERSION,
16230e4e410SJoerg Sonnenberger _CITRUS_ESDB_VERSION));
16330e4e410SJoerg Sonnenberger
16430e4e410SJoerg Sonnenberger /* store encoding */
16530e4e410SJoerg Sonnenberger CHKERR(ret, _db_factory_addstr_by_s, (df, _CITRUS_ESDB_SYM_ENCODING,
16630e4e410SJoerg Sonnenberger encoding));
16730e4e410SJoerg Sonnenberger
16830e4e410SJoerg Sonnenberger /* store variable */
16930e4e410SJoerg Sonnenberger if (variable)
17030e4e410SJoerg Sonnenberger CHKERR(ret, _db_factory_addstr_by_s,
17130e4e410SJoerg Sonnenberger (df, _CITRUS_ESDB_SYM_VARIABLE, variable));
17230e4e410SJoerg Sonnenberger
17330e4e410SJoerg Sonnenberger /* store invalid */
17430e4e410SJoerg Sonnenberger if (use_invalid)
17530e4e410SJoerg Sonnenberger CHKERR(ret, _db_factory_add32_by_s, (df,
17630e4e410SJoerg Sonnenberger _CITRUS_ESDB_SYM_INVALID,
17730e4e410SJoerg Sonnenberger invalid));
17830e4e410SJoerg Sonnenberger
17930e4e410SJoerg Sonnenberger /* store num of charsets */
18030e4e410SJoerg Sonnenberger CHKERR(ret, _db_factory_add32_by_s, (df, _CITRUS_ESDB_SYM_NUM_CHARSETS,
18130e4e410SJoerg Sonnenberger num_csids));
18230e4e410SJoerg Sonnenberger i=0;
18330e4e410SJoerg Sonnenberger STAILQ_FOREACH(csid, &named_csids, ci_entry) {
18430e4e410SJoerg Sonnenberger snprintf(buf, sizeof(buf), _CITRUS_ESDB_SYM_CSNAME_PREFIX "%d",
18530e4e410SJoerg Sonnenberger i);
18630e4e410SJoerg Sonnenberger CHKERR(ret, _db_factory_addstr_by_s,
18730e4e410SJoerg Sonnenberger (df, buf, csid->ci_symbol));
18830e4e410SJoerg Sonnenberger snprintf(buf, sizeof(buf), _CITRUS_ESDB_SYM_CSID_PREFIX "%d",
18930e4e410SJoerg Sonnenberger i);
19030e4e410SJoerg Sonnenberger CHKERR(ret, _db_factory_add32_by_s, (df, buf, csid->ci_csid));
19130e4e410SJoerg Sonnenberger i++;
19230e4e410SJoerg Sonnenberger }
19330e4e410SJoerg Sonnenberger
19430e4e410SJoerg Sonnenberger /*
19530e4e410SJoerg Sonnenberger * dump database to file
19630e4e410SJoerg Sonnenberger */
19730e4e410SJoerg Sonnenberger if (output)
19830e4e410SJoerg Sonnenberger fp = fopen(output, "wb");
19930e4e410SJoerg Sonnenberger else
20030e4e410SJoerg Sonnenberger fp = stdout;
20130e4e410SJoerg Sonnenberger
20230e4e410SJoerg Sonnenberger if (fp == NULL) {
20330e4e410SJoerg Sonnenberger perror("fopen");
20430e4e410SJoerg Sonnenberger exit(1);
20530e4e410SJoerg Sonnenberger }
20630e4e410SJoerg Sonnenberger
20730e4e410SJoerg Sonnenberger /* dump database body */
20830e4e410SJoerg Sonnenberger size = _db_factory_calc_size(df);
20930e4e410SJoerg Sonnenberger serialized = malloc(size);
21030e4e410SJoerg Sonnenberger _region_init(&data, serialized, size);
21130e4e410SJoerg Sonnenberger CHKERR(ret, _db_factory_serialize, (df, _CITRUS_ESDB_MAGIC, &data));
21230e4e410SJoerg Sonnenberger if (fwrite(serialized, size, 1, fp) != 1)
21330e4e410SJoerg Sonnenberger err(EXIT_FAILURE, "fwrite");
21430e4e410SJoerg Sonnenberger
21530e4e410SJoerg Sonnenberger fclose(fp);
21630e4e410SJoerg Sonnenberger }
21730e4e410SJoerg Sonnenberger
21830e4e410SJoerg Sonnenberger static void
set_prop_string(const char * res,char ** store,char ** data)21930e4e410SJoerg Sonnenberger set_prop_string(const char *res, char **store, char **data)
22030e4e410SJoerg Sonnenberger {
22130e4e410SJoerg Sonnenberger char buf[256];
22230e4e410SJoerg Sonnenberger
22330e4e410SJoerg Sonnenberger if (*store) {
22430e4e410SJoerg Sonnenberger snprintf(buf, sizeof(buf),
22530e4e410SJoerg Sonnenberger "%s is duplicated. ignored the one", res);
22630e4e410SJoerg Sonnenberger yyerror(buf);
22730e4e410SJoerg Sonnenberger return;
22830e4e410SJoerg Sonnenberger }
22930e4e410SJoerg Sonnenberger
23030e4e410SJoerg Sonnenberger *store = *data;
23130e4e410SJoerg Sonnenberger *data = NULL;
23230e4e410SJoerg Sonnenberger }
23330e4e410SJoerg Sonnenberger
23430e4e410SJoerg Sonnenberger static void
set_invalid(uint32_t inv)23530e4e410SJoerg Sonnenberger set_invalid(uint32_t inv)
23630e4e410SJoerg Sonnenberger {
23730e4e410SJoerg Sonnenberger invalid = inv;
23830e4e410SJoerg Sonnenberger use_invalid = 1;
23930e4e410SJoerg Sonnenberger }
24030e4e410SJoerg Sonnenberger
24130e4e410SJoerg Sonnenberger static void
register_named_csid(char * sym,uint32_t val)24230e4e410SJoerg Sonnenberger register_named_csid(char *sym, uint32_t val)
24330e4e410SJoerg Sonnenberger {
24430e4e410SJoerg Sonnenberger struct named_csid *csid;
24530e4e410SJoerg Sonnenberger
24630e4e410SJoerg Sonnenberger STAILQ_FOREACH(csid, &named_csids, ci_entry) {
24730e4e410SJoerg Sonnenberger if (strcmp(csid->ci_symbol, sym) == 0) {
24830e4e410SJoerg Sonnenberger yyerror("multiply defined CSID");
24930e4e410SJoerg Sonnenberger exit(1);
25030e4e410SJoerg Sonnenberger }
25130e4e410SJoerg Sonnenberger }
25230e4e410SJoerg Sonnenberger
25330e4e410SJoerg Sonnenberger csid = malloc(sizeof(*csid));
25430e4e410SJoerg Sonnenberger if (csid == NULL) {
25530e4e410SJoerg Sonnenberger perror("malloc");
25630e4e410SJoerg Sonnenberger exit(1);
25730e4e410SJoerg Sonnenberger }
25830e4e410SJoerg Sonnenberger csid->ci_symbol = sym;
25930e4e410SJoerg Sonnenberger csid->ci_csid = val;
26030e4e410SJoerg Sonnenberger STAILQ_INSERT_TAIL(&named_csids, csid, ci_entry);
26130e4e410SJoerg Sonnenberger num_csids++;
26230e4e410SJoerg Sonnenberger }
26330e4e410SJoerg Sonnenberger
26430e4e410SJoerg Sonnenberger static void
do_mkdb(FILE * in)26530e4e410SJoerg Sonnenberger do_mkdb(FILE *in)
26630e4e410SJoerg Sonnenberger {
26730e4e410SJoerg Sonnenberger int ret;
26830e4e410SJoerg Sonnenberger FILE *out;
26930e4e410SJoerg Sonnenberger
27030e4e410SJoerg Sonnenberger /* dump DB to file */
27130e4e410SJoerg Sonnenberger if (output)
27230e4e410SJoerg Sonnenberger out = fopen(output, "wb");
27330e4e410SJoerg Sonnenberger else
27430e4e410SJoerg Sonnenberger out = stdout;
27530e4e410SJoerg Sonnenberger
27630e4e410SJoerg Sonnenberger if (out==NULL)
27730e4e410SJoerg Sonnenberger err(EXIT_FAILURE, "fopen");
27830e4e410SJoerg Sonnenberger
27930e4e410SJoerg Sonnenberger ret = _lookup_factory_convert(out, in);
28030e4e410SJoerg Sonnenberger fclose(out);
28130e4e410SJoerg Sonnenberger if (ret && output)
28230e4e410SJoerg Sonnenberger unlink(output); /* dump failure */
28330e4e410SJoerg Sonnenberger if (ret)
28430e4e410SJoerg Sonnenberger errx(EXIT_FAILURE, "%s\n", strerror(ret));
28530e4e410SJoerg Sonnenberger }
28630e4e410SJoerg Sonnenberger
28730e4e410SJoerg Sonnenberger static void
usage(void)28830e4e410SJoerg Sonnenberger usage(void)
28930e4e410SJoerg Sonnenberger {
29030e4e410SJoerg Sonnenberger errx(EXIT_FAILURE,
29130e4e410SJoerg Sonnenberger "usage:\n"
29230e4e410SJoerg Sonnenberger "\t%s [-o outfile] [infile]\n"
29330e4e410SJoerg Sonnenberger "\t%s -m [-o outfile] [infile]",
29430e4e410SJoerg Sonnenberger getprogname(), getprogname());
29530e4e410SJoerg Sonnenberger }
29630e4e410SJoerg Sonnenberger
29730e4e410SJoerg Sonnenberger int
main(int argc,char ** argv)29830e4e410SJoerg Sonnenberger main(int argc, char **argv)
29930e4e410SJoerg Sonnenberger {
30030e4e410SJoerg Sonnenberger int ch;
30130e4e410SJoerg Sonnenberger FILE *in = NULL;
30230e4e410SJoerg Sonnenberger int mkdb = 0;
30330e4e410SJoerg Sonnenberger
3049b0ec895SSascha Wildner while ((ch=getopt(argc, argv, "do:m")) != -1) {
30530e4e410SJoerg Sonnenberger switch (ch) {
30630e4e410SJoerg Sonnenberger case 'd':
30730e4e410SJoerg Sonnenberger debug = 1;
30830e4e410SJoerg Sonnenberger break;
30930e4e410SJoerg Sonnenberger case 'o':
31030e4e410SJoerg Sonnenberger output = strdup(optarg);
31130e4e410SJoerg Sonnenberger break;
31230e4e410SJoerg Sonnenberger case 'm':
31330e4e410SJoerg Sonnenberger mkdb = 1;
31430e4e410SJoerg Sonnenberger break;
31530e4e410SJoerg Sonnenberger default:
31630e4e410SJoerg Sonnenberger usage();
31730e4e410SJoerg Sonnenberger }
31830e4e410SJoerg Sonnenberger }
31930e4e410SJoerg Sonnenberger
32030e4e410SJoerg Sonnenberger argc-=optind;
32130e4e410SJoerg Sonnenberger argv+=optind;
32230e4e410SJoerg Sonnenberger switch (argc) {
32330e4e410SJoerg Sonnenberger case 0:
32430e4e410SJoerg Sonnenberger in = stdin;
32530e4e410SJoerg Sonnenberger break;
32630e4e410SJoerg Sonnenberger case 1:
32730e4e410SJoerg Sonnenberger in = fopen(argv[0], "r");
32830e4e410SJoerg Sonnenberger if (!in)
3299462167aSSascha Wildner err(EXIT_FAILURE, "%s", argv[0]);
33030e4e410SJoerg Sonnenberger break;
33130e4e410SJoerg Sonnenberger default:
33230e4e410SJoerg Sonnenberger usage();
33330e4e410SJoerg Sonnenberger }
33430e4e410SJoerg Sonnenberger
33530e4e410SJoerg Sonnenberger if (mkdb)
33630e4e410SJoerg Sonnenberger do_mkdb(in);
33730e4e410SJoerg Sonnenberger else {
33830e4e410SJoerg Sonnenberger STAILQ_INIT(&named_csids);
33930e4e410SJoerg Sonnenberger yyin=in;
34030e4e410SJoerg Sonnenberger yyparse();
34130e4e410SJoerg Sonnenberger }
34230e4e410SJoerg Sonnenberger
34330e4e410SJoerg Sonnenberger return (0);
34430e4e410SJoerg Sonnenberger }
345