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
);
101 #if YYPATCH < 20180510
109 linear_zone_t lz_value
;
112 %token R_TYPE R_NAME R_SRC_ZONE R_DST_UNIT_BITS
113 %token R_DST_INVALID R_DST_ILSEQ
114 %token R_BEGIN_MAP R_END_MAP R_INVALID R_ROWCOL
115 %token R_ILSEQ R_OOB_MODE
117 %token
<i_value
> L_IMM
118 %token
<s_value
> L_STRING
121 %type
<i_value
> dst types oob_mode_sel zone
125 file
: property mapping lns
128 property
: /* empty */
133 | property dst_invalid
135 | property dst_unit_bits
138 name
: R_NAME L_STRING
{ set_name
($2); $2 = NULL
; }
139 type
: R_TYPE types
{ set_type
($2); }
140 types
: R_ROWCOL
{ $$
= R_ROWCOL
; }
141 range
: L_IMM
'-' L_IMM
{ set_range
($1, $3); }
146 src_zone
: R_SRC_ZONE zone
{ set_src_zone
($2); }
150 | range
'/' range
'/' ranges L_IMM
{
154 dst_invalid
: R_DST_INVALID L_IMM
{ set_dst_invalid
($2); }
155 dst_ilseq
: R_DST_ILSEQ L_IMM
{ set_dst_ilseq
($2); }
156 dst_unit_bits
: R_DST_UNIT_BITS L_IMM
{ set_dst_unit_bits
($2); }
157 oob_mode
: R_OOB_MODE oob_mode_sel
{ set_oob_mode
($2); }
159 oob_mode_sel
: R_INVALID
{ $$
= _CITRUS_MAPPER_STD_OOB_NONIDENTICAL
; }
160 | R_ILSEQ
{ $$
= _CITRUS_MAPPER_STD_OOB_ILSEQ
; }
162 mapping
: begin_map map_elems R_END_MAP
163 begin_map
: R_BEGIN_MAP lns
{ setup_map
(); }
165 map_elems
: /* empty */
166 | map_elems map_elem lns
168 map_elem
: src
'=' dst
169 { store
(&$1, $3, 0); }
171 { store
(&$1, $3, 1); }
187 set_src
(&$$
, src_next
, src_next
);
191 set_src
(&$$
, $1, $1);
195 set_src
(&$$
, $1, $3);
199 set_src
(&$$
, src_next
, $2);
207 warning
(const char *s
)
210 fprintf
(stderr
, "%s in %d\n", s
, linenumber
);
214 yyerror(const char *s
)
222 put8
(void *ptr
, size_t ofs
, u_int32_t val
)
225 *((u_int8_t
*)ptr
+ ofs
) = val
;
229 put16
(void *ptr
, size_t ofs
, u_int32_t val
)
232 u_int16_t oval
= htons
(val
);
233 memcpy
((u_int16_t
*)ptr
+ ofs
, &oval
, 2);
237 put32
(void *ptr
, size_t ofs
, u_int32_t val
)
240 u_int32_t oval
= htonl
(val
);
241 memcpy
((u_int32_t
*)ptr
+ ofs
, &oval
, 4);
253 table_size
= p
->width
;
256 table_size
*= p
->width
;
258 table
= (void *)malloc
(table_size
* dst_unit_bits
/ 8);
265 case _CITRUS_MAPPER_STD_OOB_NONIDENTICAL
:
268 case _CITRUS_MAPPER_STD_OOB_ILSEQ
:
274 for
(i
= 0; i
< table_size
; i
++)
275 (*putfunc
)(table
, i
, val
);
282 if
((done_flag
& DF_SRC_ZONE
)==0) {
283 fprintf
(stderr
, "SRC_ZONE is mandatory.\n");
286 if
((done_flag
& DF_DST_UNIT_BITS
)==0) {
287 fprintf
(stderr
, "DST_UNIT_BITS is mandatory.\n");
291 if
((done_flag
& DF_DST_INVALID
) == 0)
292 dst_invalid
= 0xFFFFFFFF;
293 if
((done_flag
& DF_DST_ILSEQ
) == 0)
294 dst_ilseq
= 0xFFFFFFFE;
295 if
((done_flag
& DF_OOB_MODE
) == 0)
296 oob_mode
= _CITRUS_MAPPER_STD_OOB_NONIDENTICAL
;
302 create_rowcol_info
(struct _region
*r
)
308 ptr
= malloc
(_CITRUS_MAPPER_STD_ROWCOL_INFO_SIZE
);
310 err
(EXIT_FAILURE
, "malloc");
311 put32
(ptr
, ofs
, rowcol_bits
); ofs
++;
312 put32
(ptr
, ofs
, dst_invalid
); ofs
++;
314 /* XXX: keep backward compatibility */
315 switch
(rowcol_len
) {
317 put32
(ptr
, ofs
, 0); ofs
++;
318 put32
(ptr
, ofs
, 0); ofs
++;
326 for
(i
= 0; i
< rowcol_len
; ++i
) {
327 put32
(ptr
, ofs
, rowcol
[i
].begin
); ofs
++;
328 put32
(ptr
, ofs
, rowcol
[i
].end
); ofs
++;
330 put32
(ptr
, ofs
, dst_unit_bits
); ofs
++;
331 put32
(ptr
, ofs
, len
); ofs
++;
333 _region_init
(r
, ptr
, ofs
* 4);
338 create_rowcol_ext_ilseq_info
(struct _region
*r
)
344 ptr
= malloc
(_CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE
);
346 err
(EXIT_FAILURE
, "malloc");
348 put32
(ptr
, ofs
, oob_mode
); ofs
++;
349 put32
(ptr
, ofs
, dst_ilseq
); ofs
++;
351 _region_init
(r
, ptr
, _CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE
);
354 #define CHKERR(ret, func, a) \
358 errx
(EXIT_FAILURE
, "%s: %s", #func, strerror(ret)); \
359 } while
(/*CONSTCOND*/0)
364 struct _db_factory
*df
;
374 CHKERR
(ret
, _db_factory_create
, (&df
, _db_hash_std
, NULL
));
377 CHKERR
(ret
, _db_factory_addstr_by_s
,
378 (df
, _CITRUS_MAPPER_STD_SYM_TYPE
, _CITRUS_MAPPER_STD_TYPE_ROWCOL
));
381 create_rowcol_info
(&data
);
382 CHKERR
(ret
, _db_factory_add_by_s
,
383 (df
, _CITRUS_MAPPER_STD_SYM_INFO
, &data
, 1));
385 /* ilseq extension */
386 create_rowcol_ext_ilseq_info
(&data
);
387 CHKERR
(ret
, _db_factory_add_by_s
,
388 (df
, _CITRUS_MAPPER_STD_SYM_ROWCOL_EXT_ILSEQ
, &data
, 1));
391 _region_init
(&data
, table
, table_size
*dst_unit_bits
/8);
392 CHKERR
(ret
, _db_factory_add_by_s
,
393 (df
, _CITRUS_MAPPER_STD_SYM_TABLE
, &data
, 1));
396 * dump database to file
398 fp
= output ? fopen
(output
, "wb") : stdout
;
405 /* dump database body */
406 size
= _db_factory_calc_size
(df
);
407 serialized
= malloc
(size
);
408 _region_init
(&data
, serialized
, size
);
409 CHKERR
(ret
, _db_factory_serialize
,
410 (df
, _CITRUS_MAPPER_STD_MAGIC
, &data
));
411 if
(fwrite
(serialized
, size
, 1, fp
) != 1)
412 err
(EXIT_FAILURE
, "fwrite");
422 if
(done_flag
& DF_TYPE
) {
423 warning
("TYPE is duplicated. ignored this one");
429 done_flag |
= DF_TYPE
;
437 if
(done_flag
& DF_NAME
) {
438 warning
("NAME is duplicated. ignored this one");
444 done_flag |
= DF_NAME
;
448 set_src_zone
(u_int32_t val
)
453 if
(done_flag
& DF_SRC_ZONE
) {
454 warning
("SRC_ZONE is duplicated. ignored this one");
460 switch
(rowcol_bits
) {
461 case
8: case
16: case
32:
462 if
(rowcol_len
<= 32 / rowcol_bits
)
468 rowcol_mask
= 1 << (rowcol_bits
- 1);
469 rowcol_mask |
= rowcol_mask
- 1;
470 for
(i
= 0; i
< rowcol_len
; ++i
) {
472 if
(p
->end
> rowcol_mask
)
475 done_flag |
= DF_SRC_ZONE
;
479 yyerror("Illegal argument for SRC_ZONE");
483 set_dst_invalid
(u_int32_t val
)
486 if
(done_flag
& DF_DST_INVALID
) {
487 warning
("DST_INVALID is duplicated. ignored this one");
493 done_flag |
= DF_DST_INVALID
;
497 set_dst_ilseq
(u_int32_t val
)
500 if
(done_flag
& DF_DST_ILSEQ
) {
501 warning
("DST_ILSEQ is duplicated. ignored this one");
507 done_flag |
= DF_DST_ILSEQ
;
511 set_oob_mode
(u_int32_t val
)
514 if
(done_flag
& DF_OOB_MODE
) {
515 warning
("OOB_MODE is duplicated. ignored this one");
521 done_flag |
= DF_OOB_MODE
;
525 set_dst_unit_bits
(u_int32_t val
)
528 if
(done_flag
& DF_DST_UNIT_BITS
) {
529 warning
("DST_UNIT_BITS is duplicated. ignored this one");
547 yyerror("Illegal argument for DST_UNIT_BITS");
549 done_flag |
= DF_DST_UNIT_BITS
;
553 check_src
(u_int32_t begin
, u_int32_t end
)
562 m
= begin
& ~rowcol_mask
;
563 n
= end
& ~rowcol_mask
;
567 for
(i
= rowcol_len
* rowcol_bits
, p
= &rowcol
[0]; i
> 0; ++p
) {
569 m
= (begin
>> i
) & rowcol_mask
;
570 if
(m
< p
->begin || m
> p
->end
)
574 n
= end
& rowcol_mask
;
576 if
(n
< p
->begin || n
> p
->end
)
583 store
(const linear_zone_t
*lz
, u_int32_t dst
, int inc
)
590 for
(i
= rowcol_len
* rowcol_bits
, p
= &rowcol
[0]; i
> 0; ++p
) {
592 n
= ((lz
->begin
>> i
) & rowcol_mask
) - p
->begin
;
593 ofs
= (ofs
* p
->width
) + n
;
597 (*putfunc
)(table
, ofs
++, dst
);
604 set_range
(u_int32_t begin
, u_int32_t end
)
608 if
(rowcol_len
>= _CITRUS_MAPPER_STD_ROWCOL_MAX
)
610 p
= &rowcol
[rowcol_len
++];
614 p
->begin
= begin
, p
->end
= end
;
615 p
->width
= end
- begin
+ 1;
620 yyerror("Illegal argument for SRC_ZONE");
624 set_src
(linear_zone_t
*lz
, u_int32_t begin
, u_int32_t end
)
627 if
(check_src
(begin
, end
) != 0)
628 yyerror("illegal zone");
630 lz
->begin
= begin
, lz
->end
= end
;
631 lz
->width
= end
- begin
+ 1;
642 /* dump DB to file */
643 out
= output ? fopen
(output
, "wb") : stdout
;
646 err
(EXIT_FAILURE
, "fopen");
648 ret
= _lookup_factory_convert
(out
, in
);
651 unlink
(output
); /* dump failure */
660 /* dump pivot to file */
661 out
= output ? fopen
(output
, "wb") : stdout
;
664 err
(EXIT_FAILURE
, "fopen");
666 ret
= _pivot_factory_convert
(out
, in
);
669 unlink
(output
); /* dump failure */
671 errx
(EXIT_FAILURE
, "%s\n", strerror
(ret
));
678 "\t%s [-d] [-o outfile] [infile]\n"
679 "\t%s -m [-d] [-o outfile] [infile]\n"
680 "\t%s -p [-d] [-o outfile] [infile]\n",
681 getprogname
(), getprogname
(), getprogname
());
686 main
(int argc
, char **argv
)
689 int ch
, mkdb
= 0, mkpv
= 0;
691 while
((ch
= getopt
(argc
, argv
, "do:mp")) != EOF
) {
697 output
= strdup
(optarg
);
717 in
= fopen
(argv
[0], "r");
719 err
(EXIT_FAILURE
, "%s", argv
[0]);