1 /* $NetBSD: yacc.y,v 1.6 2005/06/02 02:07:54 lukem 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 #if HAVE_NBTOOL_CONFIG_H
31 #include "nbtool_config.h"
34 #include <sys/cdefs.h>
36 __RCSID
("$NetBSD: yacc.y,v 1.6 2005/06/02 02:07:54 lukem Exp $");
47 #include <arpa/inet.h>
48 #include <sys/types.h>
56 #include "citrus_namespace.h"
57 #include "citrus_types.h"
58 #include "citrus_mapper_std_file.h"
59 #include "citrus_region.h"
60 #include "citrus_db_factory.h"
61 #include "citrus_db_hash.h"
62 #include "citrus_lookup_factory.h"
63 #include "citrus_pivot_factory.h"
66 static char *output
= NULL
;
67 static void *table
= NULL
;
68 static size_t table_size
;
69 static char *map_name
;
71 static u_int32_t dst_invalid
, dst_ilseq
, oob_mode
, dst_unit_bits
;
72 static void (*putfunc
)(void *, size_t, u_int32_t
) = 0;
74 static u_int32_t src_next
;
76 static u_int32_t done_flag
= 0;
77 #define DF_TYPE 0x00000001
78 #define DF_NAME 0x00000002
79 #define DF_SRC_ZONE 0x00000004
80 #define DF_DST_INVALID 0x00000008
81 #define DF_DST_ILSEQ 0x00000010
82 #define DF_DST_UNIT_BITS 0x00000020
83 #define DF_OOB_MODE 0x00000040
85 static linear_zone_t rowcol
[_CITRUS_MAPPER_STD_ROWCOL_MAX
];
86 static size_t rowcol_len
= 0;
87 static u_int32_t rowcol_bits
= 0, rowcol_mask
= 0;
89 static void dump_file
(void);
90 static void setup_map
(void);
91 static void set_type
(int);
92 static void set_name
(char *);
93 static void set_src_zone
(u_int32_t
);
94 static void set_dst_invalid
(u_int32_t
);
95 static void set_dst_ilseq
(u_int32_t
);
96 static void set_dst_unit_bits
(u_int32_t
);
97 static void set_oob_mode
(u_int32_t
);
98 static int check_src
(u_int32_t
, u_int32_t
);
99 static void store
(const linear_zone_t
*, u_int32_t
, int);
100 static void put8
(void *, size_t, u_int32_t
);
101 static void put16
(void *, size_t, u_int32_t
);
102 static void put32
(void *, size_t, u_int32_t
);
103 static void set_range
(u_int32_t
, u_int32_t
);
104 static void set_src
(linear_zone_t
*, u_int32_t
, u_int32_t
);
110 linear_zone_t lz_value
;
113 %token R_TYPE R_NAME R_SRC_ZONE R_DST_UNIT_BITS
114 %token R_DST_INVALID R_DST_ILSEQ
115 %token R_BEGIN_MAP R_END_MAP R_INVALID R_ROWCOL
116 %token R_ILSEQ R_OOB_MODE
118 %token
<i_value
> L_IMM
119 %token
<s_value
> L_STRING
122 %type
<i_value
> dst types oob_mode_sel zone
126 file
: property mapping lns
129 property
: /* empty */
134 | property dst_invalid
136 | property dst_unit_bits
139 name
: R_NAME L_STRING
{ set_name
($2); $2 = NULL
; }
140 type
: R_TYPE types
{ set_type
($2); }
141 types
: R_ROWCOL
{ $$
= R_ROWCOL
; }
142 range
: L_IMM
'-' L_IMM
{ set_range
($1, $3); }
147 src_zone
: R_SRC_ZONE zone
{ set_src_zone
($2); }
151 | range
'/' range
'/' ranges L_IMM
{
155 dst_invalid
: R_DST_INVALID L_IMM
{ set_dst_invalid
($2); }
156 dst_ilseq
: R_DST_ILSEQ L_IMM
{ set_dst_ilseq
($2); }
157 dst_unit_bits
: R_DST_UNIT_BITS L_IMM
{ set_dst_unit_bits
($2); }
158 oob_mode
: R_OOB_MODE oob_mode_sel
{ set_oob_mode
($2); }
160 oob_mode_sel
: R_INVALID
{ $$
= _CITRUS_MAPPER_STD_OOB_NONIDENTICAL
; }
161 | R_ILSEQ
{ $$
= _CITRUS_MAPPER_STD_OOB_ILSEQ
; }
163 mapping
: begin_map map_elems R_END_MAP
164 begin_map
: R_BEGIN_MAP lns
{ setup_map
(); }
166 map_elems
: /* empty */
167 | map_elems map_elem lns
169 map_elem
: src
'=' dst
170 { store
(&$1, $3, 0); }
172 { store
(&$1, $3, 1); }
188 set_src
(&$$
, src_next
, src_next
);
192 set_src
(&$$
, $1, $1);
196 set_src
(&$$
, $1, $3);
200 set_src
(&$$
, src_next
, $2);
208 warning
(const char *s
)
210 fprintf
(stderr
, "%s in %d\n", s
, line_number
);
214 yyerror(const char *s
)
221 put8
(void *ptr
, size_t ofs
, u_int32_t val
)
223 *((u_int8_t
*)ptr
+ ofs
) = val
;
227 put16
(void *ptr
, size_t ofs
, u_int32_t val
)
229 u_int16_t oval
= htons
(val
);
230 memcpy
((u_int16_t
*)ptr
+ ofs
, &oval
, 2);
234 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)
362 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
,
375 _CITRUS_MAPPER_STD_TYPE_ROWCOL
));
378 create_rowcol_info
(&data
);
379 CHKERR
(ret
, _db_factory_add_by_s
,
380 (df
, _CITRUS_MAPPER_STD_SYM_INFO
, &data
, 1));
382 /* ilseq extension */
383 create_rowcol_ext_ilseq_info
(&data
);
384 CHKERR
(ret
, _db_factory_add_by_s
,
385 (df
, _CITRUS_MAPPER_STD_SYM_ROWCOL_EXT_ILSEQ
, &data
, 1));
388 _region_init
(&data
, table
, table_size
*dst_unit_bits
/8);
389 CHKERR
(ret
, _db_factory_add_by_s
,
390 (df
, _CITRUS_MAPPER_STD_SYM_TABLE
, &data
, 1));
393 * dump database to file
396 fp
= fopen
(output
, "wb");
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
;
436 if
(done_flag
& DF_NAME
) {
437 warning
("NAME is duplicated. ignored this one");
443 done_flag |
= DF_NAME
;
446 set_src_zone
(u_int32_t val
)
451 if
(done_flag
& DF_SRC_ZONE
) {
452 warning
("SRC_ZONE is duplicated. ignored this one");
458 switch
(rowcol_bits
) {
459 case
8: case
16: case
32:
460 if
(rowcol_len
<= 32 / rowcol_bits
)
466 rowcol_mask
= 1 << (rowcol_bits
- 1);
467 rowcol_mask |
= rowcol_mask
- 1;
468 for
(i
= 0; i
< rowcol_len
; ++i
) {
470 _DIAGASSERT
(p
->begin
<= p
->end
);
471 if
(p
->end
> rowcol_mask
)
474 done_flag |
= DF_SRC_ZONE
;
478 yyerror("Illegal argument for SRC_ZONE");
481 set_dst_invalid
(u_int32_t val
)
484 if
(done_flag
& DF_DST_INVALID
) {
485 warning
("DST_INVALID is duplicated. ignored this one");
491 done_flag |
= DF_DST_INVALID
;
494 set_dst_ilseq
(u_int32_t val
)
497 if
(done_flag
& DF_DST_ILSEQ
) {
498 warning
("DST_ILSEQ is duplicated. ignored this one");
504 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
;
520 set_dst_unit_bits
(u_int32_t val
)
523 if
(done_flag
& DF_DST_UNIT_BITS
) {
524 warning
("DST_UNIT_BITS is duplicated. ignored this one");
542 yyerror("Illegal argument for DST_UNIT_BITS");
544 done_flag |
= DF_DST_UNIT_BITS
;
547 check_src
(u_int32_t begin
, u_int32_t end
)
556 m
= begin
& ~rowcol_mask
;
557 n
= end
& ~rowcol_mask
;
561 for
(i
= rowcol_len
* rowcol_bits
, p
= &rowcol
[0]; i
> 0; ++p
) {
563 m
= (begin
>> i
) & rowcol_mask
;
564 if
(m
< p
->begin || m
> p
->end
)
568 n
= end
& rowcol_mask
;
569 _DIAGASSERT
(p
> rowcol
);
571 if
(n
< p
->begin || n
> p
->end
)
577 store
(const linear_zone_t
*lz
, u_int32_t dst
, int inc
)
584 for
(i
= rowcol_len
* rowcol_bits
, p
= &rowcol
[0]; i
> 0; ++p
) {
586 n
= ((lz
->begin
>> i
) & rowcol_mask
) - p
->begin
;
587 ofs
= (ofs
* p
->width
) + n
;
591 (*putfunc
)(table
, ofs
++, dst
);
597 set_range
(u_int32_t begin
, u_int32_t end
)
601 if
(rowcol_len
>= _CITRUS_MAPPER_STD_ROWCOL_MAX
)
603 p
= &rowcol
[rowcol_len
++];
607 p
->begin
= begin
, p
->end
= end
;
608 p
->width
= end
- begin
+ 1;
613 yyerror("Illegal argument for SRC_ZONE");
616 set_src
(linear_zone_t
*lz
, u_int32_t begin
, u_int32_t end
)
618 _DIAGASSERT
(lz
!= NULL
);
620 if
(check_src
(begin
, end
) != 0)
621 yyerror("illegal zone");
623 lz
->begin
= begin
, lz
->end
= end
;
624 lz
->width
= end
- begin
+ 1;
635 /* dump DB to file */
637 out
= fopen
(output
, "wb");
642 err
(EXIT_FAILURE
, "fopen");
644 ret
= _lookup_factory_convert
(out
, in
);
647 unlink
(output
); /* dump failure */
656 /* dump pivot to file */
658 out
= fopen
(output
, "wb");
663 err
(EXIT_FAILURE
, "fopen");
665 ret
= _pivot_factory_convert
(out
, in
);
668 unlink
(output
); /* dump failure */
670 errx
(EXIT_FAILURE
, "%s\n", strerror
(ret
));
677 "\t%s [-d] [-o outfile] [infile]\n"
678 "\t%s -m [-d] [-o outfile] [infile]\n"
679 "\t%s -p [-d] [-o outfile] [infile]\n",
680 getprogname
(), getprogname
(), getprogname
());
685 main
(int argc
, char **argv
)
691 int mkdb
= 0, mkpv
= 0;
693 while
((ch
=getopt
(argc
, argv
, "do:mp")) != EOF
) {
699 output
= strdup
(optarg
);
719 in
= fopen
(argv
[0], "r");
721 err
(EXIT_FAILURE
, argv
[0]);