xref: /dflybsd-src/usr.bin/mkcsmapper/yacc.y (revision 98d441962b1cbdff27f00af41c5e330627b8c1d2)
10d5acd74SJohn Marino /* $FreeBSD: head/usr.bin/mkcsmapper/yacc.y 250984 2013-05-25 15:36:15Z ed $ */
252347f71SHasso Tepper /* $NetBSD: yacc.y,v 1.7 2006/09/09 14:35:17 tnozaki Exp $	*/
330e4e410SJoerg Sonnenberger 
430e4e410SJoerg Sonnenberger %{
530e4e410SJoerg Sonnenberger /*-
652347f71SHasso Tepper  * Copyright (c)2003, 2006 Citrus Project,
730e4e410SJoerg Sonnenberger  * All rights reserved.
830e4e410SJoerg Sonnenberger  *
930e4e410SJoerg Sonnenberger  * Redistribution and use in source and binary forms, with or without
1030e4e410SJoerg Sonnenberger  * modification, are permitted provided that the following conditions
1130e4e410SJoerg Sonnenberger  * are met:
1230e4e410SJoerg Sonnenberger  * 1. Redistributions of source code must retain the above copyright
1330e4e410SJoerg Sonnenberger  *    notice, this list of conditions and the following disclaimer.
1430e4e410SJoerg Sonnenberger  * 2. Redistributions in binary form must reproduce the above copyright
1530e4e410SJoerg Sonnenberger  *    notice, this list of conditions and the following disclaimer in the
1630e4e410SJoerg Sonnenberger  *    documentation and/or other materials provided with the distribution.
1730e4e410SJoerg Sonnenberger  *
1830e4e410SJoerg Sonnenberger  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1930e4e410SJoerg Sonnenberger  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2030e4e410SJoerg Sonnenberger  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2130e4e410SJoerg Sonnenberger  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2230e4e410SJoerg Sonnenberger  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2330e4e410SJoerg Sonnenberger  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2430e4e410SJoerg Sonnenberger  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2530e4e410SJoerg Sonnenberger  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2630e4e410SJoerg Sonnenberger  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2730e4e410SJoerg Sonnenberger  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2830e4e410SJoerg Sonnenberger  * SUCH DAMAGE.
2930e4e410SJoerg Sonnenberger  */
3030e4e410SJoerg Sonnenberger 
310d5acd74SJohn Marino #include <sys/cdefs.h>
3230e4e410SJoerg Sonnenberger #include <sys/types.h>
330d5acd74SJohn Marino 
3430e4e410SJoerg Sonnenberger #include <assert.h>
3530e4e410SJoerg Sonnenberger #include <err.h>
3630e4e410SJoerg Sonnenberger #include <errno.h>
3730e4e410SJoerg Sonnenberger #include <limits.h>
3830e4e410SJoerg Sonnenberger #include <stdio.h>
3930e4e410SJoerg Sonnenberger #include <stdlib.h>
4030e4e410SJoerg Sonnenberger #include <string.h>
4130e4e410SJoerg Sonnenberger #include <unistd.h>
420d5acd74SJohn Marino #include <arpa/inet.h>
4330e4e410SJoerg Sonnenberger 
4430e4e410SJoerg Sonnenberger #include "ldef.h"
4530e4e410SJoerg Sonnenberger 
460d5acd74SJohn Marino #ifndef __packed
470d5acd74SJohn Marino #define __packed
480d5acd74SJohn Marino #endif
490d5acd74SJohn Marino 
5030e4e410SJoerg Sonnenberger #include "citrus_namespace.h"
5130e4e410SJoerg Sonnenberger #include "citrus_types.h"
5230e4e410SJoerg Sonnenberger #include "citrus_mapper_std_file.h"
5330e4e410SJoerg Sonnenberger #include "citrus_region.h"
5430e4e410SJoerg Sonnenberger #include "citrus_db_factory.h"
5530e4e410SJoerg Sonnenberger #include "citrus_db_hash.h"
5630e4e410SJoerg Sonnenberger #include "citrus_lookup_factory.h"
5730e4e410SJoerg Sonnenberger #include "citrus_pivot_factory.h"
5830e4e410SJoerg Sonnenberger 
5930e4e410SJoerg Sonnenberger extern FILE		*yyin;
6030e4e410SJoerg Sonnenberger 
6130e4e410SJoerg Sonnenberger int			 debug = 0;
620d5acd74SJohn Marino 
630d5acd74SJohn Marino static linear_zone_t	 rowcol[_CITRUS_MAPPER_STD_ROWCOL_MAX];
640d5acd74SJohn Marino static char		*map_name;
6530e4e410SJoerg Sonnenberger static char		*output = NULL;
6630e4e410SJoerg Sonnenberger static void		*table = NULL;
670d5acd74SJohn Marino static size_t		 rowcol_len = 0;
6830e4e410SJoerg Sonnenberger static size_t		 table_size;
6930e4e410SJoerg Sonnenberger static u_int32_t	 done_flag = 0;
700d5acd74SJohn Marino static u_int32_t	 dst_ilseq, dst_invalid, dst_unit_bits, oob_mode;
710d5acd74SJohn Marino static u_int32_t	 rowcol_bits = 0, rowcol_mask = 0;
720d5acd74SJohn Marino static u_int32_t	 src_next;
730d5acd74SJohn Marino static int		 map_type;
740d5acd74SJohn Marino static void		 (*putfunc)(void *, size_t, u_int32_t) = NULL;
750d5acd74SJohn Marino 
7630e4e410SJoerg Sonnenberger #define DF_TYPE			0x00000001
7730e4e410SJoerg Sonnenberger #define DF_NAME			0x00000002
7830e4e410SJoerg Sonnenberger #define DF_SRC_ZONE		0x00000004
7930e4e410SJoerg Sonnenberger #define DF_DST_INVALID		0x00000008
8030e4e410SJoerg Sonnenberger #define DF_DST_ILSEQ		0x00000010
8130e4e410SJoerg Sonnenberger #define DF_DST_UNIT_BITS	0x00000020
8230e4e410SJoerg Sonnenberger #define DF_OOB_MODE		0x00000040
8330e4e410SJoerg Sonnenberger 
8430e4e410SJoerg Sonnenberger static void	dump_file(void);
8530e4e410SJoerg Sonnenberger static void	setup_map(void);
8630e4e410SJoerg Sonnenberger static void	set_type(int);
8730e4e410SJoerg Sonnenberger static void	set_name(char *);
8852347f71SHasso Tepper static void	set_src_zone(u_int32_t);
8930e4e410SJoerg Sonnenberger static void	set_dst_invalid(u_int32_t);
9030e4e410SJoerg Sonnenberger static void	set_dst_ilseq(u_int32_t);
9130e4e410SJoerg Sonnenberger static void	set_dst_unit_bits(u_int32_t);
9230e4e410SJoerg Sonnenberger static void	set_oob_mode(u_int32_t);
9330e4e410SJoerg Sonnenberger static int	check_src(u_int32_t, u_int32_t);
9430e4e410SJoerg Sonnenberger static void	store(const linear_zone_t *, u_int32_t, int);
9530e4e410SJoerg Sonnenberger static void	put8(void *, size_t, u_int32_t);
9630e4e410SJoerg Sonnenberger static void	put16(void *, size_t, u_int32_t);
9730e4e410SJoerg Sonnenberger static void	put32(void *, size_t, u_int32_t);
9852347f71SHasso Tepper static void	set_range(u_int32_t, u_int32_t);
9952347f71SHasso Tepper static void	set_src(linear_zone_t *, u_int32_t, u_int32_t);
10001a7cd6eSSascha Wildner 
101*98d44196SSascha Wildner #if YYPATCH < 20180510
10201a7cd6eSSascha Wildner int		yylex(void);
103*98d44196SSascha Wildner #endif
10430e4e410SJoerg Sonnenberger %}
10530e4e410SJoerg Sonnenberger 
10630e4e410SJoerg Sonnenberger %union {
10730e4e410SJoerg Sonnenberger 	u_int32_t	 i_value;
10830e4e410SJoerg Sonnenberger 	char		*s_value;
10930e4e410SJoerg Sonnenberger 	linear_zone_t	 lz_value;
11030e4e410SJoerg Sonnenberger }
11130e4e410SJoerg Sonnenberger 
11230e4e410SJoerg Sonnenberger %token			R_TYPE R_NAME R_SRC_ZONE R_DST_UNIT_BITS
11330e4e410SJoerg Sonnenberger %token			R_DST_INVALID R_DST_ILSEQ
11430e4e410SJoerg Sonnenberger %token			R_BEGIN_MAP R_END_MAP R_INVALID R_ROWCOL
11530e4e410SJoerg Sonnenberger %token			R_ILSEQ R_OOB_MODE
11630e4e410SJoerg Sonnenberger %token			R_LN
11730e4e410SJoerg Sonnenberger %token <i_value>	L_IMM
11830e4e410SJoerg Sonnenberger %token <s_value>	L_STRING
11930e4e410SJoerg Sonnenberger 
12030e4e410SJoerg Sonnenberger %type <lz_value>	src
12152347f71SHasso Tepper %type <i_value>		dst types oob_mode_sel zone
12230e4e410SJoerg Sonnenberger 
12330e4e410SJoerg Sonnenberger %%
12430e4e410SJoerg Sonnenberger 
12530e4e410SJoerg Sonnenberger file		: property mapping lns
12630e4e410SJoerg Sonnenberger 		{ dump_file(); }
12730e4e410SJoerg Sonnenberger 
12830e4e410SJoerg Sonnenberger property	: /* empty */
12930e4e410SJoerg Sonnenberger 		| property R_LN
13030e4e410SJoerg Sonnenberger 		| property name
13130e4e410SJoerg Sonnenberger 		| property type
13230e4e410SJoerg Sonnenberger 		| property src_zone
13330e4e410SJoerg Sonnenberger 		| property dst_invalid
13430e4e410SJoerg Sonnenberger 		| property dst_ilseq
13530e4e410SJoerg Sonnenberger 		| property dst_unit_bits
13630e4e410SJoerg Sonnenberger 		| property oob_mode
13730e4e410SJoerg Sonnenberger 
13830e4e410SJoerg Sonnenberger name		: R_NAME L_STRING { set_name($2); $2 = NULL; }
13930e4e410SJoerg Sonnenberger type		: R_TYPE types { set_type($2); }
14030e4e410SJoerg Sonnenberger types		: R_ROWCOL { $$ = R_ROWCOL; }
14152347f71SHasso Tepper range		: L_IMM '-' L_IMM { set_range($1, $3); }
14252347f71SHasso Tepper 
14352347f71SHasso Tepper ranges		: /* empty */
14452347f71SHasso Tepper 		| ranges range '/'
14552347f71SHasso Tepper 
14652347f71SHasso Tepper src_zone	: R_SRC_ZONE zone { set_src_zone($2); }
14752347f71SHasso Tepper zone		: range {
14852347f71SHasso Tepper 			$$ = 32;
14930e4e410SJoerg Sonnenberger 		}
15052347f71SHasso Tepper 		| range '/' range '/' ranges L_IMM {
15152347f71SHasso Tepper 			$$ = $6;
15230e4e410SJoerg Sonnenberger 		}
15330e4e410SJoerg Sonnenberger 
15430e4e410SJoerg Sonnenberger dst_invalid	: R_DST_INVALID L_IMM { set_dst_invalid($2); }
15530e4e410SJoerg Sonnenberger dst_ilseq	: R_DST_ILSEQ L_IMM { set_dst_ilseq($2); }
15630e4e410SJoerg Sonnenberger dst_unit_bits	: R_DST_UNIT_BITS L_IMM { set_dst_unit_bits($2); }
15730e4e410SJoerg Sonnenberger oob_mode	: R_OOB_MODE oob_mode_sel { set_oob_mode($2); }
15830e4e410SJoerg Sonnenberger 
15930e4e410SJoerg Sonnenberger oob_mode_sel	: R_INVALID { $$ = _CITRUS_MAPPER_STD_OOB_NONIDENTICAL; }
16030e4e410SJoerg Sonnenberger 		| R_ILSEQ { $$ = _CITRUS_MAPPER_STD_OOB_ILSEQ; }
16130e4e410SJoerg Sonnenberger 
16230e4e410SJoerg Sonnenberger mapping		: begin_map map_elems R_END_MAP
16330e4e410SJoerg Sonnenberger begin_map	: R_BEGIN_MAP lns { setup_map(); }
16430e4e410SJoerg Sonnenberger 
16530e4e410SJoerg Sonnenberger map_elems	: /* empty */
16630e4e410SJoerg Sonnenberger 		| map_elems map_elem lns
16730e4e410SJoerg Sonnenberger 
16830e4e410SJoerg Sonnenberger map_elem	: src '=' dst
16930e4e410SJoerg Sonnenberger 		{ store(&$1, $3, 0); }
17030e4e410SJoerg Sonnenberger 		| src '=' L_IMM '-'
17130e4e410SJoerg Sonnenberger 		{ store(&$1, $3, 1); }
17230e4e410SJoerg Sonnenberger dst		: L_IMM
17330e4e410SJoerg Sonnenberger 		{
17430e4e410SJoerg Sonnenberger 			$$ = $1;
17530e4e410SJoerg Sonnenberger 		}
17630e4e410SJoerg Sonnenberger 		| R_INVALID
17730e4e410SJoerg Sonnenberger 		{
17830e4e410SJoerg Sonnenberger 			$$ = dst_invalid;
17930e4e410SJoerg Sonnenberger 		}
18030e4e410SJoerg Sonnenberger 		| R_ILSEQ
18130e4e410SJoerg Sonnenberger 		{
18230e4e410SJoerg Sonnenberger 			$$ = dst_ilseq;
18330e4e410SJoerg Sonnenberger 		}
18430e4e410SJoerg Sonnenberger 
18530e4e410SJoerg Sonnenberger src		: /* empty */
18630e4e410SJoerg Sonnenberger 		{
18752347f71SHasso Tepper 			set_src(&$$, src_next, src_next);
18830e4e410SJoerg Sonnenberger 		}
18930e4e410SJoerg Sonnenberger 		| L_IMM
19030e4e410SJoerg Sonnenberger 		{
19152347f71SHasso Tepper 			set_src(&$$, $1, $1);
19230e4e410SJoerg Sonnenberger 		}
19330e4e410SJoerg Sonnenberger 		| L_IMM '-' L_IMM
19430e4e410SJoerg Sonnenberger 		{
19552347f71SHasso Tepper 			set_src(&$$, $1, $3);
19630e4e410SJoerg Sonnenberger 		}
19730e4e410SJoerg Sonnenberger 		| '-' L_IMM
19830e4e410SJoerg Sonnenberger 		{
19952347f71SHasso Tepper 			set_src(&$$, src_next, $2);
20030e4e410SJoerg Sonnenberger 		}
20130e4e410SJoerg Sonnenberger lns		: R_LN
20230e4e410SJoerg Sonnenberger 		| lns R_LN
20330e4e410SJoerg Sonnenberger 
20430e4e410SJoerg Sonnenberger %%
20530e4e410SJoerg Sonnenberger 
20630e4e410SJoerg Sonnenberger static void
20730e4e410SJoerg Sonnenberger warning(const char *s)
20830e4e410SJoerg Sonnenberger {
2090d5acd74SJohn Marino 
2100d5acd74SJohn Marino 	fprintf(stderr, "%s in %d\n", s, linenumber);
21130e4e410SJoerg Sonnenberger }
21230e4e410SJoerg Sonnenberger 
21330e4e410SJoerg Sonnenberger int
yyerror(const char * s)21430e4e410SJoerg Sonnenberger yyerror(const char *s)
21530e4e410SJoerg Sonnenberger {
2160d5acd74SJohn Marino 
21730e4e410SJoerg Sonnenberger 	warning(s);
21830e4e410SJoerg Sonnenberger 	exit(1);
21930e4e410SJoerg Sonnenberger }
22030e4e410SJoerg Sonnenberger 
22130e4e410SJoerg Sonnenberger void
put8(void * ptr,size_t ofs,u_int32_t val)22230e4e410SJoerg Sonnenberger put8(void *ptr, size_t ofs, u_int32_t val)
22330e4e410SJoerg Sonnenberger {
2240d5acd74SJohn Marino 
22530e4e410SJoerg Sonnenberger 	*((u_int8_t *)ptr + ofs) = val;
22630e4e410SJoerg Sonnenberger }
22730e4e410SJoerg Sonnenberger 
22830e4e410SJoerg Sonnenberger void
put16(void * ptr,size_t ofs,u_int32_t val)22930e4e410SJoerg Sonnenberger put16(void *ptr, size_t ofs, u_int32_t val)
23030e4e410SJoerg Sonnenberger {
2310d5acd74SJohn Marino 
23230e4e410SJoerg Sonnenberger 	u_int16_t oval = htons(val);
23330e4e410SJoerg Sonnenberger 	memcpy((u_int16_t *)ptr + ofs, &oval, 2);
23430e4e410SJoerg Sonnenberger }
23530e4e410SJoerg Sonnenberger 
23630e4e410SJoerg Sonnenberger void
put32(void * ptr,size_t ofs,u_int32_t val)23730e4e410SJoerg Sonnenberger put32(void *ptr, size_t ofs, u_int32_t val)
23830e4e410SJoerg Sonnenberger {
2390d5acd74SJohn Marino 
24030e4e410SJoerg Sonnenberger 	u_int32_t oval = htonl(val);
24130e4e410SJoerg Sonnenberger 	memcpy((u_int32_t *)ptr + ofs, &oval, 4);
24230e4e410SJoerg Sonnenberger }
24330e4e410SJoerg Sonnenberger 
24430e4e410SJoerg Sonnenberger static void
alloc_table(void)24530e4e410SJoerg Sonnenberger alloc_table(void)
24630e4e410SJoerg Sonnenberger {
24752347f71SHasso Tepper 	linear_zone_t *p;
2480d5acd74SJohn Marino 	size_t i;
2490d5acd74SJohn Marino 	uint32_t val = 0;
25030e4e410SJoerg Sonnenberger 
25152347f71SHasso Tepper 	i = rowcol_len;
25252347f71SHasso Tepper 	p = &rowcol[--i];
25352347f71SHasso Tepper 	table_size = p->width;
25452347f71SHasso Tepper 	while (i > 0) {
25552347f71SHasso Tepper 		p = &rowcol[--i];
25652347f71SHasso Tepper 		table_size *= p->width;
25752347f71SHasso Tepper 	}
25852347f71SHasso Tepper 	table = (void *)malloc(table_size * dst_unit_bits / 8);
25952347f71SHasso Tepper 	if (table == NULL) {
26030e4e410SJoerg Sonnenberger 		perror("malloc");
26130e4e410SJoerg Sonnenberger 		exit(1);
26230e4e410SJoerg Sonnenberger 	}
26330e4e410SJoerg Sonnenberger 
26430e4e410SJoerg Sonnenberger 	switch (oob_mode) {
26530e4e410SJoerg Sonnenberger 	case _CITRUS_MAPPER_STD_OOB_NONIDENTICAL:
26630e4e410SJoerg Sonnenberger 		val = dst_invalid;
26730e4e410SJoerg Sonnenberger 		break;
26830e4e410SJoerg Sonnenberger 	case _CITRUS_MAPPER_STD_OOB_ILSEQ:
26930e4e410SJoerg Sonnenberger 		val = dst_ilseq;
27030e4e410SJoerg Sonnenberger 		break;
27130e4e410SJoerg Sonnenberger 	default:
2720d5acd74SJohn Marino 		break;
27330e4e410SJoerg Sonnenberger 	}
27430e4e410SJoerg Sonnenberger 	for (i = 0; i < table_size; i++)
27530e4e410SJoerg Sonnenberger 		(*putfunc)(table, i, val);
27630e4e410SJoerg Sonnenberger }
27730e4e410SJoerg Sonnenberger 
27830e4e410SJoerg Sonnenberger static void
setup_map(void)27930e4e410SJoerg Sonnenberger setup_map(void)
28030e4e410SJoerg Sonnenberger {
28130e4e410SJoerg Sonnenberger 
28230e4e410SJoerg Sonnenberger 	if ((done_flag & DF_SRC_ZONE)==0) {
28330e4e410SJoerg Sonnenberger 		fprintf(stderr, "SRC_ZONE is mandatory.\n");
28430e4e410SJoerg Sonnenberger 		exit(1);
28530e4e410SJoerg Sonnenberger 	}
28630e4e410SJoerg Sonnenberger 	if ((done_flag & DF_DST_UNIT_BITS)==0) {
28730e4e410SJoerg Sonnenberger 		fprintf(stderr, "DST_UNIT_BITS is mandatory.\n");
28830e4e410SJoerg Sonnenberger 		exit(1);
28930e4e410SJoerg Sonnenberger 	}
29030e4e410SJoerg Sonnenberger 
29130e4e410SJoerg Sonnenberger 	if ((done_flag & DF_DST_INVALID) == 0)
29230e4e410SJoerg Sonnenberger 		dst_invalid = 0xFFFFFFFF;
29330e4e410SJoerg Sonnenberger 	if ((done_flag & DF_DST_ILSEQ) == 0)
29430e4e410SJoerg Sonnenberger 		dst_ilseq = 0xFFFFFFFE;
29530e4e410SJoerg Sonnenberger 	if ((done_flag & DF_OOB_MODE) == 0)
29630e4e410SJoerg Sonnenberger 		oob_mode = _CITRUS_MAPPER_STD_OOB_NONIDENTICAL;
29730e4e410SJoerg Sonnenberger 
29830e4e410SJoerg Sonnenberger 	alloc_table();
29930e4e410SJoerg Sonnenberger }
30030e4e410SJoerg Sonnenberger 
30130e4e410SJoerg Sonnenberger static void
create_rowcol_info(struct _region * r)30230e4e410SJoerg Sonnenberger create_rowcol_info(struct _region *r)
30330e4e410SJoerg Sonnenberger {
30430e4e410SJoerg Sonnenberger 	void *ptr;
3050d5acd74SJohn Marino 	size_t i, len, ofs;
30630e4e410SJoerg Sonnenberger 
30730e4e410SJoerg Sonnenberger 	ofs = 0;
30830e4e410SJoerg Sonnenberger 	ptr = malloc(_CITRUS_MAPPER_STD_ROWCOL_INFO_SIZE);
30930e4e410SJoerg Sonnenberger 	if (ptr == NULL)
31030e4e410SJoerg Sonnenberger 		err(EXIT_FAILURE, "malloc");
31152347f71SHasso Tepper 	put32(ptr, ofs, rowcol_bits); ofs++;
31230e4e410SJoerg Sonnenberger 	put32(ptr, ofs, dst_invalid); ofs++;
31330e4e410SJoerg Sonnenberger 
31452347f71SHasso Tepper 	/* XXX: keep backward compatibility */
31552347f71SHasso Tepper 	switch (rowcol_len) {
31652347f71SHasso Tepper 	case 1:
31752347f71SHasso Tepper 		put32(ptr, ofs, 0); ofs++;
31852347f71SHasso Tepper 		put32(ptr, ofs, 0); ofs++;
31952347f71SHasso Tepper 	/*FALLTHROUGH*/
32052347f71SHasso Tepper 	case 2:
32152347f71SHasso Tepper 		len = 0;
32252347f71SHasso Tepper 		break;
32352347f71SHasso Tepper 	default:
32452347f71SHasso Tepper 		len = rowcol_len;
32530e4e410SJoerg Sonnenberger 	}
32652347f71SHasso Tepper 	for (i = 0; i < rowcol_len; ++i) {
32752347f71SHasso Tepper 		put32(ptr, ofs, rowcol[i].begin); ofs++;
32852347f71SHasso Tepper 		put32(ptr, ofs, rowcol[i].end); ofs++;
32952347f71SHasso Tepper 	}
33052347f71SHasso Tepper 	put32(ptr, ofs, dst_unit_bits); ofs++;
33152347f71SHasso Tepper 	put32(ptr, ofs, len); ofs++;
33252347f71SHasso Tepper 
33352347f71SHasso Tepper 	_region_init(r, ptr, ofs * 4);
33452347f71SHasso Tepper }
33552347f71SHasso Tepper 
33630e4e410SJoerg Sonnenberger 
33730e4e410SJoerg Sonnenberger static void
create_rowcol_ext_ilseq_info(struct _region * r)33830e4e410SJoerg Sonnenberger create_rowcol_ext_ilseq_info(struct _region *r)
33930e4e410SJoerg Sonnenberger {
34030e4e410SJoerg Sonnenberger 	void *ptr;
34130e4e410SJoerg Sonnenberger 	size_t ofs;
34230e4e410SJoerg Sonnenberger 
34330e4e410SJoerg Sonnenberger 	ofs = 0;
34430e4e410SJoerg Sonnenberger 	ptr = malloc(_CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE);
34530e4e410SJoerg Sonnenberger 	if (ptr == NULL)
34630e4e410SJoerg Sonnenberger 		err(EXIT_FAILURE, "malloc");
34730e4e410SJoerg Sonnenberger 
34830e4e410SJoerg Sonnenberger 	put32(ptr, ofs, oob_mode); ofs++;
34930e4e410SJoerg Sonnenberger 	put32(ptr, ofs, dst_ilseq); ofs++;
35030e4e410SJoerg Sonnenberger 
35130e4e410SJoerg Sonnenberger 	_region_init(r, ptr, _CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE);
35230e4e410SJoerg Sonnenberger }
35330e4e410SJoerg Sonnenberger 
35430e4e410SJoerg Sonnenberger #define CHKERR(ret, func, a)						\
35530e4e410SJoerg Sonnenberger do {									\
35630e4e410SJoerg Sonnenberger 	ret = func a;							\
35730e4e410SJoerg Sonnenberger 	if (ret)							\
35830e4e410SJoerg Sonnenberger 		errx(EXIT_FAILURE, "%s: %s", #func, strerror(ret));	\
35930e4e410SJoerg Sonnenberger } while (/*CONSTCOND*/0)
36030e4e410SJoerg Sonnenberger 
36130e4e410SJoerg Sonnenberger static void
dump_file(void)36230e4e410SJoerg Sonnenberger dump_file(void)
36330e4e410SJoerg Sonnenberger {
36430e4e410SJoerg Sonnenberger 	struct _db_factory *df;
36530e4e410SJoerg Sonnenberger 	struct _region data;
36630e4e410SJoerg Sonnenberger 	void *serialized;
3670d5acd74SJohn Marino 	FILE *fp;
36830e4e410SJoerg Sonnenberger 	size_t size;
3690d5acd74SJohn Marino 	int ret;
37030e4e410SJoerg Sonnenberger 
37130e4e410SJoerg Sonnenberger 	/*
37230e4e410SJoerg Sonnenberger 	 * build database
37330e4e410SJoerg Sonnenberger 	 */
37430e4e410SJoerg Sonnenberger 	CHKERR(ret, _db_factory_create, (&df, _db_hash_std, NULL));
37530e4e410SJoerg Sonnenberger 
37630e4e410SJoerg Sonnenberger 	/* store type */
37730e4e410SJoerg Sonnenberger 	CHKERR(ret, _db_factory_addstr_by_s,
3780d5acd74SJohn Marino 	    (df, _CITRUS_MAPPER_STD_SYM_TYPE, _CITRUS_MAPPER_STD_TYPE_ROWCOL));
37930e4e410SJoerg Sonnenberger 
38030e4e410SJoerg Sonnenberger 	/* store info */
38130e4e410SJoerg Sonnenberger 	create_rowcol_info(&data);
38230e4e410SJoerg Sonnenberger 	CHKERR(ret, _db_factory_add_by_s,
38330e4e410SJoerg Sonnenberger 	    (df, _CITRUS_MAPPER_STD_SYM_INFO, &data, 1));
38430e4e410SJoerg Sonnenberger 
38530e4e410SJoerg Sonnenberger 	/* ilseq extension */
38630e4e410SJoerg Sonnenberger 	create_rowcol_ext_ilseq_info(&data);
38730e4e410SJoerg Sonnenberger 	CHKERR(ret, _db_factory_add_by_s,
38830e4e410SJoerg Sonnenberger 	    (df, _CITRUS_MAPPER_STD_SYM_ROWCOL_EXT_ILSEQ, &data, 1));
38930e4e410SJoerg Sonnenberger 
39030e4e410SJoerg Sonnenberger 	/* store table */
39130e4e410SJoerg Sonnenberger 	_region_init(&data, table, table_size*dst_unit_bits/8);
39230e4e410SJoerg Sonnenberger 	CHKERR(ret, _db_factory_add_by_s,
39330e4e410SJoerg Sonnenberger 	    (df, _CITRUS_MAPPER_STD_SYM_TABLE, &data, 1));
39430e4e410SJoerg Sonnenberger 
39530e4e410SJoerg Sonnenberger 	/*
39630e4e410SJoerg Sonnenberger 	 * dump database to file
39730e4e410SJoerg Sonnenberger 	 */
3980d5acd74SJohn Marino 	fp = output ? fopen(output, "wb") : stdout;
39930e4e410SJoerg Sonnenberger 
40030e4e410SJoerg Sonnenberger 	if (fp == NULL) {
40130e4e410SJoerg Sonnenberger 		perror("fopen");
40230e4e410SJoerg Sonnenberger 		exit(1);
40330e4e410SJoerg Sonnenberger 	}
40430e4e410SJoerg Sonnenberger 
40530e4e410SJoerg Sonnenberger 	/* dump database body */
40630e4e410SJoerg Sonnenberger 	size = _db_factory_calc_size(df);
40730e4e410SJoerg Sonnenberger 	serialized = malloc(size);
40830e4e410SJoerg Sonnenberger 	_region_init(&data, serialized, size);
40930e4e410SJoerg Sonnenberger 	CHKERR(ret, _db_factory_serialize,
41030e4e410SJoerg Sonnenberger 	    (df, _CITRUS_MAPPER_STD_MAGIC, &data));
41130e4e410SJoerg Sonnenberger 	if (fwrite(serialized, size, 1, fp) != 1)
41230e4e410SJoerg Sonnenberger 		err(EXIT_FAILURE, "fwrite");
41330e4e410SJoerg Sonnenberger 
41430e4e410SJoerg Sonnenberger 	fclose(fp);
41530e4e410SJoerg Sonnenberger }
41630e4e410SJoerg Sonnenberger 
41730e4e410SJoerg Sonnenberger static void
41830e4e410SJoerg Sonnenberger /*ARGSUSED*/
set_type(int type)41930e4e410SJoerg Sonnenberger set_type(int type)
42030e4e410SJoerg Sonnenberger {
42130e4e410SJoerg Sonnenberger 
42230e4e410SJoerg Sonnenberger 	if (done_flag & DF_TYPE) {
42330e4e410SJoerg Sonnenberger 		warning("TYPE is duplicated. ignored this one");
42430e4e410SJoerg Sonnenberger 		return;
42530e4e410SJoerg Sonnenberger 	}
42630e4e410SJoerg Sonnenberger 
42730e4e410SJoerg Sonnenberger 	map_type = type;
42830e4e410SJoerg Sonnenberger 
42930e4e410SJoerg Sonnenberger 	done_flag |= DF_TYPE;
43030e4e410SJoerg Sonnenberger }
4310d5acd74SJohn Marino 
43230e4e410SJoerg Sonnenberger static void
43330e4e410SJoerg Sonnenberger /*ARGSUSED*/
set_name(char * str)43430e4e410SJoerg Sonnenberger set_name(char *str)
43530e4e410SJoerg Sonnenberger {
43630e4e410SJoerg Sonnenberger 
43730e4e410SJoerg Sonnenberger 	if (done_flag & DF_NAME) {
43830e4e410SJoerg Sonnenberger 		warning("NAME is duplicated. ignored this one");
43930e4e410SJoerg Sonnenberger 		return;
44030e4e410SJoerg Sonnenberger 	}
44130e4e410SJoerg Sonnenberger 
44230e4e410SJoerg Sonnenberger 	map_name = str;
44330e4e410SJoerg Sonnenberger 
44430e4e410SJoerg Sonnenberger 	done_flag |= DF_NAME;
44530e4e410SJoerg Sonnenberger }
4460d5acd74SJohn Marino 
44730e4e410SJoerg Sonnenberger static void
set_src_zone(u_int32_t val)44852347f71SHasso Tepper set_src_zone(u_int32_t val)
44930e4e410SJoerg Sonnenberger {
45052347f71SHasso Tepper 	linear_zone_t *p;
4510d5acd74SJohn Marino 	size_t i;
45230e4e410SJoerg Sonnenberger 
45330e4e410SJoerg Sonnenberger 	if (done_flag & DF_SRC_ZONE) {
45430e4e410SJoerg Sonnenberger 		warning("SRC_ZONE is duplicated. ignored this one");
45530e4e410SJoerg Sonnenberger 		return;
45630e4e410SJoerg Sonnenberger 	}
45752347f71SHasso Tepper 	rowcol_bits = val;
45830e4e410SJoerg Sonnenberger 
45930e4e410SJoerg Sonnenberger 	/* sanity check */
46052347f71SHasso Tepper 	switch (rowcol_bits) {
46152347f71SHasso Tepper 	case 8: case 16: case 32:
46252347f71SHasso Tepper 		if (rowcol_len <= 32 / rowcol_bits)
46352347f71SHasso Tepper 			break;
46452347f71SHasso Tepper 	/*FALLTHROUGH*/
46552347f71SHasso Tepper 	default:
46630e4e410SJoerg Sonnenberger 		goto bad;
46730e4e410SJoerg Sonnenberger 	}
46852347f71SHasso Tepper 	rowcol_mask = 1 << (rowcol_bits - 1);
46952347f71SHasso Tepper 	rowcol_mask |= rowcol_mask - 1;
47052347f71SHasso Tepper 	for (i = 0; i < rowcol_len; ++i) {
47152347f71SHasso Tepper 		p = &rowcol[i];
47252347f71SHasso Tepper 		if (p->end > rowcol_mask)
47352347f71SHasso Tepper 			goto bad;
47452347f71SHasso Tepper 	}
47552347f71SHasso Tepper 	done_flag |= DF_SRC_ZONE;
47652347f71SHasso Tepper 	return;
47730e4e410SJoerg Sonnenberger 
47830e4e410SJoerg Sonnenberger bad:
47930e4e410SJoerg Sonnenberger 	yyerror("Illegal argument for SRC_ZONE");
48030e4e410SJoerg Sonnenberger }
4810d5acd74SJohn Marino 
48230e4e410SJoerg Sonnenberger static void
set_dst_invalid(u_int32_t val)48330e4e410SJoerg Sonnenberger set_dst_invalid(u_int32_t val)
48430e4e410SJoerg Sonnenberger {
48530e4e410SJoerg Sonnenberger 
48630e4e410SJoerg Sonnenberger 	if (done_flag & DF_DST_INVALID) {
48730e4e410SJoerg Sonnenberger 		warning("DST_INVALID is duplicated. ignored this one");
48830e4e410SJoerg Sonnenberger 		return;
48930e4e410SJoerg Sonnenberger 	}
49030e4e410SJoerg Sonnenberger 
49130e4e410SJoerg Sonnenberger 	dst_invalid = val;
49230e4e410SJoerg Sonnenberger 
49330e4e410SJoerg Sonnenberger 	done_flag |= DF_DST_INVALID;
49430e4e410SJoerg Sonnenberger }
4950d5acd74SJohn Marino 
49630e4e410SJoerg Sonnenberger static void
set_dst_ilseq(u_int32_t val)49730e4e410SJoerg Sonnenberger set_dst_ilseq(u_int32_t val)
49830e4e410SJoerg Sonnenberger {
49930e4e410SJoerg Sonnenberger 
50030e4e410SJoerg Sonnenberger 	if (done_flag & DF_DST_ILSEQ) {
50130e4e410SJoerg Sonnenberger 		warning("DST_ILSEQ is duplicated. ignored this one");
50230e4e410SJoerg Sonnenberger 		return;
50330e4e410SJoerg Sonnenberger 	}
50430e4e410SJoerg Sonnenberger 
50530e4e410SJoerg Sonnenberger 	dst_ilseq = val;
50630e4e410SJoerg Sonnenberger 
50730e4e410SJoerg Sonnenberger 	done_flag |= DF_DST_ILSEQ;
50830e4e410SJoerg Sonnenberger }
5090d5acd74SJohn Marino 
51030e4e410SJoerg Sonnenberger static void
set_oob_mode(u_int32_t val)51130e4e410SJoerg Sonnenberger set_oob_mode(u_int32_t val)
51230e4e410SJoerg Sonnenberger {
51330e4e410SJoerg Sonnenberger 
51430e4e410SJoerg Sonnenberger 	if (done_flag & DF_OOB_MODE) {
51530e4e410SJoerg Sonnenberger 		warning("OOB_MODE is duplicated. ignored this one");
51630e4e410SJoerg Sonnenberger 		return;
51730e4e410SJoerg Sonnenberger 	}
51830e4e410SJoerg Sonnenberger 
51930e4e410SJoerg Sonnenberger 	oob_mode = val;
52030e4e410SJoerg Sonnenberger 
52130e4e410SJoerg Sonnenberger 	done_flag |= DF_OOB_MODE;
52230e4e410SJoerg Sonnenberger }
5230d5acd74SJohn Marino 
52430e4e410SJoerg Sonnenberger static void
set_dst_unit_bits(u_int32_t val)52530e4e410SJoerg Sonnenberger set_dst_unit_bits(u_int32_t val)
52630e4e410SJoerg Sonnenberger {
52730e4e410SJoerg Sonnenberger 
52830e4e410SJoerg Sonnenberger 	if (done_flag & DF_DST_UNIT_BITS) {
52930e4e410SJoerg Sonnenberger 		warning("DST_UNIT_BITS is duplicated. ignored this one");
53030e4e410SJoerg Sonnenberger 		return;
53130e4e410SJoerg Sonnenberger 	}
53230e4e410SJoerg Sonnenberger 
53330e4e410SJoerg Sonnenberger 	switch (val) {
53430e4e410SJoerg Sonnenberger 	case 8:
53530e4e410SJoerg Sonnenberger 		putfunc = &put8;
53630e4e410SJoerg Sonnenberger 		dst_unit_bits = val;
53730e4e410SJoerg Sonnenberger 		break;
53830e4e410SJoerg Sonnenberger 	case 16:
53930e4e410SJoerg Sonnenberger 		putfunc = &put16;
54030e4e410SJoerg Sonnenberger 		dst_unit_bits = val;
54130e4e410SJoerg Sonnenberger 		break;
54230e4e410SJoerg Sonnenberger 	case 32:
54330e4e410SJoerg Sonnenberger 		putfunc = &put32;
54430e4e410SJoerg Sonnenberger 		dst_unit_bits = val;
54530e4e410SJoerg Sonnenberger 		break;
54630e4e410SJoerg Sonnenberger 	default:
54730e4e410SJoerg Sonnenberger 		yyerror("Illegal argument for DST_UNIT_BITS");
54830e4e410SJoerg Sonnenberger 	}
54930e4e410SJoerg Sonnenberger 	done_flag |= DF_DST_UNIT_BITS;
55030e4e410SJoerg Sonnenberger }
5510d5acd74SJohn Marino 
55230e4e410SJoerg Sonnenberger static int
check_src(u_int32_t begin,u_int32_t end)55330e4e410SJoerg Sonnenberger check_src(u_int32_t begin, u_int32_t end)
55430e4e410SJoerg Sonnenberger {
55552347f71SHasso Tepper 	linear_zone_t *p;
5560d5acd74SJohn Marino 	size_t i;
55752347f71SHasso Tepper 	u_int32_t m, n;
55830e4e410SJoerg Sonnenberger 
55952347f71SHasso Tepper 	if (begin > end)
5600d5acd74SJohn Marino 		return (1);
56152347f71SHasso Tepper 	if (begin < end) {
56252347f71SHasso Tepper 		m = begin & ~rowcol_mask;
56352347f71SHasso Tepper 		n = end & ~rowcol_mask;
56452347f71SHasso Tepper 		if (m != n)
5650d5acd74SJohn Marino 			return (1);
56630e4e410SJoerg Sonnenberger 	}
56752347f71SHasso Tepper 	for (i = rowcol_len * rowcol_bits, p = &rowcol[0]; i > 0; ++p) {
56852347f71SHasso Tepper 		i -= rowcol_bits;
56952347f71SHasso Tepper 		m = (begin >> i) & rowcol_mask;
57052347f71SHasso Tepper 		if (m < p->begin || m > p->end)
5710d5acd74SJohn Marino 			return (1);
57230e4e410SJoerg Sonnenberger 	}
57352347f71SHasso Tepper 	if (begin < end) {
57452347f71SHasso Tepper 		n = end & rowcol_mask;
57552347f71SHasso Tepper 		--p;
57652347f71SHasso Tepper 		if (n < p->begin || n > p->end)
5770d5acd74SJohn Marino 			return (1);
57852347f71SHasso Tepper 	}
5790d5acd74SJohn Marino 	return (0);
58030e4e410SJoerg Sonnenberger }
5810d5acd74SJohn Marino 
58230e4e410SJoerg Sonnenberger static void
store(const linear_zone_t * lz,u_int32_t dst,int inc)58330e4e410SJoerg Sonnenberger store(const linear_zone_t *lz, u_int32_t dst, int inc)
58430e4e410SJoerg Sonnenberger {
58552347f71SHasso Tepper 	linear_zone_t *p;
5860d5acd74SJohn Marino 	size_t i, ofs;
58752347f71SHasso Tepper 	u_int32_t n;
58830e4e410SJoerg Sonnenberger 
58952347f71SHasso Tepper 	ofs = 0;
59052347f71SHasso Tepper 	for (i = rowcol_len * rowcol_bits, p = &rowcol[0]; i > 0; ++p) {
59152347f71SHasso Tepper 		i -= rowcol_bits;
59252347f71SHasso Tepper 		n = ((lz->begin >> i) & rowcol_mask) - p->begin;
59352347f71SHasso Tepper 		ofs = (ofs * p->width) + n;
59452347f71SHasso Tepper 	}
59552347f71SHasso Tepper 	n = lz->width;
59652347f71SHasso Tepper 	while (n-- > 0) {
59730e4e410SJoerg Sonnenberger 		(*putfunc)(table, ofs++, dst);
59830e4e410SJoerg Sonnenberger 		if (inc)
59930e4e410SJoerg Sonnenberger 			dst++;
60030e4e410SJoerg Sonnenberger 	}
60130e4e410SJoerg Sonnenberger }
6020d5acd74SJohn Marino 
60352347f71SHasso Tepper static void
set_range(u_int32_t begin,u_int32_t end)60452347f71SHasso Tepper set_range(u_int32_t begin, u_int32_t end)
60552347f71SHasso Tepper {
60652347f71SHasso Tepper 	linear_zone_t *p;
60752347f71SHasso Tepper 
60852347f71SHasso Tepper 	if (rowcol_len >= _CITRUS_MAPPER_STD_ROWCOL_MAX)
60952347f71SHasso Tepper 		goto bad;
61052347f71SHasso Tepper 	p = &rowcol[rowcol_len++];
61152347f71SHasso Tepper 
61252347f71SHasso Tepper 	if (begin > end)
61352347f71SHasso Tepper 		goto bad;
61452347f71SHasso Tepper 	p->begin = begin, p->end = end;
61552347f71SHasso Tepper 	p->width = end - begin + 1;
61652347f71SHasso Tepper 
61752347f71SHasso Tepper 	return;
61852347f71SHasso Tepper 
61952347f71SHasso Tepper bad:
62052347f71SHasso Tepper 	yyerror("Illegal argument for SRC_ZONE");
62152347f71SHasso Tepper }
6220d5acd74SJohn Marino 
62352347f71SHasso Tepper static void
set_src(linear_zone_t * lz,u_int32_t begin,u_int32_t end)62452347f71SHasso Tepper set_src(linear_zone_t *lz, u_int32_t begin, u_int32_t end)
62552347f71SHasso Tepper {
62652347f71SHasso Tepper 
62752347f71SHasso Tepper 	if (check_src(begin, end) != 0)
62852347f71SHasso Tepper 		yyerror("illegal zone");
62952347f71SHasso Tepper 
63052347f71SHasso Tepper 	lz->begin = begin, lz->end = end;
63152347f71SHasso Tepper 	lz->width = end - begin + 1;
63252347f71SHasso Tepper 
63352347f71SHasso Tepper 	src_next = end + 1;
63452347f71SHasso Tepper }
63530e4e410SJoerg Sonnenberger 
63630e4e410SJoerg Sonnenberger static void
do_mkdb(FILE * in)63730e4e410SJoerg Sonnenberger do_mkdb(FILE *in)
63830e4e410SJoerg Sonnenberger {
63930e4e410SJoerg Sonnenberger 	FILE *out;
6400d5acd74SJohn Marino 	int ret;
64130e4e410SJoerg Sonnenberger 
64230e4e410SJoerg Sonnenberger         /* dump DB to file */
6430d5acd74SJohn Marino 	out = output ? fopen(output, "wb") : stdout;
64430e4e410SJoerg Sonnenberger 
64530e4e410SJoerg Sonnenberger 	if (out == NULL)
64630e4e410SJoerg Sonnenberger 		err(EXIT_FAILURE, "fopen");
64730e4e410SJoerg Sonnenberger 
64830e4e410SJoerg Sonnenberger 	ret = _lookup_factory_convert(out, in);
64930e4e410SJoerg Sonnenberger 	fclose(out);
65030e4e410SJoerg Sonnenberger 	if (ret && output)
65130e4e410SJoerg Sonnenberger 		unlink(output); /* dump failure */
65230e4e410SJoerg Sonnenberger }
65330e4e410SJoerg Sonnenberger 
65430e4e410SJoerg Sonnenberger static void
do_mkpv(FILE * in)65530e4e410SJoerg Sonnenberger do_mkpv(FILE *in)
65630e4e410SJoerg Sonnenberger {
65730e4e410SJoerg Sonnenberger 	FILE *out;
6580d5acd74SJohn Marino 	int ret;
65930e4e410SJoerg Sonnenberger 
66030e4e410SJoerg Sonnenberger         /* dump pivot to file */
6610d5acd74SJohn Marino 	out = output ? fopen(output, "wb") : stdout;
66230e4e410SJoerg Sonnenberger 
66330e4e410SJoerg Sonnenberger 	if (out == NULL)
66430e4e410SJoerg Sonnenberger 		err(EXIT_FAILURE, "fopen");
66530e4e410SJoerg Sonnenberger 
66630e4e410SJoerg Sonnenberger 	ret = _pivot_factory_convert(out, in);
66730e4e410SJoerg Sonnenberger 	fclose(out);
66830e4e410SJoerg Sonnenberger 	if (ret && output)
66930e4e410SJoerg Sonnenberger 		unlink(output); /* dump failure */
67030e4e410SJoerg Sonnenberger 	if (ret)
67130e4e410SJoerg Sonnenberger 		errx(EXIT_FAILURE, "%s\n", strerror(ret));
67230e4e410SJoerg Sonnenberger }
67330e4e410SJoerg Sonnenberger 
67430e4e410SJoerg Sonnenberger static void
usage(void)67530e4e410SJoerg Sonnenberger usage(void)
67630e4e410SJoerg Sonnenberger {
67730e4e410SJoerg Sonnenberger 	warnx("usage: \n"
67830e4e410SJoerg Sonnenberger 	    "\t%s [-d] [-o outfile] [infile]\n"
67930e4e410SJoerg Sonnenberger 	    "\t%s -m [-d] [-o outfile] [infile]\n"
68030e4e410SJoerg Sonnenberger 	    "\t%s -p [-d] [-o outfile] [infile]\n",
68130e4e410SJoerg Sonnenberger 	    getprogname(), getprogname(), getprogname());
68230e4e410SJoerg Sonnenberger 	exit(1);
68330e4e410SJoerg Sonnenberger }
68430e4e410SJoerg Sonnenberger 
68530e4e410SJoerg Sonnenberger int
main(int argc,char ** argv)68630e4e410SJoerg Sonnenberger main(int argc, char **argv)
68730e4e410SJoerg Sonnenberger {
68830e4e410SJoerg Sonnenberger 	FILE *in = NULL;
6890d5acd74SJohn Marino 	int ch, mkdb = 0, mkpv = 0;
69030e4e410SJoerg Sonnenberger 
6910d5acd74SJohn Marino 	while ((ch = getopt(argc, argv, "do:mp")) != EOF) {
69230e4e410SJoerg Sonnenberger 		switch (ch) {
69330e4e410SJoerg Sonnenberger 		case 'd':
69430e4e410SJoerg Sonnenberger 			debug = 1;
69530e4e410SJoerg Sonnenberger 			break;
69630e4e410SJoerg Sonnenberger 		case 'o':
69730e4e410SJoerg Sonnenberger 			output = strdup(optarg);
69830e4e410SJoerg Sonnenberger 			break;
69930e4e410SJoerg Sonnenberger 		case 'm':
70030e4e410SJoerg Sonnenberger 			mkdb = 1;
70130e4e410SJoerg Sonnenberger 			break;
70230e4e410SJoerg Sonnenberger 		case 'p':
70330e4e410SJoerg Sonnenberger 			mkpv = 1;
70430e4e410SJoerg Sonnenberger 			break;
70530e4e410SJoerg Sonnenberger 		default:
70630e4e410SJoerg Sonnenberger 			usage();
70730e4e410SJoerg Sonnenberger 		}
70830e4e410SJoerg Sonnenberger 	}
70930e4e410SJoerg Sonnenberger 
71030e4e410SJoerg Sonnenberger 	argc -= optind;
71130e4e410SJoerg Sonnenberger 	argv += optind;
71230e4e410SJoerg Sonnenberger 	switch (argc) {
71330e4e410SJoerg Sonnenberger 	case 0:
71430e4e410SJoerg Sonnenberger 		in = stdin;
71530e4e410SJoerg Sonnenberger 		break;
71630e4e410SJoerg Sonnenberger 	case 1:
71730e4e410SJoerg Sonnenberger 		in = fopen(argv[0], "r");
71830e4e410SJoerg Sonnenberger 		if (!in)
7190d5acd74SJohn Marino 			err(EXIT_FAILURE, "%s", argv[0]);
72030e4e410SJoerg Sonnenberger 		break;
72130e4e410SJoerg Sonnenberger 	default:
72230e4e410SJoerg Sonnenberger 		usage();
72330e4e410SJoerg Sonnenberger 	}
72430e4e410SJoerg Sonnenberger 
72530e4e410SJoerg Sonnenberger 	if (mkdb)
72630e4e410SJoerg Sonnenberger 		do_mkdb(in);
72730e4e410SJoerg Sonnenberger 	else if (mkpv)
72830e4e410SJoerg Sonnenberger 		do_mkpv(in);
72930e4e410SJoerg Sonnenberger 	else {
73030e4e410SJoerg Sonnenberger 		yyin = in;
73130e4e410SJoerg Sonnenberger 		yyparse();
73230e4e410SJoerg Sonnenberger 	}
73330e4e410SJoerg Sonnenberger 
73430e4e410SJoerg Sonnenberger 	return (0);
73530e4e410SJoerg Sonnenberger }
736