xref: /freebsd/usr.bin/mkcsmapper/yacc.y (revision 5e3934b15a2741b2de6b217e77dc9d798d740804)
1aa0bf3d6SBaptiste Daroussin /*     $NetBSD: yacc.y,v 1.11 2016/06/28 09:22:16 wiz Exp $    */
2ad30f8e7SGabor Kovesdan 
3ad30f8e7SGabor Kovesdan %{
4ad30f8e7SGabor Kovesdan /*-
51de7b4b8SPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause
61de7b4b8SPedro F. Giffuni  *
7ad30f8e7SGabor Kovesdan  * Copyright (c)2003, 2006 Citrus Project,
8ad30f8e7SGabor Kovesdan  * All rights reserved.
9ad30f8e7SGabor Kovesdan  *
10ad30f8e7SGabor Kovesdan  * Redistribution and use in source and binary forms, with or without
11ad30f8e7SGabor Kovesdan  * modification, are permitted provided that the following conditions
12ad30f8e7SGabor Kovesdan  * are met:
13ad30f8e7SGabor Kovesdan  * 1. Redistributions of source code must retain the above copyright
14ad30f8e7SGabor Kovesdan  *    notice, this list of conditions and the following disclaimer.
15ad30f8e7SGabor Kovesdan  * 2. Redistributions in binary form must reproduce the above copyright
16ad30f8e7SGabor Kovesdan  *    notice, this list of conditions and the following disclaimer in the
17ad30f8e7SGabor Kovesdan  *    documentation and/or other materials provided with the distribution.
18ad30f8e7SGabor Kovesdan  *
19ad30f8e7SGabor Kovesdan  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20ad30f8e7SGabor Kovesdan  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21ad30f8e7SGabor Kovesdan  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22ad30f8e7SGabor Kovesdan  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23ad30f8e7SGabor Kovesdan  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24ad30f8e7SGabor Kovesdan  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25ad30f8e7SGabor Kovesdan  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26ad30f8e7SGabor Kovesdan  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27ad30f8e7SGabor Kovesdan  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28ad30f8e7SGabor Kovesdan  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29ad30f8e7SGabor Kovesdan  * SUCH DAMAGE.
30ad30f8e7SGabor Kovesdan  */
31ad30f8e7SGabor Kovesdan 
32ad30f8e7SGabor Kovesdan #include <sys/types.h>
33ad30f8e7SGabor Kovesdan 
34ad30f8e7SGabor Kovesdan #include <assert.h>
35ad30f8e7SGabor Kovesdan #include <err.h>
36ad30f8e7SGabor Kovesdan #include <errno.h>
37ad30f8e7SGabor Kovesdan #include <limits.h>
38ad30f8e7SGabor Kovesdan #include <stdio.h>
39ad30f8e7SGabor Kovesdan #include <stdlib.h>
40ad30f8e7SGabor Kovesdan #include <string.h>
41ad30f8e7SGabor Kovesdan #include <unistd.h>
42ad30f8e7SGabor Kovesdan #include <arpa/inet.h>
43ad30f8e7SGabor Kovesdan 
44ad30f8e7SGabor Kovesdan #include "ldef.h"
45ad30f8e7SGabor Kovesdan 
46ad30f8e7SGabor Kovesdan #ifndef __packed
47ad30f8e7SGabor Kovesdan #define __packed
48ad30f8e7SGabor Kovesdan #endif
49ad30f8e7SGabor Kovesdan 
50ad30f8e7SGabor Kovesdan #include "citrus_namespace.h"
51ad30f8e7SGabor Kovesdan #include "citrus_types.h"
52ad30f8e7SGabor Kovesdan #include "citrus_mapper_std_file.h"
53ad30f8e7SGabor Kovesdan #include "citrus_region.h"
54ad30f8e7SGabor Kovesdan #include "citrus_db_factory.h"
55ad30f8e7SGabor Kovesdan #include "citrus_db_hash.h"
56ad30f8e7SGabor Kovesdan #include "citrus_lookup_factory.h"
57ad30f8e7SGabor Kovesdan #include "citrus_pivot_factory.h"
58ad30f8e7SGabor Kovesdan 
59ad30f8e7SGabor Kovesdan extern FILE		*yyin;
60ad30f8e7SGabor Kovesdan 
61ad30f8e7SGabor Kovesdan int			 debug = 0;
62ad30f8e7SGabor Kovesdan 
63ad30f8e7SGabor Kovesdan static linear_zone_t	 rowcol[_CITRUS_MAPPER_STD_ROWCOL_MAX];
64ad30f8e7SGabor Kovesdan static char		*map_name;
65ad30f8e7SGabor Kovesdan static char		*output = NULL;
66ad30f8e7SGabor Kovesdan static void		*table = NULL;
67ad30f8e7SGabor Kovesdan static size_t		 rowcol_len = 0;
68ad30f8e7SGabor Kovesdan static size_t		 table_size;
69ad30f8e7SGabor Kovesdan static u_int32_t	 done_flag = 0;
70ad30f8e7SGabor Kovesdan static u_int32_t	 dst_ilseq, dst_invalid, dst_unit_bits, oob_mode;
71ad30f8e7SGabor Kovesdan static u_int32_t	 rowcol_bits = 0, rowcol_mask = 0;
72ad30f8e7SGabor Kovesdan static u_int32_t	 src_next;
73ad30f8e7SGabor Kovesdan static int		 map_type;
74ad30f8e7SGabor Kovesdan static void		 (*putfunc)(void *, size_t, u_int32_t) = NULL;
75ad30f8e7SGabor Kovesdan 
76ad30f8e7SGabor Kovesdan #define DF_TYPE			0x00000001
77ad30f8e7SGabor Kovesdan #define DF_NAME			0x00000002
78ad30f8e7SGabor Kovesdan #define DF_SRC_ZONE		0x00000004
79ad30f8e7SGabor Kovesdan #define DF_DST_INVALID		0x00000008
80ad30f8e7SGabor Kovesdan #define DF_DST_ILSEQ		0x00000010
81ad30f8e7SGabor Kovesdan #define DF_DST_UNIT_BITS	0x00000020
82ad30f8e7SGabor Kovesdan #define DF_OOB_MODE		0x00000040
83ad30f8e7SGabor Kovesdan 
84ad30f8e7SGabor Kovesdan static void	dump_file(void);
85ad30f8e7SGabor Kovesdan static void	setup_map(void);
86ad30f8e7SGabor Kovesdan static void	set_type(int);
87ad30f8e7SGabor Kovesdan static void	set_name(char *);
88ad30f8e7SGabor Kovesdan static void	set_src_zone(u_int32_t);
89ad30f8e7SGabor Kovesdan static void	set_dst_invalid(u_int32_t);
90ad30f8e7SGabor Kovesdan static void	set_dst_ilseq(u_int32_t);
91ad30f8e7SGabor Kovesdan static void	set_dst_unit_bits(u_int32_t);
92ad30f8e7SGabor Kovesdan static void	set_oob_mode(u_int32_t);
93ad30f8e7SGabor Kovesdan static int	check_src(u_int32_t, u_int32_t);
94ad30f8e7SGabor Kovesdan static void	store(const linear_zone_t *, u_int32_t, int);
95ad30f8e7SGabor Kovesdan static void	put8(void *, size_t, u_int32_t);
96ad30f8e7SGabor Kovesdan static void	put16(void *, size_t, u_int32_t);
97ad30f8e7SGabor Kovesdan static void	put32(void *, size_t, u_int32_t);
98ad30f8e7SGabor Kovesdan static void	set_range(u_int32_t, u_int32_t);
99ad30f8e7SGabor Kovesdan static void	set_src(linear_zone_t *, u_int32_t, u_int32_t);
100ad30f8e7SGabor Kovesdan %}
101ad30f8e7SGabor Kovesdan 
102ad30f8e7SGabor Kovesdan %union {
103ad30f8e7SGabor Kovesdan 	u_int32_t	 i_value;
104ad30f8e7SGabor Kovesdan 	char		*s_value;
105ad30f8e7SGabor Kovesdan 	linear_zone_t	 lz_value;
106ad30f8e7SGabor Kovesdan }
107ad30f8e7SGabor Kovesdan 
108ad30f8e7SGabor Kovesdan %token			R_TYPE R_NAME R_SRC_ZONE R_DST_UNIT_BITS
109ad30f8e7SGabor Kovesdan %token			R_DST_INVALID R_DST_ILSEQ
110ad30f8e7SGabor Kovesdan %token			R_BEGIN_MAP R_END_MAP R_INVALID R_ROWCOL
111ad30f8e7SGabor Kovesdan %token			R_ILSEQ R_OOB_MODE
112ad30f8e7SGabor Kovesdan %token			R_LN
113ad30f8e7SGabor Kovesdan %token <i_value>	L_IMM
114ad30f8e7SGabor Kovesdan %token <s_value>	L_STRING
115ad30f8e7SGabor Kovesdan 
116ad30f8e7SGabor Kovesdan %type <lz_value>	src
117ad30f8e7SGabor Kovesdan %type <i_value>		dst types oob_mode_sel zone
118ad30f8e7SGabor Kovesdan 
119ad30f8e7SGabor Kovesdan %%
120ad30f8e7SGabor Kovesdan 
121ad30f8e7SGabor Kovesdan file		: property mapping lns
122ad30f8e7SGabor Kovesdan 		{ dump_file(); }
123ad30f8e7SGabor Kovesdan 
124ad30f8e7SGabor Kovesdan property	: /* empty */
125ad30f8e7SGabor Kovesdan 		| property R_LN
126ad30f8e7SGabor Kovesdan 		| property name
127ad30f8e7SGabor Kovesdan 		| property type
128ad30f8e7SGabor Kovesdan 		| property src_zone
129ad30f8e7SGabor Kovesdan 		| property dst_invalid
130ad30f8e7SGabor Kovesdan 		| property dst_ilseq
131ad30f8e7SGabor Kovesdan 		| property dst_unit_bits
132ad30f8e7SGabor Kovesdan 		| property oob_mode
133ad30f8e7SGabor Kovesdan 
134ad30f8e7SGabor Kovesdan name		: R_NAME L_STRING { set_name($2); $2 = NULL; }
135ad30f8e7SGabor Kovesdan type		: R_TYPE types { set_type($2); }
136ad30f8e7SGabor Kovesdan types		: R_ROWCOL { $$ = R_ROWCOL; }
137ad30f8e7SGabor Kovesdan range		: L_IMM '-' L_IMM { set_range($1, $3); }
138ad30f8e7SGabor Kovesdan 
139ad30f8e7SGabor Kovesdan ranges		: /* empty */
140ad30f8e7SGabor Kovesdan 		| ranges range '/'
141ad30f8e7SGabor Kovesdan 
142ad30f8e7SGabor Kovesdan src_zone	: R_SRC_ZONE zone { set_src_zone($2); }
143ad30f8e7SGabor Kovesdan zone		: range {
144ad30f8e7SGabor Kovesdan 			$$ = 32;
145ad30f8e7SGabor Kovesdan 		}
146ad30f8e7SGabor Kovesdan 		| range '/' range '/' ranges L_IMM {
147ad30f8e7SGabor Kovesdan 			$$ = $6;
148ad30f8e7SGabor Kovesdan 		}
149ad30f8e7SGabor Kovesdan 
150ad30f8e7SGabor Kovesdan dst_invalid	: R_DST_INVALID L_IMM { set_dst_invalid($2); }
151ad30f8e7SGabor Kovesdan dst_ilseq	: R_DST_ILSEQ L_IMM { set_dst_ilseq($2); }
152ad30f8e7SGabor Kovesdan dst_unit_bits	: R_DST_UNIT_BITS L_IMM { set_dst_unit_bits($2); }
153ad30f8e7SGabor Kovesdan oob_mode	: R_OOB_MODE oob_mode_sel { set_oob_mode($2); }
154ad30f8e7SGabor Kovesdan 
155ad30f8e7SGabor Kovesdan oob_mode_sel	: R_INVALID { $$ = _CITRUS_MAPPER_STD_OOB_NONIDENTICAL; }
156ad30f8e7SGabor Kovesdan 		| R_ILSEQ { $$ = _CITRUS_MAPPER_STD_OOB_ILSEQ; }
157ad30f8e7SGabor Kovesdan 
158ad30f8e7SGabor Kovesdan mapping		: begin_map map_elems R_END_MAP
159ad30f8e7SGabor Kovesdan begin_map	: R_BEGIN_MAP lns { setup_map(); }
160ad30f8e7SGabor Kovesdan 
161ad30f8e7SGabor Kovesdan map_elems	: /* empty */
162ad30f8e7SGabor Kovesdan 		| map_elems map_elem lns
163ad30f8e7SGabor Kovesdan 
164ad30f8e7SGabor Kovesdan map_elem	: src '=' dst
165ad30f8e7SGabor Kovesdan 		{ store(&$1, $3, 0); }
166ad30f8e7SGabor Kovesdan 		| src '=' L_IMM '-'
167ad30f8e7SGabor Kovesdan 		{ store(&$1, $3, 1); }
168ad30f8e7SGabor Kovesdan dst		: L_IMM
169ad30f8e7SGabor Kovesdan 		{
170ad30f8e7SGabor Kovesdan 			$$ = $1;
171ad30f8e7SGabor Kovesdan 		}
172ad30f8e7SGabor Kovesdan 		| R_INVALID
173ad30f8e7SGabor Kovesdan 		{
174ad30f8e7SGabor Kovesdan 			$$ = dst_invalid;
175ad30f8e7SGabor Kovesdan 		}
176ad30f8e7SGabor Kovesdan 		| R_ILSEQ
177ad30f8e7SGabor Kovesdan 		{
178ad30f8e7SGabor Kovesdan 			$$ = dst_ilseq;
179ad30f8e7SGabor Kovesdan 		}
180ad30f8e7SGabor Kovesdan 
181ad30f8e7SGabor Kovesdan src		: /* empty */
182ad30f8e7SGabor Kovesdan 		{
183ad30f8e7SGabor Kovesdan 			set_src(&$$, src_next, src_next);
184ad30f8e7SGabor Kovesdan 		}
185ad30f8e7SGabor Kovesdan 		| L_IMM
186ad30f8e7SGabor Kovesdan 		{
187ad30f8e7SGabor Kovesdan 			set_src(&$$, $1, $1);
188ad30f8e7SGabor Kovesdan 		}
189ad30f8e7SGabor Kovesdan 		| L_IMM '-' L_IMM
190ad30f8e7SGabor Kovesdan 		{
191ad30f8e7SGabor Kovesdan 			set_src(&$$, $1, $3);
192ad30f8e7SGabor Kovesdan 		}
193ad30f8e7SGabor Kovesdan 		| '-' L_IMM
194ad30f8e7SGabor Kovesdan 		{
195ad30f8e7SGabor Kovesdan 			set_src(&$$, src_next, $2);
196ad30f8e7SGabor Kovesdan 		}
197ad30f8e7SGabor Kovesdan lns		: R_LN
198ad30f8e7SGabor Kovesdan 		| lns R_LN
199ad30f8e7SGabor Kovesdan 
200ad30f8e7SGabor Kovesdan %%
201ad30f8e7SGabor Kovesdan 
202ad30f8e7SGabor Kovesdan static void
203ad30f8e7SGabor Kovesdan warning(const char *s)
204ad30f8e7SGabor Kovesdan {
205ad30f8e7SGabor Kovesdan 
206af8e44c8SEd Schouten 	fprintf(stderr, "%s in %d\n", s, linenumber);
207ad30f8e7SGabor Kovesdan }
208ad30f8e7SGabor Kovesdan 
209ad30f8e7SGabor Kovesdan int
yyerror(const char * s)210ad30f8e7SGabor Kovesdan yyerror(const char *s)
211ad30f8e7SGabor Kovesdan {
212ad30f8e7SGabor Kovesdan 
213ad30f8e7SGabor Kovesdan 	warning(s);
214ad30f8e7SGabor Kovesdan 	exit(1);
215ad30f8e7SGabor Kovesdan }
216ad30f8e7SGabor Kovesdan 
217ad30f8e7SGabor Kovesdan void
put8(void * ptr,size_t ofs,u_int32_t val)218ad30f8e7SGabor Kovesdan put8(void *ptr, size_t ofs, u_int32_t val)
219ad30f8e7SGabor Kovesdan {
220ad30f8e7SGabor Kovesdan 
221ad30f8e7SGabor Kovesdan 	*((u_int8_t *)ptr + ofs) = val;
222ad30f8e7SGabor Kovesdan }
223ad30f8e7SGabor Kovesdan 
224ad30f8e7SGabor Kovesdan void
put16(void * ptr,size_t ofs,u_int32_t val)225ad30f8e7SGabor Kovesdan put16(void *ptr, size_t ofs, u_int32_t val)
226ad30f8e7SGabor Kovesdan {
227ad30f8e7SGabor Kovesdan 
228ad30f8e7SGabor Kovesdan 	u_int16_t oval = htons(val);
229ad30f8e7SGabor Kovesdan 	memcpy((u_int16_t *)ptr + ofs, &oval, 2);
230ad30f8e7SGabor Kovesdan }
231ad30f8e7SGabor Kovesdan 
232ad30f8e7SGabor Kovesdan void
put32(void * ptr,size_t ofs,u_int32_t val)233ad30f8e7SGabor Kovesdan put32(void *ptr, size_t ofs, u_int32_t val)
234ad30f8e7SGabor Kovesdan {
235ad30f8e7SGabor Kovesdan 
236ad30f8e7SGabor Kovesdan 	u_int32_t oval = htonl(val);
237ad30f8e7SGabor Kovesdan 	memcpy((u_int32_t *)ptr + ofs, &oval, 4);
238ad30f8e7SGabor Kovesdan }
239ad30f8e7SGabor Kovesdan 
240ad30f8e7SGabor Kovesdan static void
alloc_table(void)241ad30f8e7SGabor Kovesdan alloc_table(void)
242ad30f8e7SGabor Kovesdan {
243ad30f8e7SGabor Kovesdan 	linear_zone_t *p;
244ad30f8e7SGabor Kovesdan 	size_t i;
245ad30f8e7SGabor Kovesdan 	uint32_t val = 0;
246ad30f8e7SGabor Kovesdan 
247ad30f8e7SGabor Kovesdan 	i = rowcol_len;
248ad30f8e7SGabor Kovesdan 	p = &rowcol[--i];
249ad30f8e7SGabor Kovesdan 	table_size = p->width;
250ad30f8e7SGabor Kovesdan 	while (i > 0) {
251ad30f8e7SGabor Kovesdan 		p = &rowcol[--i];
252ad30f8e7SGabor Kovesdan 		table_size *= p->width;
253ad30f8e7SGabor Kovesdan 	}
254ad30f8e7SGabor Kovesdan 	table = (void *)malloc(table_size * dst_unit_bits / 8);
255ad30f8e7SGabor Kovesdan 	if (table == NULL) {
256ad30f8e7SGabor Kovesdan 		perror("malloc");
257ad30f8e7SGabor Kovesdan 		exit(1);
258ad30f8e7SGabor Kovesdan 	}
259ad30f8e7SGabor Kovesdan 
260ad30f8e7SGabor Kovesdan 	switch (oob_mode) {
261ad30f8e7SGabor Kovesdan 	case _CITRUS_MAPPER_STD_OOB_NONIDENTICAL:
262ad30f8e7SGabor Kovesdan 		val = dst_invalid;
263ad30f8e7SGabor Kovesdan 		break;
264ad30f8e7SGabor Kovesdan 	case _CITRUS_MAPPER_STD_OOB_ILSEQ:
265ad30f8e7SGabor Kovesdan 		val = dst_ilseq;
266ad30f8e7SGabor Kovesdan 		break;
267ad30f8e7SGabor Kovesdan 	default:
268ad30f8e7SGabor Kovesdan 		break;
269ad30f8e7SGabor Kovesdan 	}
270ad30f8e7SGabor Kovesdan 	for (i = 0; i < table_size; i++)
271ad30f8e7SGabor Kovesdan 		(*putfunc)(table, i, val);
272ad30f8e7SGabor Kovesdan }
273ad30f8e7SGabor Kovesdan 
274ad30f8e7SGabor Kovesdan static void
setup_map(void)275ad30f8e7SGabor Kovesdan setup_map(void)
276ad30f8e7SGabor Kovesdan {
277ad30f8e7SGabor Kovesdan 
278ad30f8e7SGabor Kovesdan 	if ((done_flag & DF_SRC_ZONE)==0) {
279ad30f8e7SGabor Kovesdan 		fprintf(stderr, "SRC_ZONE is mandatory.\n");
280ad30f8e7SGabor Kovesdan 		exit(1);
281ad30f8e7SGabor Kovesdan 	}
282ad30f8e7SGabor Kovesdan 	if ((done_flag & DF_DST_UNIT_BITS)==0) {
283ad30f8e7SGabor Kovesdan 		fprintf(stderr, "DST_UNIT_BITS is mandatory.\n");
284ad30f8e7SGabor Kovesdan 		exit(1);
285ad30f8e7SGabor Kovesdan 	}
286ad30f8e7SGabor Kovesdan 
287ad30f8e7SGabor Kovesdan 	if ((done_flag & DF_DST_INVALID) == 0)
288ad30f8e7SGabor Kovesdan 		dst_invalid = 0xFFFFFFFF;
289ad30f8e7SGabor Kovesdan 	if ((done_flag & DF_DST_ILSEQ) == 0)
290ad30f8e7SGabor Kovesdan 		dst_ilseq = 0xFFFFFFFE;
291ad30f8e7SGabor Kovesdan 	if ((done_flag & DF_OOB_MODE) == 0)
292ad30f8e7SGabor Kovesdan 		oob_mode = _CITRUS_MAPPER_STD_OOB_NONIDENTICAL;
293ad30f8e7SGabor Kovesdan 
294ad30f8e7SGabor Kovesdan 	alloc_table();
295ad30f8e7SGabor Kovesdan }
296ad30f8e7SGabor Kovesdan 
297ad30f8e7SGabor Kovesdan static void
create_rowcol_info(struct _region * r)298ad30f8e7SGabor Kovesdan create_rowcol_info(struct _region *r)
299ad30f8e7SGabor Kovesdan {
300ad30f8e7SGabor Kovesdan 	void *ptr;
301ad30f8e7SGabor Kovesdan 	size_t i, len, ofs;
302ad30f8e7SGabor Kovesdan 
303ad30f8e7SGabor Kovesdan 	ofs = 0;
304ad30f8e7SGabor Kovesdan 	ptr = malloc(_CITRUS_MAPPER_STD_ROWCOL_INFO_SIZE);
305ad30f8e7SGabor Kovesdan 	if (ptr == NULL)
306ad30f8e7SGabor Kovesdan 		err(EXIT_FAILURE, "malloc");
307ad30f8e7SGabor Kovesdan 	put32(ptr, ofs, rowcol_bits); ofs++;
308ad30f8e7SGabor Kovesdan 	put32(ptr, ofs, dst_invalid); ofs++;
309ad30f8e7SGabor Kovesdan 
310ad30f8e7SGabor Kovesdan 	/* XXX: keep backward compatibility */
311ad30f8e7SGabor Kovesdan 	switch (rowcol_len) {
312ad30f8e7SGabor Kovesdan 	case 1:
313ad30f8e7SGabor Kovesdan 		put32(ptr, ofs, 0); ofs++;
314ad30f8e7SGabor Kovesdan 		put32(ptr, ofs, 0); ofs++;
315ad30f8e7SGabor Kovesdan 	/*FALLTHROUGH*/
316ad30f8e7SGabor Kovesdan 	case 2:
317ad30f8e7SGabor Kovesdan 		len = 0;
318ad30f8e7SGabor Kovesdan 		break;
319ad30f8e7SGabor Kovesdan 	default:
320ad30f8e7SGabor Kovesdan 		len = rowcol_len;
321ad30f8e7SGabor Kovesdan 	}
322ad30f8e7SGabor Kovesdan 	for (i = 0; i < rowcol_len; ++i) {
323ad30f8e7SGabor Kovesdan 		put32(ptr, ofs, rowcol[i].begin); ofs++;
324ad30f8e7SGabor Kovesdan 		put32(ptr, ofs, rowcol[i].end); ofs++;
325ad30f8e7SGabor Kovesdan 	}
326ad30f8e7SGabor Kovesdan 	put32(ptr, ofs, dst_unit_bits); ofs++;
327ad30f8e7SGabor Kovesdan 	put32(ptr, ofs, len); ofs++;
328ad30f8e7SGabor Kovesdan 
329ad30f8e7SGabor Kovesdan 	_region_init(r, ptr, ofs * 4);
330ad30f8e7SGabor Kovesdan }
331ad30f8e7SGabor Kovesdan 
332ad30f8e7SGabor Kovesdan 
333ad30f8e7SGabor Kovesdan static void
create_rowcol_ext_ilseq_info(struct _region * r)334ad30f8e7SGabor Kovesdan create_rowcol_ext_ilseq_info(struct _region *r)
335ad30f8e7SGabor Kovesdan {
336ad30f8e7SGabor Kovesdan 	void *ptr;
337ad30f8e7SGabor Kovesdan 	size_t ofs;
338ad30f8e7SGabor Kovesdan 
339ad30f8e7SGabor Kovesdan 	ofs = 0;
340ad30f8e7SGabor Kovesdan 	ptr = malloc(_CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE);
341ad30f8e7SGabor Kovesdan 	if (ptr == NULL)
342ad30f8e7SGabor Kovesdan 		err(EXIT_FAILURE, "malloc");
343ad30f8e7SGabor Kovesdan 
344ad30f8e7SGabor Kovesdan 	put32(ptr, ofs, oob_mode); ofs++;
345ad30f8e7SGabor Kovesdan 	put32(ptr, ofs, dst_ilseq); ofs++;
346ad30f8e7SGabor Kovesdan 
347ad30f8e7SGabor Kovesdan 	_region_init(r, ptr, _CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE);
348ad30f8e7SGabor Kovesdan }
349ad30f8e7SGabor Kovesdan 
350ad30f8e7SGabor Kovesdan #define CHKERR(ret, func, a)						\
351ad30f8e7SGabor Kovesdan do {									\
352ad30f8e7SGabor Kovesdan 	ret = func a;							\
353ad30f8e7SGabor Kovesdan 	if (ret)							\
354ad30f8e7SGabor Kovesdan 		errx(EXIT_FAILURE, "%s: %s", #func, strerror(ret));	\
355ad30f8e7SGabor Kovesdan } while (/*CONSTCOND*/0)
356ad30f8e7SGabor Kovesdan 
357ad30f8e7SGabor Kovesdan static void
dump_file(void)358ad30f8e7SGabor Kovesdan dump_file(void)
359ad30f8e7SGabor Kovesdan {
360ad30f8e7SGabor Kovesdan 	struct _db_factory *df;
361ad30f8e7SGabor Kovesdan 	struct _region data;
362ad30f8e7SGabor Kovesdan 	void *serialized;
363ad30f8e7SGabor Kovesdan 	FILE *fp;
364ad30f8e7SGabor Kovesdan 	size_t size;
365ad30f8e7SGabor Kovesdan 	int ret;
366ad30f8e7SGabor Kovesdan 
367ad30f8e7SGabor Kovesdan 	/*
368ad30f8e7SGabor Kovesdan 	 * build database
369ad30f8e7SGabor Kovesdan 	 */
370ad30f8e7SGabor Kovesdan 	CHKERR(ret, _db_factory_create, (&df, _db_hash_std, NULL));
371ad30f8e7SGabor Kovesdan 
372ad30f8e7SGabor Kovesdan 	/* store type */
373ad30f8e7SGabor Kovesdan 	CHKERR(ret, _db_factory_addstr_by_s,
374ad30f8e7SGabor Kovesdan 	    (df, _CITRUS_MAPPER_STD_SYM_TYPE, _CITRUS_MAPPER_STD_TYPE_ROWCOL));
375ad30f8e7SGabor Kovesdan 
376ad30f8e7SGabor Kovesdan 	/* store info */
377ad30f8e7SGabor Kovesdan 	create_rowcol_info(&data);
378ad30f8e7SGabor Kovesdan 	CHKERR(ret, _db_factory_add_by_s,
379ad30f8e7SGabor Kovesdan 	    (df, _CITRUS_MAPPER_STD_SYM_INFO, &data, 1));
380ad30f8e7SGabor Kovesdan 
381ad30f8e7SGabor Kovesdan 	/* ilseq extension */
382ad30f8e7SGabor Kovesdan 	create_rowcol_ext_ilseq_info(&data);
383ad30f8e7SGabor Kovesdan 	CHKERR(ret, _db_factory_add_by_s,
384ad30f8e7SGabor Kovesdan 	    (df, _CITRUS_MAPPER_STD_SYM_ROWCOL_EXT_ILSEQ, &data, 1));
385ad30f8e7SGabor Kovesdan 
386ad30f8e7SGabor Kovesdan 	/* store table */
387ad30f8e7SGabor Kovesdan 	_region_init(&data, table, table_size*dst_unit_bits/8);
388ad30f8e7SGabor Kovesdan 	CHKERR(ret, _db_factory_add_by_s,
389ad30f8e7SGabor Kovesdan 	    (df, _CITRUS_MAPPER_STD_SYM_TABLE, &data, 1));
390ad30f8e7SGabor Kovesdan 
391ad30f8e7SGabor Kovesdan 	/*
392ad30f8e7SGabor Kovesdan 	 * dump database to file
393ad30f8e7SGabor Kovesdan 	 */
394ad30f8e7SGabor Kovesdan 	fp = output ? fopen(output, "wb") : stdout;
395ad30f8e7SGabor Kovesdan 
396ad30f8e7SGabor Kovesdan 	if (fp == NULL) {
397ad30f8e7SGabor Kovesdan 		perror("fopen");
398ad30f8e7SGabor Kovesdan 		exit(1);
399ad30f8e7SGabor Kovesdan 	}
400ad30f8e7SGabor Kovesdan 
401ad30f8e7SGabor Kovesdan 	/* dump database body */
402ad30f8e7SGabor Kovesdan 	size = _db_factory_calc_size(df);
403ad30f8e7SGabor Kovesdan 	serialized = malloc(size);
404ad30f8e7SGabor Kovesdan 	_region_init(&data, serialized, size);
405ad30f8e7SGabor Kovesdan 	CHKERR(ret, _db_factory_serialize,
406ad30f8e7SGabor Kovesdan 	    (df, _CITRUS_MAPPER_STD_MAGIC, &data));
407ad30f8e7SGabor Kovesdan 	if (fwrite(serialized, size, 1, fp) != 1)
408ad30f8e7SGabor Kovesdan 		err(EXIT_FAILURE, "fwrite");
409ad30f8e7SGabor Kovesdan 
410ad30f8e7SGabor Kovesdan 	fclose(fp);
411ad30f8e7SGabor Kovesdan }
412ad30f8e7SGabor Kovesdan 
413ad30f8e7SGabor Kovesdan static void
414ad30f8e7SGabor Kovesdan /*ARGSUSED*/
set_type(int type)415ad30f8e7SGabor Kovesdan set_type(int type)
416ad30f8e7SGabor Kovesdan {
417ad30f8e7SGabor Kovesdan 
418ad30f8e7SGabor Kovesdan 	if (done_flag & DF_TYPE) {
419ad30f8e7SGabor Kovesdan 		warning("TYPE is duplicated. ignored this one");
420ad30f8e7SGabor Kovesdan 		return;
421ad30f8e7SGabor Kovesdan 	}
422ad30f8e7SGabor Kovesdan 
423ad30f8e7SGabor Kovesdan 	map_type = type;
424ad30f8e7SGabor Kovesdan 
425ad30f8e7SGabor Kovesdan 	done_flag |= DF_TYPE;
426ad30f8e7SGabor Kovesdan }
427ad30f8e7SGabor Kovesdan 
428ad30f8e7SGabor Kovesdan static void
429ad30f8e7SGabor Kovesdan /*ARGSUSED*/
set_name(char * str)430ad30f8e7SGabor Kovesdan set_name(char *str)
431ad30f8e7SGabor Kovesdan {
432ad30f8e7SGabor Kovesdan 
433ad30f8e7SGabor Kovesdan 	if (done_flag & DF_NAME) {
434ad30f8e7SGabor Kovesdan 		warning("NAME is duplicated. ignored this one");
435ad30f8e7SGabor Kovesdan 		return;
436ad30f8e7SGabor Kovesdan 	}
437ad30f8e7SGabor Kovesdan 
438ad30f8e7SGabor Kovesdan 	map_name = str;
439ad30f8e7SGabor Kovesdan 
440ad30f8e7SGabor Kovesdan 	done_flag |= DF_NAME;
441ad30f8e7SGabor Kovesdan }
442ad30f8e7SGabor Kovesdan 
443ad30f8e7SGabor Kovesdan static void
set_src_zone(u_int32_t val)444ad30f8e7SGabor Kovesdan set_src_zone(u_int32_t val)
445ad30f8e7SGabor Kovesdan {
446ad30f8e7SGabor Kovesdan 	linear_zone_t *p;
447ad30f8e7SGabor Kovesdan 	size_t i;
448ad30f8e7SGabor Kovesdan 
449ad30f8e7SGabor Kovesdan 	if (done_flag & DF_SRC_ZONE) {
450ad30f8e7SGabor Kovesdan 		warning("SRC_ZONE is duplicated. ignored this one");
451ad30f8e7SGabor Kovesdan 		return;
452ad30f8e7SGabor Kovesdan 	}
453ad30f8e7SGabor Kovesdan 	rowcol_bits = val;
454ad30f8e7SGabor Kovesdan 
455ad30f8e7SGabor Kovesdan 	/* sanity check */
456ad30f8e7SGabor Kovesdan 	switch (rowcol_bits) {
457ad30f8e7SGabor Kovesdan 	case 8: case 16: case 32:
458ad30f8e7SGabor Kovesdan 		if (rowcol_len <= 32 / rowcol_bits)
459ad30f8e7SGabor Kovesdan 			break;
460ad30f8e7SGabor Kovesdan 	/*FALLTHROUGH*/
461ad30f8e7SGabor Kovesdan 	default:
462ad30f8e7SGabor Kovesdan 		goto bad;
463ad30f8e7SGabor Kovesdan 	}
464*335770acSAlex Richardson 	rowcol_mask = 1u << (rowcol_bits - 1);
465ad30f8e7SGabor Kovesdan 	rowcol_mask |= rowcol_mask - 1;
466ad30f8e7SGabor Kovesdan 	for (i = 0; i < rowcol_len; ++i) {
467ad30f8e7SGabor Kovesdan 		p = &rowcol[i];
468ad30f8e7SGabor Kovesdan 		if (p->end > rowcol_mask)
469ad30f8e7SGabor Kovesdan 			goto bad;
470ad30f8e7SGabor Kovesdan 	}
471ad30f8e7SGabor Kovesdan 	done_flag |= DF_SRC_ZONE;
472ad30f8e7SGabor Kovesdan 	return;
473ad30f8e7SGabor Kovesdan 
474ad30f8e7SGabor Kovesdan bad:
475ad30f8e7SGabor Kovesdan 	yyerror("Illegal argument for SRC_ZONE");
476ad30f8e7SGabor Kovesdan }
477ad30f8e7SGabor Kovesdan 
478ad30f8e7SGabor Kovesdan static void
set_dst_invalid(u_int32_t val)479ad30f8e7SGabor Kovesdan set_dst_invalid(u_int32_t val)
480ad30f8e7SGabor Kovesdan {
481ad30f8e7SGabor Kovesdan 
482ad30f8e7SGabor Kovesdan 	if (done_flag & DF_DST_INVALID) {
483ad30f8e7SGabor Kovesdan 		warning("DST_INVALID is duplicated. ignored this one");
484ad30f8e7SGabor Kovesdan 		return;
485ad30f8e7SGabor Kovesdan 	}
486ad30f8e7SGabor Kovesdan 
487ad30f8e7SGabor Kovesdan 	dst_invalid = val;
488ad30f8e7SGabor Kovesdan 
489ad30f8e7SGabor Kovesdan 	done_flag |= DF_DST_INVALID;
490ad30f8e7SGabor Kovesdan }
491ad30f8e7SGabor Kovesdan 
492ad30f8e7SGabor Kovesdan static void
set_dst_ilseq(u_int32_t val)493ad30f8e7SGabor Kovesdan set_dst_ilseq(u_int32_t val)
494ad30f8e7SGabor Kovesdan {
495ad30f8e7SGabor Kovesdan 
496ad30f8e7SGabor Kovesdan 	if (done_flag & DF_DST_ILSEQ) {
497ad30f8e7SGabor Kovesdan 		warning("DST_ILSEQ is duplicated. ignored this one");
498ad30f8e7SGabor Kovesdan 		return;
499ad30f8e7SGabor Kovesdan 	}
500ad30f8e7SGabor Kovesdan 
501ad30f8e7SGabor Kovesdan 	dst_ilseq = val;
502ad30f8e7SGabor Kovesdan 
503ad30f8e7SGabor Kovesdan 	done_flag |= DF_DST_ILSEQ;
504ad30f8e7SGabor Kovesdan }
505ad30f8e7SGabor Kovesdan 
506ad30f8e7SGabor Kovesdan static void
set_oob_mode(u_int32_t val)507ad30f8e7SGabor Kovesdan set_oob_mode(u_int32_t val)
508ad30f8e7SGabor Kovesdan {
509ad30f8e7SGabor Kovesdan 
510ad30f8e7SGabor Kovesdan 	if (done_flag & DF_OOB_MODE) {
511ad30f8e7SGabor Kovesdan 		warning("OOB_MODE is duplicated. ignored this one");
512ad30f8e7SGabor Kovesdan 		return;
513ad30f8e7SGabor Kovesdan 	}
514ad30f8e7SGabor Kovesdan 
515ad30f8e7SGabor Kovesdan 	oob_mode = val;
516ad30f8e7SGabor Kovesdan 
517ad30f8e7SGabor Kovesdan 	done_flag |= DF_OOB_MODE;
518ad30f8e7SGabor Kovesdan }
519ad30f8e7SGabor Kovesdan 
520ad30f8e7SGabor Kovesdan static void
set_dst_unit_bits(u_int32_t val)521ad30f8e7SGabor Kovesdan set_dst_unit_bits(u_int32_t val)
522ad30f8e7SGabor Kovesdan {
523ad30f8e7SGabor Kovesdan 
524ad30f8e7SGabor Kovesdan 	if (done_flag & DF_DST_UNIT_BITS) {
525ad30f8e7SGabor Kovesdan 		warning("DST_UNIT_BITS is duplicated. ignored this one");
526ad30f8e7SGabor Kovesdan 		return;
527ad30f8e7SGabor Kovesdan 	}
528ad30f8e7SGabor Kovesdan 
529ad30f8e7SGabor Kovesdan 	switch (val) {
530ad30f8e7SGabor Kovesdan 	case 8:
531ad30f8e7SGabor Kovesdan 		putfunc = &put8;
532ad30f8e7SGabor Kovesdan 		dst_unit_bits = val;
533ad30f8e7SGabor Kovesdan 		break;
534ad30f8e7SGabor Kovesdan 	case 16:
535ad30f8e7SGabor Kovesdan 		putfunc = &put16;
536ad30f8e7SGabor Kovesdan 		dst_unit_bits = val;
537ad30f8e7SGabor Kovesdan 		break;
538ad30f8e7SGabor Kovesdan 	case 32:
539ad30f8e7SGabor Kovesdan 		putfunc = &put32;
540ad30f8e7SGabor Kovesdan 		dst_unit_bits = val;
541ad30f8e7SGabor Kovesdan 		break;
542ad30f8e7SGabor Kovesdan 	default:
543ad30f8e7SGabor Kovesdan 		yyerror("Illegal argument for DST_UNIT_BITS");
544ad30f8e7SGabor Kovesdan 	}
545ad30f8e7SGabor Kovesdan 	done_flag |= DF_DST_UNIT_BITS;
546ad30f8e7SGabor Kovesdan }
547ad30f8e7SGabor Kovesdan 
548ad30f8e7SGabor Kovesdan static int
check_src(u_int32_t begin,u_int32_t end)549ad30f8e7SGabor Kovesdan check_src(u_int32_t begin, u_int32_t end)
550ad30f8e7SGabor Kovesdan {
551ad30f8e7SGabor Kovesdan 	linear_zone_t *p;
552ad30f8e7SGabor Kovesdan 	size_t i;
553ad30f8e7SGabor Kovesdan 	u_int32_t m, n;
554ad30f8e7SGabor Kovesdan 
555ad30f8e7SGabor Kovesdan 	if (begin > end)
556ad30f8e7SGabor Kovesdan 		return (1);
557ad30f8e7SGabor Kovesdan 	if (begin < end) {
558ad30f8e7SGabor Kovesdan 		m = begin & ~rowcol_mask;
559ad30f8e7SGabor Kovesdan 		n = end & ~rowcol_mask;
560ad30f8e7SGabor Kovesdan 		if (m != n)
561ad30f8e7SGabor Kovesdan 			return (1);
562ad30f8e7SGabor Kovesdan 	}
563ad30f8e7SGabor Kovesdan 	for (i = rowcol_len * rowcol_bits, p = &rowcol[0]; i > 0; ++p) {
564ad30f8e7SGabor Kovesdan 		i -= rowcol_bits;
565ad30f8e7SGabor Kovesdan 		m = (begin >> i) & rowcol_mask;
566ad30f8e7SGabor Kovesdan 		if (m < p->begin || m > p->end)
567ad30f8e7SGabor Kovesdan 			return (1);
568ad30f8e7SGabor Kovesdan 	}
569ad30f8e7SGabor Kovesdan 	if (begin < end) {
570ad30f8e7SGabor Kovesdan 		n = end & rowcol_mask;
571ad30f8e7SGabor Kovesdan 		--p;
572ad30f8e7SGabor Kovesdan 		if (n < p->begin || n > p->end)
573ad30f8e7SGabor Kovesdan 			return (1);
574ad30f8e7SGabor Kovesdan 	}
575ad30f8e7SGabor Kovesdan 	return (0);
576ad30f8e7SGabor Kovesdan }
577ad30f8e7SGabor Kovesdan 
578ad30f8e7SGabor Kovesdan static void
store(const linear_zone_t * lz,u_int32_t dst,int inc)579ad30f8e7SGabor Kovesdan store(const linear_zone_t *lz, u_int32_t dst, int inc)
580ad30f8e7SGabor Kovesdan {
581ad30f8e7SGabor Kovesdan 	linear_zone_t *p;
582ad30f8e7SGabor Kovesdan 	size_t i, ofs;
583ad30f8e7SGabor Kovesdan 	u_int32_t n;
584ad30f8e7SGabor Kovesdan 
585ad30f8e7SGabor Kovesdan 	ofs = 0;
586ad30f8e7SGabor Kovesdan 	for (i = rowcol_len * rowcol_bits, p = &rowcol[0]; i > 0; ++p) {
587ad30f8e7SGabor Kovesdan 		i -= rowcol_bits;
588ad30f8e7SGabor Kovesdan 		n = ((lz->begin >> i) & rowcol_mask) - p->begin;
589ad30f8e7SGabor Kovesdan 		ofs = (ofs * p->width) + n;
590ad30f8e7SGabor Kovesdan 	}
591ad30f8e7SGabor Kovesdan 	n = lz->width;
592ad30f8e7SGabor Kovesdan 	while (n-- > 0) {
593ad30f8e7SGabor Kovesdan 		(*putfunc)(table, ofs++, dst);
594ad30f8e7SGabor Kovesdan 		if (inc)
595ad30f8e7SGabor Kovesdan 			dst++;
596ad30f8e7SGabor Kovesdan 	}
597ad30f8e7SGabor Kovesdan }
598ad30f8e7SGabor Kovesdan 
599ad30f8e7SGabor Kovesdan static void
set_range(u_int32_t begin,u_int32_t end)600ad30f8e7SGabor Kovesdan set_range(u_int32_t begin, u_int32_t end)
601ad30f8e7SGabor Kovesdan {
602ad30f8e7SGabor Kovesdan 	linear_zone_t *p;
603ad30f8e7SGabor Kovesdan 
604ad30f8e7SGabor Kovesdan 	if (rowcol_len >= _CITRUS_MAPPER_STD_ROWCOL_MAX)
605ad30f8e7SGabor Kovesdan 		goto bad;
606ad30f8e7SGabor Kovesdan 	p = &rowcol[rowcol_len++];
607ad30f8e7SGabor Kovesdan 
608ad30f8e7SGabor Kovesdan 	if (begin > end)
609ad30f8e7SGabor Kovesdan 		goto bad;
610ad30f8e7SGabor Kovesdan 	p->begin = begin, p->end = end;
611ad30f8e7SGabor Kovesdan 	p->width = end - begin + 1;
612ad30f8e7SGabor Kovesdan 
613ad30f8e7SGabor Kovesdan 	return;
614ad30f8e7SGabor Kovesdan 
615ad30f8e7SGabor Kovesdan bad:
616ad30f8e7SGabor Kovesdan 	yyerror("Illegal argument for SRC_ZONE");
617ad30f8e7SGabor Kovesdan }
618ad30f8e7SGabor Kovesdan 
619ad30f8e7SGabor Kovesdan static void
set_src(linear_zone_t * lz,u_int32_t begin,u_int32_t end)620ad30f8e7SGabor Kovesdan set_src(linear_zone_t *lz, u_int32_t begin, u_int32_t end)
621ad30f8e7SGabor Kovesdan {
622ad30f8e7SGabor Kovesdan 
623ad30f8e7SGabor Kovesdan 	if (check_src(begin, end) != 0)
624ad30f8e7SGabor Kovesdan 		yyerror("illegal zone");
625ad30f8e7SGabor Kovesdan 
626ad30f8e7SGabor Kovesdan 	lz->begin = begin, lz->end = end;
627ad30f8e7SGabor Kovesdan 	lz->width = end - begin + 1;
628ad30f8e7SGabor Kovesdan 
629ad30f8e7SGabor Kovesdan 	src_next = end + 1;
630ad30f8e7SGabor Kovesdan }
631ad30f8e7SGabor Kovesdan 
632ad30f8e7SGabor Kovesdan static void
do_mkdb(FILE * in)633ad30f8e7SGabor Kovesdan do_mkdb(FILE *in)
634ad30f8e7SGabor Kovesdan {
635ad30f8e7SGabor Kovesdan 	FILE *out;
636ad30f8e7SGabor Kovesdan 	int ret;
637ad30f8e7SGabor Kovesdan 
638ad30f8e7SGabor Kovesdan         /* dump DB to file */
639ad30f8e7SGabor Kovesdan 	out = output ? fopen(output, "wb") : stdout;
640ad30f8e7SGabor Kovesdan 
641ad30f8e7SGabor Kovesdan 	if (out == NULL)
642ad30f8e7SGabor Kovesdan 		err(EXIT_FAILURE, "fopen");
643ad30f8e7SGabor Kovesdan 
644ad30f8e7SGabor Kovesdan 	ret = _lookup_factory_convert(out, in);
645ad30f8e7SGabor Kovesdan 	fclose(out);
646ad30f8e7SGabor Kovesdan 	if (ret && output)
647ad30f8e7SGabor Kovesdan 		unlink(output); /* dump failure */
648ad30f8e7SGabor Kovesdan }
649ad30f8e7SGabor Kovesdan 
650ad30f8e7SGabor Kovesdan static void
do_mkpv(FILE * in)651ad30f8e7SGabor Kovesdan do_mkpv(FILE *in)
652ad30f8e7SGabor Kovesdan {
653ad30f8e7SGabor Kovesdan 	FILE *out;
654ad30f8e7SGabor Kovesdan 	int ret;
655ad30f8e7SGabor Kovesdan 
656ad30f8e7SGabor Kovesdan         /* dump pivot to file */
657ad30f8e7SGabor Kovesdan 	out = output ? fopen(output, "wb") : stdout;
658ad30f8e7SGabor Kovesdan 
659ad30f8e7SGabor Kovesdan 	if (out == NULL)
660ad30f8e7SGabor Kovesdan 		err(EXIT_FAILURE, "fopen");
661ad30f8e7SGabor Kovesdan 
662ad30f8e7SGabor Kovesdan 	ret = _pivot_factory_convert(out, in);
663ad30f8e7SGabor Kovesdan 	fclose(out);
664ad30f8e7SGabor Kovesdan 	if (ret && output)
665ad30f8e7SGabor Kovesdan 		unlink(output); /* dump failure */
666ad30f8e7SGabor Kovesdan 	if (ret)
6670833e924SBaptiste Daroussin 		errx(EXIT_FAILURE, "%s\n", strerror(ret));
668ad30f8e7SGabor Kovesdan }
669ad30f8e7SGabor Kovesdan 
670ad30f8e7SGabor Kovesdan static void
usage(void)671ad30f8e7SGabor Kovesdan usage(void)
672ad30f8e7SGabor Kovesdan {
673aa0bf3d6SBaptiste Daroussin 	fprintf(stderr, "Usage: %s [-d] [-m|-p] [-o outfile] [infile]\n",
674aa0bf3d6SBaptiste Daroussin 	    getprogname());
675aa0bf3d6SBaptiste Daroussin 	exit(EXIT_FAILURE);
676ad30f8e7SGabor Kovesdan }
677ad30f8e7SGabor Kovesdan 
678ad30f8e7SGabor Kovesdan int
main(int argc,char ** argv)679ad30f8e7SGabor Kovesdan main(int argc, char **argv)
680ad30f8e7SGabor Kovesdan {
681ad30f8e7SGabor Kovesdan 	FILE *in = NULL;
682ad30f8e7SGabor Kovesdan 	int ch, mkdb = 0, mkpv = 0;
683ad30f8e7SGabor Kovesdan 
684ad30f8e7SGabor Kovesdan 	while ((ch = getopt(argc, argv, "do:mp")) != EOF) {
685ad30f8e7SGabor Kovesdan 		switch (ch) {
686ad30f8e7SGabor Kovesdan 		case 'd':
687ad30f8e7SGabor Kovesdan 			debug = 1;
688ad30f8e7SGabor Kovesdan 			break;
689ad30f8e7SGabor Kovesdan 		case 'o':
690ad30f8e7SGabor Kovesdan 			output = strdup(optarg);
691ad30f8e7SGabor Kovesdan 			break;
692ad30f8e7SGabor Kovesdan 		case 'm':
693ad30f8e7SGabor Kovesdan 			mkdb = 1;
694ad30f8e7SGabor Kovesdan 			break;
695ad30f8e7SGabor Kovesdan 		case 'p':
696ad30f8e7SGabor Kovesdan 			mkpv = 1;
697ad30f8e7SGabor Kovesdan 			break;
698ad30f8e7SGabor Kovesdan 		default:
699ad30f8e7SGabor Kovesdan 			usage();
700ad30f8e7SGabor Kovesdan 		}
701ad30f8e7SGabor Kovesdan 	}
702ad30f8e7SGabor Kovesdan 
703ad30f8e7SGabor Kovesdan 	argc -= optind;
704ad30f8e7SGabor Kovesdan 	argv += optind;
705ad30f8e7SGabor Kovesdan 	switch (argc) {
706ad30f8e7SGabor Kovesdan 	case 0:
707ad30f8e7SGabor Kovesdan 		in = stdin;
708ad30f8e7SGabor Kovesdan 		break;
709ad30f8e7SGabor Kovesdan 	case 1:
710ad30f8e7SGabor Kovesdan 		in = fopen(argv[0], "r");
711ad30f8e7SGabor Kovesdan 		if (!in)
712ad30f8e7SGabor Kovesdan 			err(EXIT_FAILURE, "%s", argv[0]);
713ad30f8e7SGabor Kovesdan 		break;
714ad30f8e7SGabor Kovesdan 	default:
715ad30f8e7SGabor Kovesdan 		usage();
716ad30f8e7SGabor Kovesdan 	}
717ad30f8e7SGabor Kovesdan 
718ad30f8e7SGabor Kovesdan 	if (mkdb)
719ad30f8e7SGabor Kovesdan 		do_mkdb(in);
720ad30f8e7SGabor Kovesdan 	else if (mkpv)
721ad30f8e7SGabor Kovesdan 		do_mkpv(in);
722ad30f8e7SGabor Kovesdan 	else {
723ad30f8e7SGabor Kovesdan 		yyin = in;
724ad30f8e7SGabor Kovesdan 		yyparse();
725ad30f8e7SGabor Kovesdan 	}
726ad30f8e7SGabor Kovesdan 
727ad30f8e7SGabor Kovesdan 	return (0);
728ad30f8e7SGabor Kovesdan }
729