1 /* $NetBSD: yacc.y,v 1.7 2006/09/09 14:35:17 tnozaki Exp $ */
5 * Copyright (c)2003, 2006 Citrus Project,
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/types.h>
40 #include <netinet/in.h>
44 #include "citrus_namespace.h"
45 #include "citrus_types.h"
46 #include "citrus_mapper_std_file.h"
47 #include "citrus_region.h"
48 #include "citrus_db_factory.h"
49 #include "citrus_db_hash.h"
50 #include "citrus_lookup_factory.h"
51 #include "citrus_pivot_factory.h"
56 static char *output = NULL;
57 static void *table = NULL;
58 static size_t table_size;
59 static char *map_name;
61 static u_int32_t dst_invalid, dst_ilseq, oob_mode, dst_unit_bits;
62 static void (*putfunc)(void *, size_t, u_int32_t) = 0;
64 static u_int32_t src_next;
66 static u_int32_t done_flag = 0;
67 #define DF_TYPE 0x00000001
68 #define DF_NAME 0x00000002
69 #define DF_SRC_ZONE 0x00000004
70 #define DF_DST_INVALID 0x00000008
71 #define DF_DST_ILSEQ 0x00000010
72 #define DF_DST_UNIT_BITS 0x00000020
73 #define DF_OOB_MODE 0x00000040
75 static linear_zone_t rowcol[_CITRUS_MAPPER_STD_ROWCOL_MAX];
76 static size_t rowcol_len = 0;
77 static u_int32_t rowcol_bits = 0, rowcol_mask = 0;
79 static void dump_file(void);
80 static void setup_map(void);
81 static void set_type(int);
82 static void set_name(char *);
83 static void set_src_zone(u_int32_t);
84 static void set_dst_invalid(u_int32_t);
85 static void set_dst_ilseq(u_int32_t);
86 static void set_dst_unit_bits(u_int32_t);
87 static void set_oob_mode(u_int32_t);
88 static int check_src(u_int32_t, u_int32_t);
89 static void store(const linear_zone_t *, u_int32_t, int);
90 static void put8(void *, size_t, u_int32_t);
91 static void put16(void *, size_t, u_int32_t);
92 static void put32(void *, size_t, u_int32_t);
93 static void set_range(u_int32_t, u_int32_t);
94 static void set_src(linear_zone_t *, u_int32_t, u_int32_t);
102 linear_zone_t lz_value;
105 %token R_TYPE R_NAME R_SRC_ZONE R_DST_UNIT_BITS
106 %token R_DST_INVALID R_DST_ILSEQ
107 %token R_BEGIN_MAP R_END_MAP R_INVALID R_ROWCOL
108 %token R_ILSEQ R_OOB_MODE
110 %token <i_value> L_IMM
111 %token <s_value> L_STRING
114 %type <i_value> dst types oob_mode_sel zone
118 file : property mapping lns
121 property : /* empty */
126 | property dst_invalid
128 | property dst_unit_bits
131 name : R_NAME L_STRING { set_name($2); $2 = NULL; }
132 type : R_TYPE types { set_type($2); }
133 types : R_ROWCOL { $$ = R_ROWCOL; }
134 range : L_IMM '-' L_IMM { set_range($1, $3); }
139 src_zone : R_SRC_ZONE zone { set_src_zone($2); }
143 | range '/' range '/' ranges L_IMM {
147 dst_invalid : R_DST_INVALID L_IMM { set_dst_invalid($2); }
148 dst_ilseq : R_DST_ILSEQ L_IMM { set_dst_ilseq($2); }
149 dst_unit_bits : R_DST_UNIT_BITS L_IMM { set_dst_unit_bits($2); }
150 oob_mode : R_OOB_MODE oob_mode_sel { set_oob_mode($2); }
152 oob_mode_sel : R_INVALID { $$ = _CITRUS_MAPPER_STD_OOB_NONIDENTICAL; }
153 | R_ILSEQ { $$ = _CITRUS_MAPPER_STD_OOB_ILSEQ; }
155 mapping : begin_map map_elems R_END_MAP
156 begin_map : R_BEGIN_MAP lns { setup_map(); }
158 map_elems : /* empty */
159 | map_elems map_elem lns
161 map_elem : src '=' dst
162 { store(&$1, $3, 0); }
164 { store(&$1, $3, 1); }
180 set_src(&$$, src_next, src_next);
184 set_src(&$$, $1, $1);
188 set_src(&$$, $1, $3);
192 set_src(&$$, src_next, $2);
200 warning(const char *s)
202 fprintf(stderr, "%s in %d\n", s, aline_number);
206 yyerror(const char *s)
213 put8(void *ptr, size_t ofs, u_int32_t val)
215 *((u_int8_t *)ptr + ofs) = val;
219 put16(void *ptr, size_t ofs, u_int32_t val)
221 u_int16_t oval = htons(val);
222 memcpy((u_int16_t *)ptr + ofs, &oval, 2);
226 put32(void *ptr, size_t ofs, u_int32_t val)
228 u_int32_t oval = htonl(val);
229 memcpy((u_int32_t *)ptr + ofs, &oval, 4);
241 table_size = p->width;
244 table_size *= p->width;
246 table = (void *)malloc(table_size * dst_unit_bits / 8);
253 case _CITRUS_MAPPER_STD_OOB_NONIDENTICAL:
256 case _CITRUS_MAPPER_STD_OOB_ILSEQ:
262 for (i = 0; i < table_size; i++)
263 (*putfunc)(table, i, val);
270 if ((done_flag & DF_SRC_ZONE)==0) {
271 fprintf(stderr, "SRC_ZONE is mandatory.\n");
274 if ((done_flag & DF_DST_UNIT_BITS)==0) {
275 fprintf(stderr, "DST_UNIT_BITS is mandatory.\n");
279 if ((done_flag & DF_DST_INVALID) == 0)
280 dst_invalid = 0xFFFFFFFF;
281 if ((done_flag & DF_DST_ILSEQ) == 0)
282 dst_ilseq = 0xFFFFFFFE;
283 if ((done_flag & DF_OOB_MODE) == 0)
284 oob_mode = _CITRUS_MAPPER_STD_OOB_NONIDENTICAL;
290 create_rowcol_info(struct _region *r)
296 ptr = malloc(_CITRUS_MAPPER_STD_ROWCOL_INFO_SIZE);
298 err(EXIT_FAILURE, "malloc");
299 put32(ptr, ofs, rowcol_bits); ofs++;
300 put32(ptr, ofs, dst_invalid); ofs++;
302 /* XXX: keep backward compatibility */
303 switch (rowcol_len) {
305 put32(ptr, ofs, 0); ofs++;
306 put32(ptr, ofs, 0); ofs++;
314 for (i = 0; i < rowcol_len; ++i) {
315 put32(ptr, ofs, rowcol[i].begin); ofs++;
316 put32(ptr, ofs, rowcol[i].end); ofs++;
318 put32(ptr, ofs, dst_unit_bits); ofs++;
319 put32(ptr, ofs, len); ofs++;
321 _region_init(r, ptr, ofs * 4);
326 create_rowcol_ext_ilseq_info(struct _region *r)
332 ptr = malloc(_CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE);
334 err(EXIT_FAILURE, "malloc");
336 put32(ptr, ofs, oob_mode); ofs++;
337 put32(ptr, ofs, dst_ilseq); ofs++;
339 _region_init(r, ptr, _CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE);
342 #define CHKERR(ret, func, a) \
346 errx(EXIT_FAILURE, "%s: %s", #func, strerror(ret)); \
347 } while (/*CONSTCOND*/0)
354 struct _db_factory *df;
362 CHKERR(ret, _db_factory_create, (&df, _db_hash_std, NULL));
365 CHKERR(ret, _db_factory_addstr_by_s,
366 (df, _CITRUS_MAPPER_STD_SYM_TYPE,
367 _CITRUS_MAPPER_STD_TYPE_ROWCOL));
370 create_rowcol_info(&data);
371 CHKERR(ret, _db_factory_add_by_s,
372 (df, _CITRUS_MAPPER_STD_SYM_INFO, &data, 1));
374 /* ilseq extension */
375 create_rowcol_ext_ilseq_info(&data);
376 CHKERR(ret, _db_factory_add_by_s,
377 (df, _CITRUS_MAPPER_STD_SYM_ROWCOL_EXT_ILSEQ, &data, 1));
380 _region_init(&data, table, table_size*dst_unit_bits/8);
381 CHKERR(ret, _db_factory_add_by_s,
382 (df, _CITRUS_MAPPER_STD_SYM_TABLE, &data, 1));
385 * dump database to file
388 fp = fopen(output, "wb");
397 /* dump database body */
398 size = _db_factory_calc_size(df);
399 serialized = malloc(size);
400 _region_init(&data, serialized, size);
401 CHKERR(ret, _db_factory_serialize,
402 (df, _CITRUS_MAPPER_STD_MAGIC, &data));
403 if (fwrite(serialized, size, 1, fp) != 1)
404 err(EXIT_FAILURE, "fwrite");
414 if (done_flag & DF_TYPE) {
415 warning("TYPE is duplicated. ignored this one");
421 done_flag |= DF_TYPE;
428 if (done_flag & DF_NAME) {
429 warning("NAME is duplicated. ignored this one");
435 done_flag |= DF_NAME;
438 set_src_zone(u_int32_t val)
443 if (done_flag & DF_SRC_ZONE) {
444 warning("SRC_ZONE is duplicated. ignored this one");
450 switch (rowcol_bits) {
451 case 8: case 16: case 32:
452 if (rowcol_len <= 32 / rowcol_bits)
458 rowcol_mask = 1 << (rowcol_bits - 1);
459 rowcol_mask |= rowcol_mask - 1;
460 for (i = 0; i < rowcol_len; ++i) {
462 _DIAGASSERT(p->begin <= p->end);
463 if (p->end > rowcol_mask)
466 done_flag |= DF_SRC_ZONE;
470 yyerror("Illegal argument for SRC_ZONE");
473 set_dst_invalid(u_int32_t val)
476 if (done_flag & DF_DST_INVALID) {
477 warning("DST_INVALID is duplicated. ignored this one");
483 done_flag |= DF_DST_INVALID;
486 set_dst_ilseq(u_int32_t val)
489 if (done_flag & DF_DST_ILSEQ) {
490 warning("DST_ILSEQ is duplicated. ignored this one");
496 done_flag |= DF_DST_ILSEQ;
499 set_oob_mode(u_int32_t val)
502 if (done_flag & DF_OOB_MODE) {
503 warning("OOB_MODE is duplicated. ignored this one");
509 done_flag |= DF_OOB_MODE;
512 set_dst_unit_bits(u_int32_t val)
515 if (done_flag & DF_DST_UNIT_BITS) {
516 warning("DST_UNIT_BITS is duplicated. ignored this one");
534 yyerror("Illegal argument for DST_UNIT_BITS");
536 done_flag |= DF_DST_UNIT_BITS;
539 check_src(u_int32_t begin, u_int32_t end)
548 m = begin & ~rowcol_mask;
549 n = end & ~rowcol_mask;
553 for (i = rowcol_len * rowcol_bits, p = &rowcol[0]; i > 0; ++p) {
555 m = (begin >> i) & rowcol_mask;
556 if (m < p->begin || m > p->end)
560 n = end & rowcol_mask;
561 _DIAGASSERT(p > rowcol);
563 if (n < p->begin || n > p->end)
569 store(const linear_zone_t *lz, u_int32_t dst, int inc)
576 for (i = rowcol_len * rowcol_bits, p = &rowcol[0]; i > 0; ++p) {
578 n = ((lz->begin >> i) & rowcol_mask) - p->begin;
579 ofs = (ofs * p->width) + n;
583 (*putfunc)(table, ofs++, dst);
589 set_range(u_int32_t begin, u_int32_t end)
593 if (rowcol_len >= _CITRUS_MAPPER_STD_ROWCOL_MAX)
595 p = &rowcol[rowcol_len++];
599 p->begin = begin, p->end = end;
600 p->width = end - begin + 1;
605 yyerror("Illegal argument for SRC_ZONE");
608 set_src(linear_zone_t *lz, u_int32_t begin, u_int32_t end)
610 _DIAGASSERT(lz != NULL);
612 if (check_src(begin, end) != 0)
613 yyerror("illegal zone");
615 lz->begin = begin, lz->end = end;
616 lz->width = end - begin + 1;
627 /* dump DB to file */
629 out = fopen(output, "wb");
634 err(EXIT_FAILURE, "fopen");
636 ret = _lookup_factory_convert(out, in);
639 unlink(output); /* dump failure */
648 /* dump pivot to file */
650 out = fopen(output, "wb");
655 err(EXIT_FAILURE, "fopen");
657 ret = _pivot_factory_convert(out, in);
660 unlink(output); /* dump failure */
662 errx(EXIT_FAILURE, "%s\n", strerror(ret));
669 "\t%s [-d] [-o outfile] [infile]\n"
670 "\t%s -m [-d] [-o outfile] [infile]\n"
671 "\t%s -p [-d] [-o outfile] [infile]\n",
672 getprogname(), getprogname(), getprogname());
677 main(int argc, char **argv)
681 int mkdb = 0, mkpv = 0;
683 while ((ch = getopt(argc, argv, "do:mp")) != -1) {
689 output = strdup(optarg);
709 in = fopen(argv[0], "r");
711 err(EXIT_FAILURE, argv[0]);