1 /* $FreeBSD: head/usr.bin/mkcsmapper/yacc.y 250984 2013-05-25 15:36:15Z ed $ */
2 /* $NetBSD: yacc.y,v 1.7 2006/09/09 14:35:17 tnozaki Exp $ */
6 * Copyright (c)2003, 2006 Citrus Project,
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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 THE 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
31 #include <sys/cdefs.h>
32 #include <sys/types.h>
42 #include <arpa/inet.h>
50 #include "citrus_namespace.h"
51 #include "citrus_types.h"
52 #include "citrus_mapper_std_file.h"
53 #include "citrus_region.h"
54 #include "citrus_db_factory.h"
55 #include "citrus_db_hash.h"
56 #include "citrus_lookup_factory.h"
57 #include "citrus_pivot_factory.h"
63 static linear_zone_t rowcol
[_CITRUS_MAPPER_STD_ROWCOL_MAX
];
64 static char *map_name
;
65 static char *output
= NULL
;
66 static void *table
= NULL
;
67 static size_t rowcol_len
= 0;
68 static size_t table_size
;
69 static u_int32_t done_flag
= 0;
70 static u_int32_t dst_ilseq
, dst_invalid
, dst_unit_bits
, oob_mode
;
71 static u_int32_t rowcol_bits
= 0, rowcol_mask
= 0;
72 static u_int32_t src_next
;
74 static void (*putfunc
)(void *, size_t, u_int32_t
) = NULL
;
76 #define DF_TYPE 0x00000001
77 #define DF_NAME 0x00000002
78 #define DF_SRC_ZONE 0x00000004
79 #define DF_DST_INVALID 0x00000008
80 #define DF_DST_ILSEQ 0x00000010
81 #define DF_DST_UNIT_BITS 0x00000020
82 #define DF_OOB_MODE 0x00000040
84 static void dump_file
(void);
85 static void setup_map
(void);
86 static void set_type
(int);
87 static void set_name
(char *);
88 static void set_src_zone
(u_int32_t
);
89 static void set_dst_invalid
(u_int32_t
);
90 static void set_dst_ilseq
(u_int32_t
);
91 static void set_dst_unit_bits
(u_int32_t
);
92 static void set_oob_mode
(u_int32_t
);
93 static int check_src
(u_int32_t
, u_int32_t
);
94 static void store
(const linear_zone_t
*, u_int32_t
, int);
95 static void put8
(void *, size_t, u_int32_t
);
96 static void put16
(void *, size_t, u_int32_t
);
97 static void put32
(void *, size_t, u_int32_t
);
98 static void set_range
(u_int32_t
, u_int32_t
);
99 static void set_src
(linear_zone_t
*, u_int32_t
, u_int32_t
);
105 linear_zone_t lz_value
;
108 %token R_TYPE R_NAME R_SRC_ZONE R_DST_UNIT_BITS
109 %token R_DST_INVALID R_DST_ILSEQ
110 %token R_BEGIN_MAP R_END_MAP R_INVALID R_ROWCOL
111 %token R_ILSEQ R_OOB_MODE
113 %token
<i_value
> L_IMM
114 %token
<s_value
> L_STRING
117 %type
<i_value
> dst types oob_mode_sel zone
121 file
: property mapping lns
124 property
: /* empty */
129 | property dst_invalid
131 | property dst_unit_bits
134 name
: R_NAME L_STRING
{ set_name
($2); $2 = NULL
; }
135 type
: R_TYPE types
{ set_type
($2); }
136 types
: R_ROWCOL
{ $$
= R_ROWCOL
; }
137 range
: L_IMM
'-' L_IMM
{ set_range
($1, $3); }
142 src_zone
: R_SRC_ZONE zone
{ set_src_zone
($2); }
146 | range
'/' range
'/' ranges L_IMM
{
150 dst_invalid
: R_DST_INVALID L_IMM
{ set_dst_invalid
($2); }
151 dst_ilseq
: R_DST_ILSEQ L_IMM
{ set_dst_ilseq
($2); }
152 dst_unit_bits
: R_DST_UNIT_BITS L_IMM
{ set_dst_unit_bits
($2); }
153 oob_mode
: R_OOB_MODE oob_mode_sel
{ set_oob_mode
($2); }
155 oob_mode_sel
: R_INVALID
{ $$
= _CITRUS_MAPPER_STD_OOB_NONIDENTICAL
; }
156 | R_ILSEQ
{ $$
= _CITRUS_MAPPER_STD_OOB_ILSEQ
; }
158 mapping
: begin_map map_elems R_END_MAP
159 begin_map
: R_BEGIN_MAP lns
{ setup_map
(); }
161 map_elems
: /* empty */
162 | map_elems map_elem lns
164 map_elem
: src
'=' dst
165 { store
(&$1, $3, 0); }
167 { store
(&$1, $3, 1); }
183 set_src
(&$$
, src_next
, src_next
);
187 set_src
(&$$
, $1, $1);
191 set_src
(&$$
, $1, $3);
195 set_src
(&$$
, src_next
, $2);
203 warning
(const char *s
)
206 fprintf
(stderr
, "%s in %d\n", s
, linenumber
);
210 yyerror(const char *s
)
218 put8
(void *ptr
, size_t ofs
, u_int32_t val
)
221 *((u_int8_t
*)ptr
+ ofs
) = val
;
225 put16
(void *ptr
, size_t ofs
, u_int32_t val
)
228 u_int16_t oval
= htons
(val
);
229 memcpy
((u_int16_t
*)ptr
+ ofs
, &oval
, 2);
233 put32
(void *ptr
, size_t ofs
, u_int32_t val
)
236 u_int32_t oval
= htonl
(val
);
237 memcpy
((u_int32_t
*)ptr
+ ofs
, &oval
, 4);
249 table_size
= p
->width
;
252 table_size
*= p
->width
;
254 table
= (void *)malloc
(table_size
* dst_unit_bits
/ 8);
261 case _CITRUS_MAPPER_STD_OOB_NONIDENTICAL
:
264 case _CITRUS_MAPPER_STD_OOB_ILSEQ
:
270 for
(i
= 0; i
< table_size
; i
++)
271 (*putfunc
)(table
, i
, val
);
278 if
((done_flag
& DF_SRC_ZONE
)==0) {
279 fprintf
(stderr
, "SRC_ZONE is mandatory.\n");
282 if
((done_flag
& DF_DST_UNIT_BITS
)==0) {
283 fprintf
(stderr
, "DST_UNIT_BITS is mandatory.\n");
287 if
((done_flag
& DF_DST_INVALID
) == 0)
288 dst_invalid
= 0xFFFFFFFF;
289 if
((done_flag
& DF_DST_ILSEQ
) == 0)
290 dst_ilseq
= 0xFFFFFFFE;
291 if
((done_flag
& DF_OOB_MODE
) == 0)
292 oob_mode
= _CITRUS_MAPPER_STD_OOB_NONIDENTICAL
;
298 create_rowcol_info
(struct _region
*r
)
304 ptr
= malloc
(_CITRUS_MAPPER_STD_ROWCOL_INFO_SIZE
);
306 err
(EXIT_FAILURE
, "malloc");
307 put32
(ptr
, ofs
, rowcol_bits
); ofs
++;
308 put32
(ptr
, ofs
, dst_invalid
); ofs
++;
310 /* XXX: keep backward compatibility */
311 switch
(rowcol_len
) {
313 put32
(ptr
, ofs
, 0); ofs
++;
314 put32
(ptr
, ofs
, 0); ofs
++;
322 for
(i
= 0; i
< rowcol_len
; ++i
) {
323 put32
(ptr
, ofs
, rowcol
[i
].begin
); ofs
++;
324 put32
(ptr
, ofs
, rowcol
[i
].end
); ofs
++;
326 put32
(ptr
, ofs
, dst_unit_bits
); ofs
++;
327 put32
(ptr
, ofs
, len
); ofs
++;
329 _region_init
(r
, ptr
, ofs
* 4);
334 create_rowcol_ext_ilseq_info
(struct _region
*r
)
340 ptr
= malloc
(_CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE
);
342 err
(EXIT_FAILURE
, "malloc");
344 put32
(ptr
, ofs
, oob_mode
); ofs
++;
345 put32
(ptr
, ofs
, dst_ilseq
); ofs
++;
347 _region_init
(r
, ptr
, _CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE
);
350 #define CHKERR(ret, func, a) \
354 errx
(EXIT_FAILURE
, "%s: %s", #func, strerror(ret)); \
355 } while
(/*CONSTCOND*/0)
360 struct _db_factory
*df
;
370 CHKERR
(ret
, _db_factory_create
, (&df
, _db_hash_std
, NULL
));
373 CHKERR
(ret
, _db_factory_addstr_by_s
,
374 (df
, _CITRUS_MAPPER_STD_SYM_TYPE
, _CITRUS_MAPPER_STD_TYPE_ROWCOL
));
377 create_rowcol_info
(&data
);
378 CHKERR
(ret
, _db_factory_add_by_s
,
379 (df
, _CITRUS_MAPPER_STD_SYM_INFO
, &data
, 1));
381 /* ilseq extension */
382 create_rowcol_ext_ilseq_info
(&data
);
383 CHKERR
(ret
, _db_factory_add_by_s
,
384 (df
, _CITRUS_MAPPER_STD_SYM_ROWCOL_EXT_ILSEQ
, &data
, 1));
387 _region_init
(&data
, table
, table_size
*dst_unit_bits
/8);
388 CHKERR
(ret
, _db_factory_add_by_s
,
389 (df
, _CITRUS_MAPPER_STD_SYM_TABLE
, &data
, 1));
392 * dump database to file
394 fp
= output ? fopen
(output
, "wb") : stdout
;
401 /* dump database body */
402 size
= _db_factory_calc_size
(df
);
403 serialized
= malloc
(size
);
404 _region_init
(&data
, serialized
, size
);
405 CHKERR
(ret
, _db_factory_serialize
,
406 (df
, _CITRUS_MAPPER_STD_MAGIC
, &data
));
407 if
(fwrite
(serialized
, size
, 1, fp
) != 1)
408 err
(EXIT_FAILURE
, "fwrite");
418 if
(done_flag
& DF_TYPE
) {
419 warning
("TYPE is duplicated. ignored this one");
425 done_flag |
= DF_TYPE
;
433 if
(done_flag
& DF_NAME
) {
434 warning
("NAME is duplicated. ignored this one");
440 done_flag |
= DF_NAME
;
444 set_src_zone
(u_int32_t val
)
449 if
(done_flag
& DF_SRC_ZONE
) {
450 warning
("SRC_ZONE is duplicated. ignored this one");
456 switch
(rowcol_bits
) {
457 case
8: case
16: case
32:
458 if
(rowcol_len
<= 32 / rowcol_bits
)
464 rowcol_mask
= 1 << (rowcol_bits
- 1);
465 rowcol_mask |
= rowcol_mask
- 1;
466 for
(i
= 0; i
< rowcol_len
; ++i
) {
468 if
(p
->end
> rowcol_mask
)
471 done_flag |
= DF_SRC_ZONE
;
475 yyerror("Illegal argument for SRC_ZONE");
479 set_dst_invalid
(u_int32_t val
)
482 if
(done_flag
& DF_DST_INVALID
) {
483 warning
("DST_INVALID is duplicated. ignored this one");
489 done_flag |
= DF_DST_INVALID
;
493 set_dst_ilseq
(u_int32_t val
)
496 if
(done_flag
& DF_DST_ILSEQ
) {
497 warning
("DST_ILSEQ is duplicated. ignored this one");
503 done_flag |
= DF_DST_ILSEQ
;
507 set_oob_mode
(u_int32_t val
)
510 if
(done_flag
& DF_OOB_MODE
) {
511 warning
("OOB_MODE is duplicated. ignored this one");
517 done_flag |
= DF_OOB_MODE
;
521 set_dst_unit_bits
(u_int32_t val
)
524 if
(done_flag
& DF_DST_UNIT_BITS
) {
525 warning
("DST_UNIT_BITS is duplicated. ignored this one");
543 yyerror("Illegal argument for DST_UNIT_BITS");
545 done_flag |
= DF_DST_UNIT_BITS
;
549 check_src
(u_int32_t begin
, u_int32_t end
)
558 m
= begin
& ~rowcol_mask
;
559 n
= end
& ~rowcol_mask
;
563 for
(i
= rowcol_len
* rowcol_bits
, p
= &rowcol
[0]; i
> 0; ++p
) {
565 m
= (begin
>> i
) & rowcol_mask
;
566 if
(m
< p
->begin || m
> p
->end
)
570 n
= end
& rowcol_mask
;
572 if
(n
< p
->begin || n
> p
->end
)
579 store
(const linear_zone_t
*lz
, u_int32_t dst
, int inc
)
586 for
(i
= rowcol_len
* rowcol_bits
, p
= &rowcol
[0]; i
> 0; ++p
) {
588 n
= ((lz
->begin
>> i
) & rowcol_mask
) - p
->begin
;
589 ofs
= (ofs
* p
->width
) + n
;
593 (*putfunc
)(table
, ofs
++, dst
);
600 set_range
(u_int32_t begin
, u_int32_t end
)
604 if
(rowcol_len
>= _CITRUS_MAPPER_STD_ROWCOL_MAX
)
606 p
= &rowcol
[rowcol_len
++];
610 p
->begin
= begin
, p
->end
= end
;
611 p
->width
= end
- begin
+ 1;
616 yyerror("Illegal argument for SRC_ZONE");
620 set_src
(linear_zone_t
*lz
, u_int32_t begin
, u_int32_t end
)
623 if
(check_src
(begin
, end
) != 0)
624 yyerror("illegal zone");
626 lz
->begin
= begin
, lz
->end
= end
;
627 lz
->width
= end
- begin
+ 1;
638 /* dump DB to file */
639 out
= output ? fopen
(output
, "wb") : stdout
;
642 err
(EXIT_FAILURE
, "fopen");
644 ret
= _lookup_factory_convert
(out
, in
);
647 unlink
(output
); /* dump failure */
656 /* dump pivot to file */
657 out
= output ? fopen
(output
, "wb") : stdout
;
660 err
(EXIT_FAILURE
, "fopen");
662 ret
= _pivot_factory_convert
(out
, in
);
665 unlink
(output
); /* dump failure */
667 errx
(EXIT_FAILURE
, "%s\n", strerror
(ret
));
674 "\t%s [-d] [-o outfile] [infile]\n"
675 "\t%s -m [-d] [-o outfile] [infile]\n"
676 "\t%s -p [-d] [-o outfile] [infile]\n",
677 getprogname
(), getprogname
(), getprogname
());
682 main
(int argc
, char **argv
)
685 int ch
, mkdb
= 0, mkpv
= 0;
687 while
((ch
= getopt
(argc
, argv
, "do:mp")) != EOF
) {
693 output
= strdup
(optarg
);
713 in
= fopen
(argv
[0], "r");
715 err
(EXIT_FAILURE
, "%s", argv
[0]);