1 /* $NetBSD: yacc.y,v 1.7 2006/09/09 14:35:17 tnozaki Exp $ */
2 /* $DragonFly: src/usr.bin/mkcsmapper/yacc.y,v 1.2 2008/04/10 10:21:13 hasso 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/types.h>
41 #include <netinet/in.h>
45 #include "citrus_namespace.h"
46 #include "citrus_types.h"
47 #include "citrus_mapper_std_file.h"
48 #include "citrus_region.h"
49 #include "citrus_db_factory.h"
50 #include "citrus_db_hash.h"
51 #include "citrus_lookup_factory.h"
52 #include "citrus_pivot_factory.h"
57 static char *output
= NULL
;
58 static void *table
= NULL
;
59 static size_t table_size
;
60 static char *map_name
;
62 static u_int32_t dst_invalid
, dst_ilseq
, oob_mode
, dst_unit_bits
;
63 static void (*putfunc
)(void *, size_t, u_int32_t
) = 0;
65 static u_int32_t src_next
;
67 static u_int32_t done_flag
= 0;
68 #define DF_TYPE 0x00000001
69 #define DF_NAME 0x00000002
70 #define DF_SRC_ZONE 0x00000004
71 #define DF_DST_INVALID 0x00000008
72 #define DF_DST_ILSEQ 0x00000010
73 #define DF_DST_UNIT_BITS 0x00000020
74 #define DF_OOB_MODE 0x00000040
76 static linear_zone_t rowcol
[_CITRUS_MAPPER_STD_ROWCOL_MAX
];
77 static size_t rowcol_len
= 0;
78 static u_int32_t rowcol_bits
= 0, rowcol_mask
= 0;
80 static void dump_file
(void);
81 static void setup_map
(void);
82 static void set_type
(int);
83 static void set_name
(char *);
84 static void set_src_zone
(u_int32_t
);
85 static void set_dst_invalid
(u_int32_t
);
86 static void set_dst_ilseq
(u_int32_t
);
87 static void set_dst_unit_bits
(u_int32_t
);
88 static void set_oob_mode
(u_int32_t
);
89 static int check_src
(u_int32_t
, u_int32_t
);
90 static void store
(const linear_zone_t
*, u_int32_t
, int);
91 static void put8
(void *, size_t, u_int32_t
);
92 static void put16
(void *, size_t, u_int32_t
);
93 static void put32
(void *, size_t, u_int32_t
);
94 static void set_range
(u_int32_t
, u_int32_t
);
95 static void set_src
(linear_zone_t
*, u_int32_t
, u_int32_t
);
101 linear_zone_t lz_value
;
104 %token R_TYPE R_NAME R_SRC_ZONE R_DST_UNIT_BITS
105 %token R_DST_INVALID R_DST_ILSEQ
106 %token R_BEGIN_MAP R_END_MAP R_INVALID R_ROWCOL
107 %token R_ILSEQ R_OOB_MODE
109 %token
<i_value
> L_IMM
110 %token
<s_value
> L_STRING
113 %type
<i_value
> dst types oob_mode_sel zone
117 file
: property mapping lns
120 property
: /* empty */
125 | property dst_invalid
127 | property dst_unit_bits
130 name
: R_NAME L_STRING
{ set_name
($2); $2 = NULL
; }
131 type
: R_TYPE types
{ set_type
($2); }
132 types
: R_ROWCOL
{ $$
= R_ROWCOL
; }
133 range
: L_IMM
'-' L_IMM
{ set_range
($1, $3); }
138 src_zone
: R_SRC_ZONE zone
{ set_src_zone
($2); }
142 | range
'/' range
'/' ranges L_IMM
{
146 dst_invalid
: R_DST_INVALID L_IMM
{ set_dst_invalid
($2); }
147 dst_ilseq
: R_DST_ILSEQ L_IMM
{ set_dst_ilseq
($2); }
148 dst_unit_bits
: R_DST_UNIT_BITS L_IMM
{ set_dst_unit_bits
($2); }
149 oob_mode
: R_OOB_MODE oob_mode_sel
{ set_oob_mode
($2); }
151 oob_mode_sel
: R_INVALID
{ $$
= _CITRUS_MAPPER_STD_OOB_NONIDENTICAL
; }
152 | R_ILSEQ
{ $$
= _CITRUS_MAPPER_STD_OOB_ILSEQ
; }
154 mapping
: begin_map map_elems R_END_MAP
155 begin_map
: R_BEGIN_MAP lns
{ setup_map
(); }
157 map_elems
: /* empty */
158 | map_elems map_elem lns
160 map_elem
: src
'=' dst
161 { store
(&$1, $3, 0); }
163 { store
(&$1, $3, 1); }
179 set_src
(&$$
, src_next
, src_next
);
183 set_src
(&$$
, $1, $1);
187 set_src
(&$$
, $1, $3);
191 set_src
(&$$
, src_next
, $2);
199 warning
(const char *s
)
201 fprintf
(stderr
, "%s in %d\n", s
, line_number
);
205 yyerror(const char *s
)
212 put8
(void *ptr
, size_t ofs
, u_int32_t val
)
214 *((u_int8_t
*)ptr
+ ofs
) = val
;
218 put16
(void *ptr
, size_t ofs
, u_int32_t val
)
220 u_int16_t oval
= htons
(val
);
221 memcpy
((u_int16_t
*)ptr
+ ofs
, &oval
, 2);
225 put32
(void *ptr
, size_t ofs
, u_int32_t val
)
227 u_int32_t oval
= htonl
(val
);
228 memcpy
((u_int32_t
*)ptr
+ ofs
, &oval
, 4);
240 table_size
= p
->width
;
243 table_size
*= p
->width
;
245 table
= (void *)malloc
(table_size
* dst_unit_bits
/ 8);
252 case _CITRUS_MAPPER_STD_OOB_NONIDENTICAL
:
255 case _CITRUS_MAPPER_STD_OOB_ILSEQ
:
261 for
(i
= 0; i
< table_size
; i
++)
262 (*putfunc
)(table
, i
, val
);
269 if
((done_flag
& DF_SRC_ZONE
)==0) {
270 fprintf
(stderr
, "SRC_ZONE is mandatory.\n");
273 if
((done_flag
& DF_DST_UNIT_BITS
)==0) {
274 fprintf
(stderr
, "DST_UNIT_BITS is mandatory.\n");
278 if
((done_flag
& DF_DST_INVALID
) == 0)
279 dst_invalid
= 0xFFFFFFFF;
280 if
((done_flag
& DF_DST_ILSEQ
) == 0)
281 dst_ilseq
= 0xFFFFFFFE;
282 if
((done_flag
& DF_OOB_MODE
) == 0)
283 oob_mode
= _CITRUS_MAPPER_STD_OOB_NONIDENTICAL
;
289 create_rowcol_info
(struct _region
*r
)
295 ptr
= malloc
(_CITRUS_MAPPER_STD_ROWCOL_INFO_SIZE
);
297 err
(EXIT_FAILURE
, "malloc");
298 put32
(ptr
, ofs
, rowcol_bits
); ofs
++;
299 put32
(ptr
, ofs
, dst_invalid
); ofs
++;
301 /* XXX: keep backward compatibility */
302 switch
(rowcol_len
) {
304 put32
(ptr
, ofs
, 0); ofs
++;
305 put32
(ptr
, ofs
, 0); ofs
++;
313 for
(i
= 0; i
< rowcol_len
; ++i
) {
314 put32
(ptr
, ofs
, rowcol
[i
].begin
); ofs
++;
315 put32
(ptr
, ofs
, rowcol
[i
].end
); ofs
++;
317 put32
(ptr
, ofs
, dst_unit_bits
); ofs
++;
318 put32
(ptr
, ofs
, len
); ofs
++;
320 _region_init
(r
, ptr
, ofs
* 4);
325 create_rowcol_ext_ilseq_info
(struct _region
*r
)
331 ptr
= malloc
(_CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE
);
333 err
(EXIT_FAILURE
, "malloc");
335 put32
(ptr
, ofs
, oob_mode
); ofs
++;
336 put32
(ptr
, ofs
, dst_ilseq
); ofs
++;
338 _region_init
(r
, ptr
, _CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE
);
341 #define CHKERR(ret, func, a) \
345 errx
(EXIT_FAILURE
, "%s: %s", #func, strerror(ret)); \
346 } while
(/*CONSTCOND*/0)
353 struct _db_factory
*df
;
361 CHKERR
(ret
, _db_factory_create
, (&df
, _db_hash_std
, NULL
));
364 CHKERR
(ret
, _db_factory_addstr_by_s
,
365 (df
, _CITRUS_MAPPER_STD_SYM_TYPE
,
366 _CITRUS_MAPPER_STD_TYPE_ROWCOL
));
369 create_rowcol_info
(&data
);
370 CHKERR
(ret
, _db_factory_add_by_s
,
371 (df
, _CITRUS_MAPPER_STD_SYM_INFO
, &data
, 1));
373 /* ilseq extension */
374 create_rowcol_ext_ilseq_info
(&data
);
375 CHKERR
(ret
, _db_factory_add_by_s
,
376 (df
, _CITRUS_MAPPER_STD_SYM_ROWCOL_EXT_ILSEQ
, &data
, 1));
379 _region_init
(&data
, table
, table_size
*dst_unit_bits
/8);
380 CHKERR
(ret
, _db_factory_add_by_s
,
381 (df
, _CITRUS_MAPPER_STD_SYM_TABLE
, &data
, 1));
384 * dump database to file
387 fp
= fopen
(output
, "wb");
396 /* dump database body */
397 size
= _db_factory_calc_size
(df
);
398 serialized
= malloc
(size
);
399 _region_init
(&data
, serialized
, size
);
400 CHKERR
(ret
, _db_factory_serialize
,
401 (df
, _CITRUS_MAPPER_STD_MAGIC
, &data
));
402 if
(fwrite
(serialized
, size
, 1, fp
) != 1)
403 err
(EXIT_FAILURE
, "fwrite");
413 if
(done_flag
& DF_TYPE
) {
414 warning
("TYPE is duplicated. ignored this one");
420 done_flag |
= DF_TYPE
;
427 if
(done_flag
& DF_NAME
) {
428 warning
("NAME is duplicated. ignored this one");
434 done_flag |
= DF_NAME
;
437 set_src_zone
(u_int32_t val
)
442 if
(done_flag
& DF_SRC_ZONE
) {
443 warning
("SRC_ZONE is duplicated. ignored this one");
449 switch
(rowcol_bits
) {
450 case
8: case
16: case
32:
451 if
(rowcol_len
<= 32 / rowcol_bits
)
457 rowcol_mask
= 1 << (rowcol_bits
- 1);
458 rowcol_mask |
= rowcol_mask
- 1;
459 for
(i
= 0; i
< rowcol_len
; ++i
) {
461 _DIAGASSERT
(p
->begin
<= p
->end
);
462 if
(p
->end
> rowcol_mask
)
465 done_flag |
= DF_SRC_ZONE
;
469 yyerror("Illegal argument for SRC_ZONE");
472 set_dst_invalid
(u_int32_t val
)
475 if
(done_flag
& DF_DST_INVALID
) {
476 warning
("DST_INVALID is duplicated. ignored this one");
482 done_flag |
= DF_DST_INVALID
;
485 set_dst_ilseq
(u_int32_t val
)
488 if
(done_flag
& DF_DST_ILSEQ
) {
489 warning
("DST_ILSEQ is duplicated. ignored this one");
495 done_flag |
= DF_DST_ILSEQ
;
498 set_oob_mode
(u_int32_t val
)
501 if
(done_flag
& DF_OOB_MODE
) {
502 warning
("OOB_MODE is duplicated. ignored this one");
508 done_flag |
= DF_OOB_MODE
;
511 set_dst_unit_bits
(u_int32_t val
)
514 if
(done_flag
& DF_DST_UNIT_BITS
) {
515 warning
("DST_UNIT_BITS is duplicated. ignored this one");
533 yyerror("Illegal argument for DST_UNIT_BITS");
535 done_flag |
= DF_DST_UNIT_BITS
;
538 check_src
(u_int32_t begin
, u_int32_t end
)
547 m
= begin
& ~rowcol_mask
;
548 n
= end
& ~rowcol_mask
;
552 for
(i
= rowcol_len
* rowcol_bits
, p
= &rowcol
[0]; i
> 0; ++p
) {
554 m
= (begin
>> i
) & rowcol_mask
;
555 if
(m
< p
->begin || m
> p
->end
)
559 n
= end
& rowcol_mask
;
560 _DIAGASSERT
(p
> rowcol
);
562 if
(n
< p
->begin || n
> p
->end
)
568 store
(const linear_zone_t
*lz
, u_int32_t dst
, int inc
)
575 for
(i
= rowcol_len
* rowcol_bits
, p
= &rowcol
[0]; i
> 0; ++p
) {
577 n
= ((lz
->begin
>> i
) & rowcol_mask
) - p
->begin
;
578 ofs
= (ofs
* p
->width
) + n
;
582 (*putfunc
)(table
, ofs
++, dst
);
588 set_range
(u_int32_t begin
, u_int32_t end
)
592 if
(rowcol_len
>= _CITRUS_MAPPER_STD_ROWCOL_MAX
)
594 p
= &rowcol
[rowcol_len
++];
598 p
->begin
= begin
, p
->end
= end
;
599 p
->width
= end
- begin
+ 1;
604 yyerror("Illegal argument for SRC_ZONE");
607 set_src
(linear_zone_t
*lz
, u_int32_t begin
, u_int32_t end
)
609 _DIAGASSERT
(lz
!= NULL
);
611 if
(check_src
(begin
, end
) != 0)
612 yyerror("illegal zone");
614 lz
->begin
= begin
, lz
->end
= end
;
615 lz
->width
= end
- begin
+ 1;
626 /* dump DB to file */
628 out
= fopen
(output
, "wb");
633 err
(EXIT_FAILURE
, "fopen");
635 ret
= _lookup_factory_convert
(out
, in
);
638 unlink
(output
); /* dump failure */
647 /* dump pivot to file */
649 out
= fopen
(output
, "wb");
654 err
(EXIT_FAILURE
, "fopen");
656 ret
= _pivot_factory_convert
(out
, in
);
659 unlink
(output
); /* dump failure */
661 errx
(EXIT_FAILURE
, "%s\n", strerror
(ret
));
668 "\t%s [-d] [-o outfile] [infile]\n"
669 "\t%s -m [-d] [-o outfile] [infile]\n"
670 "\t%s -p [-d] [-o outfile] [infile]\n",
671 getprogname
(), getprogname
(), getprogname
());
676 main
(int argc
, char **argv
)
680 int mkdb
= 0, mkpv
= 0;
682 while
((ch
= getopt
(argc
, argv
, "do:mp")) != EOF
) {
688 output
= strdup
(optarg
);
708 in
= fopen
(argv
[0], "r");
710 err
(EXIT_FAILURE
, argv
[0]);