1 /* $NetBSD: src/usr.bin/mkcsmapper/yacc.y,v 1.5 2004/01/05 19:20:10 itojun Exp $ */
2 /* $DragonFly: src/usr.bin/mkcsmapper/yacc.y,v 1.1 2005/03/11 20:17:11 joerg Exp $ */
6 * Copyright (c)2003 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 zone_t src_zone
;
63 static u_int32_t colmask
, rowmask
;
64 static u_int32_t dst_invalid
, dst_ilseq
, oob_mode
, dst_unit_bits
;
65 static void (*putfunc
)(void *, size_t, u_int32_t
) = 0;
67 static u_int32_t src_next
;
68 static int next_valid
;
70 static u_int32_t done_flag
= 0;
71 #define DF_TYPE 0x00000001
72 #define DF_NAME 0x00000002
73 #define DF_SRC_ZONE 0x00000004
74 #define DF_DST_INVALID 0x00000008
75 #define DF_DST_ILSEQ 0x00000010
76 #define DF_DST_UNIT_BITS 0x00000020
77 #define DF_OOB_MODE 0x00000040
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
(const zone_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 void calc_next
(void);
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
);
100 linear_zone_t lz_value
;
103 %token R_TYPE R_NAME R_SRC_ZONE R_DST_UNIT_BITS
104 %token R_DST_INVALID R_DST_ILSEQ
105 %token R_BEGIN_MAP R_END_MAP R_INVALID R_ROWCOL
106 %token R_ILSEQ R_OOB_MODE
108 %token
<i_value
> L_IMM
109 %token
<s_value
> L_STRING
113 %type
<i_value
> dst types oob_mode_sel
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 src_zone
: R_SRC_ZONE zone
{ set_src_zone
(&$2); }
134 zone
: L_IMM
'-' L_IMM
{
135 $$.row_begin
= $$.row_end
= 0;
136 $$.col_begin
= $1; $$.col_end
= $3;
139 | L_IMM
'-' L_IMM
'/' L_IMM
'-' L_IMM
'/' L_IMM
{
140 $$.row_begin
= $1; $$.row_end
= $3;
141 $$.col_begin
= $5; $$.col_end
= $7;
145 dst_invalid
: R_DST_INVALID L_IMM
{ set_dst_invalid
($2); }
146 dst_ilseq
: R_DST_ILSEQ L_IMM
{ set_dst_ilseq
($2); }
147 dst_unit_bits
: R_DST_UNIT_BITS L_IMM
{ set_dst_unit_bits
($2); }
148 oob_mode
: R_OOB_MODE oob_mode_sel
{ set_oob_mode
($2); }
150 oob_mode_sel
: R_INVALID
{ $$
= _CITRUS_MAPPER_STD_OOB_NONIDENTICAL
; }
151 | R_ILSEQ
{ $$
= _CITRUS_MAPPER_STD_OOB_ILSEQ
; }
153 mapping
: begin_map map_elems R_END_MAP
154 begin_map
: R_BEGIN_MAP lns
{ setup_map
(); }
156 map_elems
: /* empty */
157 | map_elems map_elem lns
159 map_elem
: src
'=' dst
160 { store
(&$1, $3, 0); }
162 { store
(&$1, $3, 1); }
179 yyerror("cannot omit src");
181 $$.begin
= $$.end
= src_next
;
186 if
(check_src
($1, $1)) {
187 yyerror("illegal zone");
189 $$.begin
= $$.end
= $1;
195 if
(check_src
($1, $3)) {
196 yyerror("illegal zone");
198 $$.begin
= $1; $$.end
= $3;
205 yyerror("cannot omit src");
207 if
(check_src
(src_next
, $2)) {
208 yyerror("illegal zone");
210 $$.begin
= src_next
; $$.end
= $2;
220 warning
(const char *s
)
222 fprintf
(stderr
, "%s in %d\n", s
, line_number
);
226 yyerror(const char *s
)
233 put8
(void *ptr
, size_t ofs
, u_int32_t val
)
235 *((u_int8_t
*)ptr
+ ofs
) = val
;
239 put16
(void *ptr
, size_t ofs
, u_int32_t val
)
241 u_int16_t oval
= htons
(val
);
242 memcpy
((u_int16_t
*)ptr
+ ofs
, &oval
, 2);
246 put32
(void *ptr
, size_t ofs
, u_int32_t val
)
248 u_int32_t oval
= htonl
(val
);
249 memcpy
((u_int32_t
*)ptr
+ ofs
, &oval
, 4);
259 (src_zone.row_end
-src_zone.row_begin
+ 1) *
260 (src_zone.col_end
-src_zone.col_begin
+ 1);
261 table
= malloc
(table_size
*dst_unit_bits
/ 8);
268 case _CITRUS_MAPPER_STD_OOB_NONIDENTICAL
:
271 case _CITRUS_MAPPER_STD_OOB_ILSEQ
:
277 for
(i
= 0; i
< table_size
; i
++)
278 (*putfunc
)(table
, i
, val
);
285 if
((done_flag
& DF_SRC_ZONE
)==0) {
286 fprintf
(stderr
, "SRC_ZONE is mandatory.\n");
289 if
((done_flag
& DF_DST_UNIT_BITS
)==0) {
290 fprintf
(stderr
, "DST_UNIT_BITS is mandatory.\n");
294 if
((done_flag
& DF_DST_INVALID
) == 0)
295 dst_invalid
= 0xFFFFFFFF;
296 if
((done_flag
& DF_DST_ILSEQ
) == 0)
297 dst_ilseq
= 0xFFFFFFFE;
298 if
((done_flag
& DF_OOB_MODE
) == 0)
299 oob_mode
= _CITRUS_MAPPER_STD_OOB_NONIDENTICAL
;
305 create_rowcol_info
(struct _region
*r
)
311 ptr
= malloc
(_CITRUS_MAPPER_STD_ROWCOL_INFO_SIZE
);
313 err
(EXIT_FAILURE
, "malloc");
315 put32
(ptr
, ofs
, src_zone.col_bits
); ofs
++;
316 put32
(ptr
, ofs
, dst_invalid
); ofs
++;
317 put32
(ptr
, ofs
, src_zone.row_begin
); ofs
++;
318 put32
(ptr
, ofs
, src_zone.row_end
); ofs
++;
319 put32
(ptr
, ofs
, src_zone.col_begin
); ofs
++;
320 put32
(ptr
, ofs
, src_zone.col_end
); ofs
++;
321 put32
(ptr
, ofs
, dst_unit_bits
); ofs
++;
322 put32
(ptr
, ofs
, 0); /* pad */
324 _region_init
(r
, ptr
, _CITRUS_MAPPER_STD_ROWCOL_INFO_SIZE
);
328 create_rowcol_ext_ilseq_info
(struct _region
*r
)
334 ptr
= malloc
(_CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE
);
336 err
(EXIT_FAILURE
, "malloc");
338 put32
(ptr
, ofs
, oob_mode
); ofs
++;
339 put32
(ptr
, ofs
, dst_ilseq
); ofs
++;
341 _region_init
(r
, ptr
, _CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE
);
344 #define CHKERR(ret, func, a) \
348 errx
(EXIT_FAILURE
, "%s: %s", #func, strerror(ret)); \
349 } while
(/*CONSTCOND*/0)
356 struct _db_factory
*df
;
364 CHKERR
(ret
, _db_factory_create
, (&df
, _db_hash_std
, NULL
));
367 CHKERR
(ret
, _db_factory_addstr_by_s
,
368 (df
, _CITRUS_MAPPER_STD_SYM_TYPE
,
369 _CITRUS_MAPPER_STD_TYPE_ROWCOL
));
372 create_rowcol_info
(&data
);
373 CHKERR
(ret
, _db_factory_add_by_s
,
374 (df
, _CITRUS_MAPPER_STD_SYM_INFO
, &data
, 1));
376 /* ilseq extension */
377 create_rowcol_ext_ilseq_info
(&data
);
378 CHKERR
(ret
, _db_factory_add_by_s
,
379 (df
, _CITRUS_MAPPER_STD_SYM_ROWCOL_EXT_ILSEQ
, &data
, 1));
382 _region_init
(&data
, table
, table_size
*dst_unit_bits
/8);
383 CHKERR
(ret
, _db_factory_add_by_s
,
384 (df
, _CITRUS_MAPPER_STD_SYM_TABLE
, &data
, 1));
387 * dump database to file
390 fp
= fopen
(output
, "wb");
399 /* dump database body */
400 size
= _db_factory_calc_size
(df
);
401 serialized
= malloc
(size
);
402 _region_init
(&data
, serialized
, size
);
403 CHKERR
(ret
, _db_factory_serialize
,
404 (df
, _CITRUS_MAPPER_STD_MAGIC
, &data
));
405 if
(fwrite
(serialized
, size
, 1, fp
) != 1)
406 err
(EXIT_FAILURE
, "fwrite");
416 if
(done_flag
& DF_TYPE
) {
417 warning
("TYPE is duplicated. ignored this one");
423 done_flag |
= DF_TYPE
;
430 if
(done_flag
& DF_NAME
) {
431 warning
("NAME is duplicated. ignored this one");
437 done_flag |
= DF_NAME
;
440 set_src_zone
(const zone_t
*zone
)
443 if
(done_flag
& DF_SRC_ZONE
) {
444 warning
("SRC_ZONE is duplicated. ignored this one");
449 if
(zone
->col_bits
< 1 || zone
->col_bits
> 32) {
453 if
(zone
->col_bits
!= 32)
454 colmask
= (1 << zone
->col_bits
)- 1;
458 if
(zone
->col_begin
> zone
->col_end ||
459 zone
->row_begin
> zone
->row_end ||
460 (zone
->col_begin
& rowmask
) != 0 ||
461 (zone
->col_end
& rowmask
) != 0 ||
462 ((zone
->row_begin
<< zone
->col_bits
) & colmask
) != 0 ||
463 ((zone
->row_end
<< zone
->col_bits
) & colmask
) != 0) {
465 yyerror("Illegal argument for SRC_ZONE");
470 done_flag |
= DF_SRC_ZONE
;
475 set_dst_invalid
(u_int32_t val
)
478 if
(done_flag
& DF_DST_INVALID
) {
479 warning
("DST_INVALID is duplicated. ignored this one");
485 done_flag |
= DF_DST_INVALID
;
488 set_dst_ilseq
(u_int32_t val
)
491 if
(done_flag
& DF_DST_ILSEQ
) {
492 warning
("DST_ILSEQ is duplicated. ignored this one");
498 done_flag |
= DF_DST_ILSEQ
;
501 set_oob_mode
(u_int32_t val
)
504 if
(done_flag
& DF_OOB_MODE
) {
505 warning
("OOB_MODE is duplicated. ignored this one");
511 done_flag |
= DF_OOB_MODE
;
514 set_dst_unit_bits
(u_int32_t val
)
517 if
(done_flag
& DF_DST_UNIT_BITS
) {
518 warning
("DST_UNIT_BITS is duplicated. ignored this one");
536 yyerror("Illegal argument for DST_UNIT_BITS");
538 done_flag |
= DF_DST_UNIT_BITS
;
544 if
(check_src
(src_next
, src_next
))
550 check_src
(u_int32_t begin
, u_int32_t end
)
552 u_int32_t b_row
= 0, e_row
= 0, b_col
, e_col
;
554 b_col
= begin
& colmask
;
555 e_col
= end
& colmask
;
556 if
(src_zone.col_bits
!= 32) {
557 b_row
= begin
>> src_zone.col_bits
;
558 e_row
= end
>> src_zone.col_bits
;
561 if
(b_row
!= e_row ||
562 b_row
< src_zone.row_begin ||
563 b_row
> src_zone.row_end ||
564 e_row
< src_zone.row_begin ||
565 e_row
> src_zone.row_end ||
566 b_col
< src_zone.col_begin ||
567 b_col
> src_zone.col_end ||
568 e_col
< src_zone.col_begin ||
569 e_col
> src_zone.col_end ||
576 store
(const linear_zone_t
*lz
, u_int32_t dst
, int inc
)
578 u_int32_t row
=0, col
, ofs
, i
;
580 if
(src_zone.col_bits
!= 32)
581 row
= lz
->begin
>> src_zone.col_bits
;
582 col
= lz
->begin
& colmask
;
583 ofs
= (row
-src_zone.row_begin
) *
584 (src_zone.col_end
-src_zone.col_begin
+ 1) +
585 (col
-src_zone.col_begin
);
586 for
(i
= lz
->end
- lz
->begin
+ 1; i
> 0; i
--) {
587 (*putfunc
)(table
, ofs
++, dst
);
599 /* dump DB to file */
601 out
= fopen
(output
, "wb");
606 err
(EXIT_FAILURE
, "fopen");
608 ret
= _lookup_factory_convert
(out
, in
);
611 unlink
(output
); /* dump failure */
620 /* dump pivot to file */
622 out
= fopen
(output
, "wb");
627 err
(EXIT_FAILURE
, "fopen");
629 ret
= _pivot_factory_convert
(out
, in
);
632 unlink
(output
); /* dump failure */
634 errx
(EXIT_FAILURE
, "%s\n", strerror
(ret
));
641 "\t%s [-d] [-o outfile] [infile]\n"
642 "\t%s -m [-d] [-o outfile] [infile]\n"
643 "\t%s -p [-d] [-o outfile] [infile]\n",
644 getprogname
(), getprogname
(), getprogname
());
649 main
(int argc
, char **argv
)
653 int mkdb
= 0, mkpv
= 0;
655 while
((ch
= getopt
(argc
, argv
, "do:mp")) != EOF
) {
661 output
= strdup
(optarg
);
681 in
= fopen
(argv
[0], "r");
683 err
(EXIT_FAILURE
, argv
[0]);