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