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