1219019Sgabor/* $FreeBSD: stable/11/usr.bin/mkcsmapper/yacc.y 330449 2018-03-05 07:26:05Z eadler $ */ 2307794Sbapt/* $NetBSD: yacc.y,v 1.11 2016/06/28 09:22:16 wiz Exp $ */ 3219019Sgabor 4219019Sgabor%{ 5219019Sgabor/*- 6330449Seadler * SPDX-License-Identifier: BSD-2-Clause 7330449Seadler * 8219019Sgabor * Copyright (c)2003, 2006 Citrus Project, 9219019Sgabor * All rights reserved. 10219019Sgabor * 11219019Sgabor * Redistribution and use in source and binary forms, with or without 12219019Sgabor * modification, are permitted provided that the following conditions 13219019Sgabor * are met: 14219019Sgabor * 1. Redistributions of source code must retain the above copyright 15219019Sgabor * notice, this list of conditions and the following disclaimer. 16219019Sgabor * 2. Redistributions in binary form must reproduce the above copyright 17219019Sgabor * notice, this list of conditions and the following disclaimer in the 18219019Sgabor * documentation and/or other materials provided with the distribution. 19219019Sgabor * 20219019Sgabor * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21219019Sgabor * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22219019Sgabor * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23219019Sgabor * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24219019Sgabor * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25219019Sgabor * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26219019Sgabor * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27219019Sgabor * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28219019Sgabor * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29219019Sgabor * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30219019Sgabor * SUCH DAMAGE. 31219019Sgabor */ 32219019Sgabor 33219019Sgabor#include <sys/cdefs.h> 34219019Sgabor#include <sys/types.h> 35219019Sgabor 36219019Sgabor#include <assert.h> 37219019Sgabor#include <err.h> 38219019Sgabor#include <errno.h> 39219019Sgabor#include <limits.h> 40219019Sgabor#include <stdio.h> 41219019Sgabor#include <stdlib.h> 42219019Sgabor#include <string.h> 43219019Sgabor#include <unistd.h> 44219019Sgabor#include <arpa/inet.h> 45219019Sgabor 46219019Sgabor#include "ldef.h" 47219019Sgabor 48219019Sgabor#ifndef __packed 49219019Sgabor#define __packed 50219019Sgabor#endif 51219019Sgabor 52219019Sgabor#include "citrus_namespace.h" 53219019Sgabor#include "citrus_types.h" 54219019Sgabor#include "citrus_mapper_std_file.h" 55219019Sgabor#include "citrus_region.h" 56219019Sgabor#include "citrus_db_factory.h" 57219019Sgabor#include "citrus_db_hash.h" 58219019Sgabor#include "citrus_lookup_factory.h" 59219019Sgabor#include "citrus_pivot_factory.h" 60219019Sgabor 61219019Sgaborextern FILE *yyin; 62219019Sgabor 63219019Sgaborint debug = 0; 64219019Sgabor 65219019Sgaborstatic linear_zone_t rowcol[_CITRUS_MAPPER_STD_ROWCOL_MAX]; 66219019Sgaborstatic char *map_name; 67219019Sgaborstatic char *output = NULL; 68219019Sgaborstatic void *table = NULL; 69219019Sgaborstatic size_t rowcol_len = 0; 70219019Sgaborstatic size_t table_size; 71219019Sgaborstatic u_int32_t done_flag = 0; 72219019Sgaborstatic u_int32_t dst_ilseq, dst_invalid, dst_unit_bits, oob_mode; 73219019Sgaborstatic u_int32_t rowcol_bits = 0, rowcol_mask = 0; 74219019Sgaborstatic u_int32_t src_next; 75219019Sgaborstatic int map_type; 76219019Sgaborstatic void (*putfunc)(void *, size_t, u_int32_t) = NULL; 77219019Sgabor 78219019Sgabor#define DF_TYPE 0x00000001 79219019Sgabor#define DF_NAME 0x00000002 80219019Sgabor#define DF_SRC_ZONE 0x00000004 81219019Sgabor#define DF_DST_INVALID 0x00000008 82219019Sgabor#define DF_DST_ILSEQ 0x00000010 83219019Sgabor#define DF_DST_UNIT_BITS 0x00000020 84219019Sgabor#define DF_OOB_MODE 0x00000040 85219019Sgabor 86219019Sgaborstatic void dump_file(void); 87219019Sgaborstatic void setup_map(void); 88219019Sgaborstatic void set_type(int); 89219019Sgaborstatic void set_name(char *); 90219019Sgaborstatic void set_src_zone(u_int32_t); 91219019Sgaborstatic void set_dst_invalid(u_int32_t); 92219019Sgaborstatic void set_dst_ilseq(u_int32_t); 93219019Sgaborstatic void set_dst_unit_bits(u_int32_t); 94219019Sgaborstatic void set_oob_mode(u_int32_t); 95219019Sgaborstatic int check_src(u_int32_t, u_int32_t); 96219019Sgaborstatic void store(const linear_zone_t *, u_int32_t, int); 97219019Sgaborstatic void put8(void *, size_t, u_int32_t); 98219019Sgaborstatic void put16(void *, size_t, u_int32_t); 99219019Sgaborstatic void put32(void *, size_t, u_int32_t); 100219019Sgaborstatic void set_range(u_int32_t, u_int32_t); 101219019Sgaborstatic void set_src(linear_zone_t *, u_int32_t, u_int32_t); 102219019Sgabor%} 103219019Sgabor 104219019Sgabor%union { 105219019Sgabor u_int32_t i_value; 106219019Sgabor char *s_value; 107219019Sgabor linear_zone_t lz_value; 108219019Sgabor} 109219019Sgabor 110219019Sgabor%token R_TYPE R_NAME R_SRC_ZONE R_DST_UNIT_BITS 111219019Sgabor%token R_DST_INVALID R_DST_ILSEQ 112219019Sgabor%token R_BEGIN_MAP R_END_MAP R_INVALID R_ROWCOL 113219019Sgabor%token R_ILSEQ R_OOB_MODE 114219019Sgabor%token R_LN 115219019Sgabor%token <i_value> L_IMM 116219019Sgabor%token <s_value> L_STRING 117219019Sgabor 118219019Sgabor%type <lz_value> src 119219019Sgabor%type <i_value> dst types oob_mode_sel zone 120219019Sgabor 121219019Sgabor%% 122219019Sgabor 123219019Sgaborfile : property mapping lns 124219019Sgabor { dump_file(); } 125219019Sgabor 126219019Sgaborproperty : /* empty */ 127219019Sgabor | property R_LN 128219019Sgabor | property name 129219019Sgabor | property type 130219019Sgabor | property src_zone 131219019Sgabor | property dst_invalid 132219019Sgabor | property dst_ilseq 133219019Sgabor | property dst_unit_bits 134219019Sgabor | property oob_mode 135219019Sgabor 136219019Sgaborname : R_NAME L_STRING { set_name($2); $2 = NULL; } 137219019Sgabortype : R_TYPE types { set_type($2); } 138219019Sgabortypes : R_ROWCOL { $$ = R_ROWCOL; } 139219019Sgaborrange : L_IMM '-' L_IMM { set_range($1, $3); } 140219019Sgabor 141219019Sgaborranges : /* empty */ 142219019Sgabor | ranges range '/' 143219019Sgabor 144219019Sgaborsrc_zone : R_SRC_ZONE zone { set_src_zone($2); } 145219019Sgaborzone : range { 146219019Sgabor $$ = 32; 147219019Sgabor } 148219019Sgabor | range '/' range '/' ranges L_IMM { 149219019Sgabor $$ = $6; 150219019Sgabor } 151219019Sgabor 152219019Sgabordst_invalid : R_DST_INVALID L_IMM { set_dst_invalid($2); } 153219019Sgabordst_ilseq : R_DST_ILSEQ L_IMM { set_dst_ilseq($2); } 154219019Sgabordst_unit_bits : R_DST_UNIT_BITS L_IMM { set_dst_unit_bits($2); } 155219019Sgaboroob_mode : R_OOB_MODE oob_mode_sel { set_oob_mode($2); } 156219019Sgabor 157219019Sgaboroob_mode_sel : R_INVALID { $$ = _CITRUS_MAPPER_STD_OOB_NONIDENTICAL; } 158219019Sgabor | R_ILSEQ { $$ = _CITRUS_MAPPER_STD_OOB_ILSEQ; } 159219019Sgabor 160219019Sgabormapping : begin_map map_elems R_END_MAP 161219019Sgaborbegin_map : R_BEGIN_MAP lns { setup_map(); } 162219019Sgabor 163219019Sgabormap_elems : /* empty */ 164219019Sgabor | map_elems map_elem lns 165219019Sgabor 166219019Sgabormap_elem : src '=' dst 167219019Sgabor { store(&$1, $3, 0); } 168219019Sgabor | src '=' L_IMM '-' 169219019Sgabor { store(&$1, $3, 1); } 170219019Sgabordst : L_IMM 171219019Sgabor { 172219019Sgabor $$ = $1; 173219019Sgabor } 174219019Sgabor | R_INVALID 175219019Sgabor { 176219019Sgabor $$ = dst_invalid; 177219019Sgabor } 178219019Sgabor | R_ILSEQ 179219019Sgabor { 180219019Sgabor $$ = dst_ilseq; 181219019Sgabor } 182219019Sgabor 183219019Sgaborsrc : /* empty */ 184219019Sgabor { 185219019Sgabor set_src(&$$, src_next, src_next); 186219019Sgabor } 187219019Sgabor | L_IMM 188219019Sgabor { 189219019Sgabor set_src(&$$, $1, $1); 190219019Sgabor } 191219019Sgabor | L_IMM '-' L_IMM 192219019Sgabor { 193219019Sgabor set_src(&$$, $1, $3); 194219019Sgabor } 195219019Sgabor | '-' L_IMM 196219019Sgabor { 197219019Sgabor set_src(&$$, src_next, $2); 198219019Sgabor } 199219019Sgaborlns : R_LN 200219019Sgabor | lns R_LN 201219019Sgabor 202219019Sgabor%% 203219019Sgabor 204219019Sgaborstatic void 205219019Sgaborwarning(const char *s) 206219019Sgabor{ 207219019Sgabor 208250984Sed fprintf(stderr, "%s in %d\n", s, linenumber); 209219019Sgabor} 210219019Sgabor 211219019Sgaborint 212219019Sgaboryyerror(const char *s) 213219019Sgabor{ 214219019Sgabor 215219019Sgabor warning(s); 216219019Sgabor exit(1); 217219019Sgabor} 218219019Sgabor 219219019Sgaborvoid 220219019Sgaborput8(void *ptr, size_t ofs, u_int32_t val) 221219019Sgabor{ 222219019Sgabor 223219019Sgabor *((u_int8_t *)ptr + ofs) = val; 224219019Sgabor} 225219019Sgabor 226219019Sgaborvoid 227219019Sgaborput16(void *ptr, size_t ofs, u_int32_t val) 228219019Sgabor{ 229219019Sgabor 230219019Sgabor u_int16_t oval = htons(val); 231219019Sgabor memcpy((u_int16_t *)ptr + ofs, &oval, 2); 232219019Sgabor} 233219019Sgabor 234219019Sgaborvoid 235219019Sgaborput32(void *ptr, size_t ofs, u_int32_t val) 236219019Sgabor{ 237219019Sgabor 238219019Sgabor u_int32_t oval = htonl(val); 239219019Sgabor memcpy((u_int32_t *)ptr + ofs, &oval, 4); 240219019Sgabor} 241219019Sgabor 242219019Sgaborstatic void 243219019Sgaboralloc_table(void) 244219019Sgabor{ 245219019Sgabor linear_zone_t *p; 246219019Sgabor size_t i; 247219019Sgabor uint32_t val = 0; 248219019Sgabor 249219019Sgabor i = rowcol_len; 250219019Sgabor p = &rowcol[--i]; 251219019Sgabor table_size = p->width; 252219019Sgabor while (i > 0) { 253219019Sgabor p = &rowcol[--i]; 254219019Sgabor table_size *= p->width; 255219019Sgabor } 256219019Sgabor table = (void *)malloc(table_size * dst_unit_bits / 8); 257219019Sgabor if (table == NULL) { 258219019Sgabor perror("malloc"); 259219019Sgabor exit(1); 260219019Sgabor } 261219019Sgabor 262219019Sgabor switch (oob_mode) { 263219019Sgabor case _CITRUS_MAPPER_STD_OOB_NONIDENTICAL: 264219019Sgabor val = dst_invalid; 265219019Sgabor break; 266219019Sgabor case _CITRUS_MAPPER_STD_OOB_ILSEQ: 267219019Sgabor val = dst_ilseq; 268219019Sgabor break; 269219019Sgabor default: 270219019Sgabor break; 271219019Sgabor } 272219019Sgabor for (i = 0; i < table_size; i++) 273219019Sgabor (*putfunc)(table, i, val); 274219019Sgabor} 275219019Sgabor 276219019Sgaborstatic void 277219019Sgaborsetup_map(void) 278219019Sgabor{ 279219019Sgabor 280219019Sgabor if ((done_flag & DF_SRC_ZONE)==0) { 281219019Sgabor fprintf(stderr, "SRC_ZONE is mandatory.\n"); 282219019Sgabor exit(1); 283219019Sgabor } 284219019Sgabor if ((done_flag & DF_DST_UNIT_BITS)==0) { 285219019Sgabor fprintf(stderr, "DST_UNIT_BITS is mandatory.\n"); 286219019Sgabor exit(1); 287219019Sgabor } 288219019Sgabor 289219019Sgabor if ((done_flag & DF_DST_INVALID) == 0) 290219019Sgabor dst_invalid = 0xFFFFFFFF; 291219019Sgabor if ((done_flag & DF_DST_ILSEQ) == 0) 292219019Sgabor dst_ilseq = 0xFFFFFFFE; 293219019Sgabor if ((done_flag & DF_OOB_MODE) == 0) 294219019Sgabor oob_mode = _CITRUS_MAPPER_STD_OOB_NONIDENTICAL; 295219019Sgabor 296219019Sgabor alloc_table(); 297219019Sgabor} 298219019Sgabor 299219019Sgaborstatic void 300219019Sgaborcreate_rowcol_info(struct _region *r) 301219019Sgabor{ 302219019Sgabor void *ptr; 303219019Sgabor size_t i, len, ofs; 304219019Sgabor 305219019Sgabor ofs = 0; 306219019Sgabor ptr = malloc(_CITRUS_MAPPER_STD_ROWCOL_INFO_SIZE); 307219019Sgabor if (ptr == NULL) 308219019Sgabor err(EXIT_FAILURE, "malloc"); 309219019Sgabor put32(ptr, ofs, rowcol_bits); ofs++; 310219019Sgabor put32(ptr, ofs, dst_invalid); ofs++; 311219019Sgabor 312219019Sgabor /* XXX: keep backward compatibility */ 313219019Sgabor switch (rowcol_len) { 314219019Sgabor case 1: 315219019Sgabor put32(ptr, ofs, 0); ofs++; 316219019Sgabor put32(ptr, ofs, 0); ofs++; 317219019Sgabor /*FALLTHROUGH*/ 318219019Sgabor case 2: 319219019Sgabor len = 0; 320219019Sgabor break; 321219019Sgabor default: 322219019Sgabor len = rowcol_len; 323219019Sgabor } 324219019Sgabor for (i = 0; i < rowcol_len; ++i) { 325219019Sgabor put32(ptr, ofs, rowcol[i].begin); ofs++; 326219019Sgabor put32(ptr, ofs, rowcol[i].end); ofs++; 327219019Sgabor } 328219019Sgabor put32(ptr, ofs, dst_unit_bits); ofs++; 329219019Sgabor put32(ptr, ofs, len); ofs++; 330219019Sgabor 331219019Sgabor _region_init(r, ptr, ofs * 4); 332219019Sgabor} 333219019Sgabor 334219019Sgabor 335219019Sgaborstatic void 336219019Sgaborcreate_rowcol_ext_ilseq_info(struct _region *r) 337219019Sgabor{ 338219019Sgabor void *ptr; 339219019Sgabor size_t ofs; 340219019Sgabor 341219019Sgabor ofs = 0; 342219019Sgabor ptr = malloc(_CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE); 343219019Sgabor if (ptr == NULL) 344219019Sgabor err(EXIT_FAILURE, "malloc"); 345219019Sgabor 346219019Sgabor put32(ptr, ofs, oob_mode); ofs++; 347219019Sgabor put32(ptr, ofs, dst_ilseq); ofs++; 348219019Sgabor 349219019Sgabor _region_init(r, ptr, _CITRUS_MAPPER_STD_ROWCOL_EXT_ILSEQ_SIZE); 350219019Sgabor} 351219019Sgabor 352219019Sgabor#define CHKERR(ret, func, a) \ 353219019Sgabordo { \ 354219019Sgabor ret = func a; \ 355219019Sgabor if (ret) \ 356219019Sgabor errx(EXIT_FAILURE, "%s: %s", #func, strerror(ret)); \ 357219019Sgabor} while (/*CONSTCOND*/0) 358219019Sgabor 359219019Sgaborstatic void 360219019Sgabordump_file(void) 361219019Sgabor{ 362219019Sgabor struct _db_factory *df; 363219019Sgabor struct _region data; 364219019Sgabor void *serialized; 365219019Sgabor FILE *fp; 366219019Sgabor size_t size; 367219019Sgabor int ret; 368219019Sgabor 369219019Sgabor /* 370219019Sgabor * build database 371219019Sgabor */ 372219019Sgabor CHKERR(ret, _db_factory_create, (&df, _db_hash_std, NULL)); 373219019Sgabor 374219019Sgabor /* store type */ 375219019Sgabor CHKERR(ret, _db_factory_addstr_by_s, 376219019Sgabor (df, _CITRUS_MAPPER_STD_SYM_TYPE, _CITRUS_MAPPER_STD_TYPE_ROWCOL)); 377219019Sgabor 378219019Sgabor /* store info */ 379219019Sgabor create_rowcol_info(&data); 380219019Sgabor CHKERR(ret, _db_factory_add_by_s, 381219019Sgabor (df, _CITRUS_MAPPER_STD_SYM_INFO, &data, 1)); 382219019Sgabor 383219019Sgabor /* ilseq extension */ 384219019Sgabor create_rowcol_ext_ilseq_info(&data); 385219019Sgabor CHKERR(ret, _db_factory_add_by_s, 386219019Sgabor (df, _CITRUS_MAPPER_STD_SYM_ROWCOL_EXT_ILSEQ, &data, 1)); 387219019Sgabor 388219019Sgabor /* store table */ 389219019Sgabor _region_init(&data, table, table_size*dst_unit_bits/8); 390219019Sgabor CHKERR(ret, _db_factory_add_by_s, 391219019Sgabor (df, _CITRUS_MAPPER_STD_SYM_TABLE, &data, 1)); 392219019Sgabor 393219019Sgabor /* 394219019Sgabor * dump database to file 395219019Sgabor */ 396219019Sgabor fp = output ? fopen(output, "wb") : stdout; 397219019Sgabor 398219019Sgabor if (fp == NULL) { 399219019Sgabor perror("fopen"); 400219019Sgabor exit(1); 401219019Sgabor } 402219019Sgabor 403219019Sgabor /* dump database body */ 404219019Sgabor size = _db_factory_calc_size(df); 405219019Sgabor serialized = malloc(size); 406219019Sgabor _region_init(&data, serialized, size); 407219019Sgabor CHKERR(ret, _db_factory_serialize, 408219019Sgabor (df, _CITRUS_MAPPER_STD_MAGIC, &data)); 409219019Sgabor if (fwrite(serialized, size, 1, fp) != 1) 410219019Sgabor err(EXIT_FAILURE, "fwrite"); 411219019Sgabor 412219019Sgabor fclose(fp); 413219019Sgabor} 414219019Sgabor 415219019Sgaborstatic void 416219019Sgabor/*ARGSUSED*/ 417219019Sgaborset_type(int type) 418219019Sgabor{ 419219019Sgabor 420219019Sgabor if (done_flag & DF_TYPE) { 421219019Sgabor warning("TYPE is duplicated. ignored this one"); 422219019Sgabor return; 423219019Sgabor } 424219019Sgabor 425219019Sgabor map_type = type; 426219019Sgabor 427219019Sgabor done_flag |= DF_TYPE; 428219019Sgabor} 429219019Sgabor 430219019Sgaborstatic void 431219019Sgabor/*ARGSUSED*/ 432219019Sgaborset_name(char *str) 433219019Sgabor{ 434219019Sgabor 435219019Sgabor if (done_flag & DF_NAME) { 436219019Sgabor warning("NAME is duplicated. ignored this one"); 437219019Sgabor return; 438219019Sgabor } 439219019Sgabor 440219019Sgabor map_name = str; 441219019Sgabor 442219019Sgabor done_flag |= DF_NAME; 443219019Sgabor} 444219019Sgabor 445219019Sgaborstatic void 446219019Sgaborset_src_zone(u_int32_t val) 447219019Sgabor{ 448219019Sgabor linear_zone_t *p; 449219019Sgabor size_t i; 450219019Sgabor 451219019Sgabor if (done_flag & DF_SRC_ZONE) { 452219019Sgabor warning("SRC_ZONE is duplicated. ignored this one"); 453219019Sgabor return; 454219019Sgabor } 455219019Sgabor rowcol_bits = val; 456219019Sgabor 457219019Sgabor /* sanity check */ 458219019Sgabor switch (rowcol_bits) { 459219019Sgabor case 8: case 16: case 32: 460219019Sgabor if (rowcol_len <= 32 / rowcol_bits) 461219019Sgabor break; 462219019Sgabor /*FALLTHROUGH*/ 463219019Sgabor default: 464219019Sgabor goto bad; 465219019Sgabor } 466219019Sgabor rowcol_mask = 1 << (rowcol_bits - 1); 467219019Sgabor rowcol_mask |= rowcol_mask - 1; 468219019Sgabor for (i = 0; i < rowcol_len; ++i) { 469219019Sgabor p = &rowcol[i]; 470219019Sgabor if (p->end > rowcol_mask) 471219019Sgabor goto bad; 472219019Sgabor } 473219019Sgabor done_flag |= DF_SRC_ZONE; 474219019Sgabor return; 475219019Sgabor 476219019Sgaborbad: 477219019Sgabor yyerror("Illegal argument for SRC_ZONE"); 478219019Sgabor} 479219019Sgabor 480219019Sgaborstatic void 481219019Sgaborset_dst_invalid(u_int32_t val) 482219019Sgabor{ 483219019Sgabor 484219019Sgabor if (done_flag & DF_DST_INVALID) { 485219019Sgabor warning("DST_INVALID is duplicated. ignored this one"); 486219019Sgabor return; 487219019Sgabor } 488219019Sgabor 489219019Sgabor dst_invalid = val; 490219019Sgabor 491219019Sgabor done_flag |= DF_DST_INVALID; 492219019Sgabor} 493219019Sgabor 494219019Sgaborstatic void 495219019Sgaborset_dst_ilseq(u_int32_t val) 496219019Sgabor{ 497219019Sgabor 498219019Sgabor if (done_flag & DF_DST_ILSEQ) { 499219019Sgabor warning("DST_ILSEQ is duplicated. ignored this one"); 500219019Sgabor return; 501219019Sgabor } 502219019Sgabor 503219019Sgabor dst_ilseq = val; 504219019Sgabor 505219019Sgabor done_flag |= DF_DST_ILSEQ; 506219019Sgabor} 507219019Sgabor 508219019Sgaborstatic void 509219019Sgaborset_oob_mode(u_int32_t val) 510219019Sgabor{ 511219019Sgabor 512219019Sgabor if (done_flag & DF_OOB_MODE) { 513219019Sgabor warning("OOB_MODE is duplicated. ignored this one"); 514219019Sgabor return; 515219019Sgabor } 516219019Sgabor 517219019Sgabor oob_mode = val; 518219019Sgabor 519219019Sgabor done_flag |= DF_OOB_MODE; 520219019Sgabor} 521219019Sgabor 522219019Sgaborstatic void 523219019Sgaborset_dst_unit_bits(u_int32_t val) 524219019Sgabor{ 525219019Sgabor 526219019Sgabor if (done_flag & DF_DST_UNIT_BITS) { 527219019Sgabor warning("DST_UNIT_BITS is duplicated. ignored this one"); 528219019Sgabor return; 529219019Sgabor } 530219019Sgabor 531219019Sgabor switch (val) { 532219019Sgabor case 8: 533219019Sgabor putfunc = &put8; 534219019Sgabor dst_unit_bits = val; 535219019Sgabor break; 536219019Sgabor case 16: 537219019Sgabor putfunc = &put16; 538219019Sgabor dst_unit_bits = val; 539219019Sgabor break; 540219019Sgabor case 32: 541219019Sgabor putfunc = &put32; 542219019Sgabor dst_unit_bits = val; 543219019Sgabor break; 544219019Sgabor default: 545219019Sgabor yyerror("Illegal argument for DST_UNIT_BITS"); 546219019Sgabor } 547219019Sgabor done_flag |= DF_DST_UNIT_BITS; 548219019Sgabor} 549219019Sgabor 550219019Sgaborstatic int 551219019Sgaborcheck_src(u_int32_t begin, u_int32_t end) 552219019Sgabor{ 553219019Sgabor linear_zone_t *p; 554219019Sgabor size_t i; 555219019Sgabor u_int32_t m, n; 556219019Sgabor 557219019Sgabor if (begin > end) 558219019Sgabor return (1); 559219019Sgabor if (begin < end) { 560219019Sgabor m = begin & ~rowcol_mask; 561219019Sgabor n = end & ~rowcol_mask; 562219019Sgabor if (m != n) 563219019Sgabor return (1); 564219019Sgabor } 565219019Sgabor for (i = rowcol_len * rowcol_bits, p = &rowcol[0]; i > 0; ++p) { 566219019Sgabor i -= rowcol_bits; 567219019Sgabor m = (begin >> i) & rowcol_mask; 568219019Sgabor if (m < p->begin || m > p->end) 569219019Sgabor return (1); 570219019Sgabor } 571219019Sgabor if (begin < end) { 572219019Sgabor n = end & rowcol_mask; 573219019Sgabor --p; 574219019Sgabor if (n < p->begin || n > p->end) 575219019Sgabor return (1); 576219019Sgabor } 577219019Sgabor return (0); 578219019Sgabor} 579219019Sgabor 580219019Sgaborstatic void 581219019Sgaborstore(const linear_zone_t *lz, u_int32_t dst, int inc) 582219019Sgabor{ 583219019Sgabor linear_zone_t *p; 584219019Sgabor size_t i, ofs; 585219019Sgabor u_int32_t n; 586219019Sgabor 587219019Sgabor ofs = 0; 588219019Sgabor for (i = rowcol_len * rowcol_bits, p = &rowcol[0]; i > 0; ++p) { 589219019Sgabor i -= rowcol_bits; 590219019Sgabor n = ((lz->begin >> i) & rowcol_mask) - p->begin; 591219019Sgabor ofs = (ofs * p->width) + n; 592219019Sgabor } 593219019Sgabor n = lz->width; 594219019Sgabor while (n-- > 0) { 595219019Sgabor (*putfunc)(table, ofs++, dst); 596219019Sgabor if (inc) 597219019Sgabor dst++; 598219019Sgabor } 599219019Sgabor} 600219019Sgabor 601219019Sgaborstatic void 602219019Sgaborset_range(u_int32_t begin, u_int32_t end) 603219019Sgabor{ 604219019Sgabor linear_zone_t *p; 605219019Sgabor 606219019Sgabor if (rowcol_len >= _CITRUS_MAPPER_STD_ROWCOL_MAX) 607219019Sgabor goto bad; 608219019Sgabor p = &rowcol[rowcol_len++]; 609219019Sgabor 610219019Sgabor if (begin > end) 611219019Sgabor goto bad; 612219019Sgabor p->begin = begin, p->end = end; 613219019Sgabor p->width = end - begin + 1; 614219019Sgabor 615219019Sgabor return; 616219019Sgabor 617219019Sgaborbad: 618219019Sgabor yyerror("Illegal argument for SRC_ZONE"); 619219019Sgabor} 620219019Sgabor 621219019Sgaborstatic void 622219019Sgaborset_src(linear_zone_t *lz, u_int32_t begin, u_int32_t end) 623219019Sgabor{ 624219019Sgabor 625219019Sgabor if (check_src(begin, end) != 0) 626219019Sgabor yyerror("illegal zone"); 627219019Sgabor 628219019Sgabor lz->begin = begin, lz->end = end; 629219019Sgabor lz->width = end - begin + 1; 630219019Sgabor 631219019Sgabor src_next = end + 1; 632219019Sgabor} 633219019Sgabor 634219019Sgaborstatic void 635219019Sgabordo_mkdb(FILE *in) 636219019Sgabor{ 637219019Sgabor FILE *out; 638219019Sgabor int ret; 639219019Sgabor 640219019Sgabor /* dump DB to file */ 641219019Sgabor out = output ? fopen(output, "wb") : stdout; 642219019Sgabor 643219019Sgabor if (out == NULL) 644219019Sgabor err(EXIT_FAILURE, "fopen"); 645219019Sgabor 646219019Sgabor ret = _lookup_factory_convert(out, in); 647219019Sgabor fclose(out); 648219019Sgabor if (ret && output) 649219019Sgabor unlink(output); /* dump failure */ 650219019Sgabor} 651219019Sgabor 652219019Sgaborstatic void 653219019Sgabordo_mkpv(FILE *in) 654219019Sgabor{ 655219019Sgabor FILE *out; 656219019Sgabor int ret; 657219019Sgabor 658219019Sgabor /* dump pivot to file */ 659219019Sgabor out = output ? fopen(output, "wb") : stdout; 660219019Sgabor 661219019Sgabor if (out == NULL) 662219019Sgabor err(EXIT_FAILURE, "fopen"); 663219019Sgabor 664219019Sgabor ret = _pivot_factory_convert(out, in); 665219019Sgabor fclose(out); 666219019Sgabor if (ret && output) 667219019Sgabor unlink(output); /* dump failure */ 668219019Sgabor if (ret) 669308357Sbapt errx(EXIT_FAILURE, "%s\n", strerror(ret)); 670219019Sgabor} 671219019Sgabor 672219019Sgaborstatic void 673219019Sgaborusage(void) 674219019Sgabor{ 675307794Sbapt fprintf(stderr, "Usage: %s [-d] [-m|-p] [-o outfile] [infile]\n", 676307794Sbapt getprogname()); 677307794Sbapt exit(EXIT_FAILURE); 678219019Sgabor} 679219019Sgabor 680219019Sgaborint 681219019Sgabormain(int argc, char **argv) 682219019Sgabor{ 683219019Sgabor FILE *in = NULL; 684219019Sgabor int ch, mkdb = 0, mkpv = 0; 685219019Sgabor 686219019Sgabor while ((ch = getopt(argc, argv, "do:mp")) != EOF) { 687219019Sgabor switch (ch) { 688219019Sgabor case 'd': 689219019Sgabor debug = 1; 690219019Sgabor break; 691219019Sgabor case 'o': 692219019Sgabor output = strdup(optarg); 693219019Sgabor break; 694219019Sgabor case 'm': 695219019Sgabor mkdb = 1; 696219019Sgabor break; 697219019Sgabor case 'p': 698219019Sgabor mkpv = 1; 699219019Sgabor break; 700219019Sgabor default: 701219019Sgabor usage(); 702219019Sgabor } 703219019Sgabor } 704219019Sgabor 705219019Sgabor argc -= optind; 706219019Sgabor argv += optind; 707219019Sgabor switch (argc) { 708219019Sgabor case 0: 709219019Sgabor in = stdin; 710219019Sgabor break; 711219019Sgabor case 1: 712219019Sgabor in = fopen(argv[0], "r"); 713219019Sgabor if (!in) 714219019Sgabor err(EXIT_FAILURE, "%s", argv[0]); 715219019Sgabor break; 716219019Sgabor default: 717219019Sgabor usage(); 718219019Sgabor } 719219019Sgabor 720219019Sgabor if (mkdb) 721219019Sgabor do_mkdb(in); 722219019Sgabor else if (mkpv) 723219019Sgabor do_mkpv(in); 724219019Sgabor else { 725219019Sgabor yyin = in; 726219019Sgabor yyparse(); 727219019Sgabor } 728219019Sgabor 729219019Sgabor return (0); 730219019Sgabor} 731