options.cc revision 67065
1/* Handles parsing the Options provided to the user. 2 Copyright (C) 1989-1998, 2000 Free Software Foundation, Inc. 3 written by Douglas C. Schmidt (schmidt@ics.uci.edu) 4 5This file is part of GNU GPERF. 6 7GNU GPERF is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 1, or (at your option) 10any later version. 11 12GNU GPERF is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with GNU GPERF; see the file COPYING. If not, write to the Free 19Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ 20 21#include <stdio.h> 22#include <stdlib.h> /* declares atoi(), abs(), exit() */ 23#include <string.h> /* declares strcmp() */ 24#include "getopt.h" 25#include "options.h" 26#include "iterator.h" 27#include "trace.h" 28#include "vectors.h" 29#include "version.h" 30 31/* Global option coordinator for the entire program. */ 32Options option; 33 34/* Records the program name. */ 35const char *program_name; 36 37/* Size to jump on a collision. */ 38static const int DEFAULT_JUMP_VALUE = 5; 39 40/* Default name for generated lookup function. */ 41static const char *const DEFAULT_NAME = "in_word_set"; 42 43/* Default name for the key component. */ 44static const char *const DEFAULT_KEY = "name"; 45 46/* Default struct initializer suffix. */ 47static const char *const DEFAULT_INITIALIZER_SUFFIX = ""; 48 49/* Default name for the generated class. */ 50static const char *const DEFAULT_CLASS_NAME = "Perfect_Hash"; 51 52/* Default name for generated hash function. */ 53static const char *const DEFAULT_HASH_NAME = "hash"; 54 55/* Default name for generated hash table array. */ 56static const char *const DEFAULT_WORDLIST_NAME = "wordlist"; 57 58/* Default delimiters that separate keywords from their attributes. */ 59static const char *const DEFAULT_DELIMITERS = ",\n"; 60 61int Options::option_word; 62int Options::total_switches; 63int Options::total_keysig_size; 64int Options::size; 65int Options::key_pos; 66int Options::jump; 67int Options::initial_asso_value; 68int Options::argument_count; 69int Options::iterations; 70char **Options::argument_vector; 71const char *Options::function_name; 72const char *Options::key_name; 73const char *Options::initializer_suffix; 74const char *Options::class_name; 75const char *Options::hash_name; 76const char *Options::wordlist_name; 77const char *Options::delimiters; 78char Options::key_positions[MAX_KEY_POS]; 79 80/* Prints program usage to given stream. */ 81 82void 83Options::short_usage (FILE * strm) 84{ 85 T (Trace t ("Options::short_usage");) 86 fprintf (strm, "Usage: %s [-cCdDef[num]F<initializers>GhH<hashname>i<init>Ijk<keys>K<keyname>lL<language>nN<function name>ors<size>S<switches>tTvW<wordlistname>Z<class name>7] [input-file]\n" 87 "Try `%s --help' for more information.\n", 88 program_name, program_name); 89} 90 91void 92Options::long_usage (FILE * strm) 93{ 94 T (Trace t ("Options::long_usage");) 95 fprintf (strm, 96 "GNU `gperf' generates perfect hash functions.\n" 97 "\n" 98 "Usage: %s [OPTION]... [INPUT-FILE]\n" 99 "\n" 100 "If a long option shows an argument as mandatory, then it is mandatory\n" 101 "for the equivalent short option also.\n" 102 "\n" 103 "Input file interpretation:\n" 104 " -e, --delimiters=DELIMITER-LIST\n" 105 " Allow user to provide a string containing delimiters\n" 106 " used to separate keywords from their attributes.\n" 107 " Default is \",\\n\".\n" 108 " -t, --struct-type Allows the user to include a structured type\n" 109 " declaration for generated code. Any text before %%%%\n" 110 " is considered part of the type declaration. Key\n" 111 " words and additional fields may follow this, one\n" 112 " group of fields per line.\n" 113 "\n" 114 "Language for the output code:\n" 115 " -L, --language=LANGUAGE-NAME\n" 116 " Generates code in the specified language. Languages\n" 117 " handled are currently C++, ANSI-C, C, and KR-C. The\n" 118 " default is C.\n" 119 "\n" 120 "Details in the output code:\n" 121 " -K, --slot-name=NAME Select name of the keyword component in the keyword\n" 122 " structure.\n" 123 " -F, --initializer-suffix=INITIALIZERS\n" 124 " Initializers for additional components in the keyword\n" 125 " structure.\n" 126 " -H, --hash-fn-name=NAME\n" 127 " Specify name of generated hash function. Default is\n" 128 " `hash'.\n" 129 " -N, --lookup-fn-name=NAME\n" 130 " Specify name of generated lookup function. Default\n" 131 " name is `in_word_set'.\n" 132 " -Z, --class-name=NAME Specify name of generated C++ class. Default name is\n" 133 " `Perfect_Hash'.\n" 134 " -7, --seven-bit Assume 7-bit characters.\n" 135 " -c, --compare-strncmp Generate comparison code using strncmp rather than\n" 136 " strcmp.\n" 137 " -C, --readonly-tables Make the contents of generated lookup tables\n" 138 " constant, i.e., readonly.\n" 139 " -E, --enum Define constant values using an enum local to the\n" 140 " lookup function rather than with defines.\n" 141 " -I, --includes Include the necessary system include file <string.h>\n" 142 " at the beginning of the code.\n" 143 " -G, --global Generate the static table of keywords as a static\n" 144 " global variable, rather than hiding it inside of the\n" 145 " lookup function (which is the default behavior).\n" 146 " -W, --word-array-name=NAME\n" 147 " Specify name of word list array. Default name is\n" 148 " `wordlist'.\n" 149 " -S, --switch=COUNT Causes the generated C code to use a switch\n" 150 " statement scheme, rather than an array lookup table.\n" 151 " This can lead to a reduction in both time and space\n" 152 " requirements for some keyfiles. The COUNT argument\n" 153 " determines how many switch statements are generated.\n" 154 " A value of 1 generates 1 switch containing all the\n" 155 " elements, a value of 2 generates 2 tables with 1/2\n" 156 " the elements in each table, etc. If COUNT is very\n" 157 " large, say 1000000, the generated C code does a\n" 158 " binary search.\n" 159 " -T, --omit-struct-type\n" 160 " Prevents the transfer of the type declaration to the\n" 161 " output file. Use this option if the type is already\n" 162 " defined elsewhere.\n" 163 "\n" 164 "Algorithm employed by gperf:\n" 165 " -k, --key-positions=KEYS\n" 166 " Select the key positions used in the hash function.\n" 167 " The allowable choices range between 1-%d, inclusive.\n" 168 " The positions are separated by commas, ranges may be\n" 169 " used, and key positions may occur in any order.\n" 170 " Also, the meta-character '*' causes the generated\n" 171 " hash function to consider ALL key positions, and $\n" 172 " indicates the ``final character'' of a key, e.g.,\n" 173 " $,1,2,4,6-10.\n" 174 " -l, --compare-strlen Compare key lengths before trying a string\n" 175 " comparison. This helps cut down on the number of\n" 176 " string comparisons made during the lookup.\n" 177 " -D, --duplicates Handle keywords that hash to duplicate values. This\n" 178 " is useful for certain highly redundant keyword sets.\n" 179 " -f, --fast=ITERATIONS Generate the gen-perf.hash function ``fast''. This\n" 180 " decreases gperf's running time at the cost of\n" 181 " minimizing generated table size. The numeric\n" 182 " argument represents the number of times to iterate\n" 183 " when resolving a collision. `0' means ``iterate by\n" 184 " the number of keywords''.\n" 185 " -i, --initial-asso=N Provide an initial value for the associate values\n" 186 " array. Default is 0. Setting this value larger helps\n" 187 " inflate the size of the final table.\n" 188 " -j, --jump=JUMP-VALUE Affects the ``jump value'', i.e., how far to advance\n" 189 " the associated character value upon collisions. Must\n" 190 " be an odd number, default is %d.\n" 191 " -n, --no-strlen Do not include the length of the keyword when\n" 192 " computing the hash function.\n" 193 " -o, --occurrence-sort Reorders input keys by frequency of occurrence of\n" 194 " the key sets. This should decrease the search time\n" 195 " dramatically.\n" 196 " -r, --random Utilizes randomness to initialize the associated\n" 197 " values table.\n" 198 " -s, --size-multiple=N Affects the size of the generated hash table. The\n" 199 " numeric argument N indicates ``how many times larger\n" 200 " or smaller'' the associated value range should be,\n" 201 " in relationship to the number of keys, e.g. a value\n" 202 " of 3 means ``allow the maximum associated value to\n" 203 " be about 3 times larger than the number of input\n" 204 " keys.'' Conversely, a value of -3 means ``make the\n" 205 " maximum associated value about 3 times smaller than\n" 206 " the number of input keys. A larger table should\n" 207 " decrease the time required for an unsuccessful\n" 208 " search, at the expense of extra table space. Default\n" 209 " value is 1.\n" 210 "\n" 211 "Informative output:\n" 212 " -h, --help Print this message.\n" 213 " -v, --version Print the gperf version number.\n" 214 " -d, --debug Enables the debugging option (produces verbose\n" 215 " output to the standard error).\n" 216 "\n" 217 "Report bugs to <bug-gnu-utils@gnu.org>.\n" 218 , program_name, MAX_KEY_POS - 1, DEFAULT_JUMP_VALUE); 219} 220 221/* Output command-line Options. */ 222 223void 224Options::print_options (void) 225{ 226 T (Trace t ("Options::print_options");) 227 int i; 228 229 printf ("/* Command-line: "); 230 231 for (i = 0; i < argument_count; i++) 232 { 233 const char *arg = argument_vector[i]; 234 235 /* Escape arg if it contains shell metacharacters. */ 236 if (*arg == '-') 237 { 238 putchar (*arg); 239 arg++; 240 if (*arg >= 'A' && *arg <= 'Z' || *arg >= 'a' && *arg <= 'z') 241 { 242 putchar (*arg); 243 arg++; 244 } 245 } 246 if (strpbrk (arg, "\t\n !\"#$&'()*;<>?[\\]`{|}~") != NULL) 247 { 248 if (strchr (arg, '\'') != NULL) 249 { 250 putchar ('"'); 251 for (; *arg; arg++) 252 { 253 if (*arg == '\"' || *arg == '\\' || *arg == '$') 254 putchar ('\\'); 255 putchar (*arg); 256 } 257 putchar ('"'); 258 } 259 else 260 { 261 putchar ('\''); 262 for (; *arg; arg++) 263 { 264 if (*arg == '\\') 265 putchar ('\\'); 266 putchar (*arg); 267 } 268 putchar ('\''); 269 } 270 } 271 else 272 printf ("%s", arg); 273 274 printf (" "); 275 } 276 277 printf (" */"); 278} 279 280/* Sorts the key positions *IN REVERSE ORDER!!* 281 This makes further routines more efficient. Especially when generating code. 282 Uses a simple Insertion Sort since the set is probably ordered. 283 Returns 1 if there are no duplicates, 0 otherwise. */ 284 285inline int 286Options::key_sort (char *base, int len) 287{ 288 T (Trace t ("Options::key_sort");) 289 int i, j; 290 291 for (i = 0, j = len - 1; i < j; i++) 292 { 293 int curr, tmp; 294 295 for (curr = i + 1,tmp = base[curr]; curr > 0 && tmp >= base[curr - 1]; curr--) 296 if ((base[curr] = base[curr - 1]) == tmp) /* oh no, a duplicate!!! */ 297 return 0; 298 299 base[curr] = tmp; 300 } 301 302 return 1; 303} 304 305/* Sets the default Options. */ 306 307Options::Options (void) 308{ 309 T (Trace t ("Options::Options");) 310 key_positions[0] = WORD_START; 311 key_positions[1] = WORD_END; 312 key_positions[2] = EOS; 313 total_keysig_size = 2; 314 delimiters = DEFAULT_DELIMITERS; 315 jump = DEFAULT_JUMP_VALUE; 316 option_word = DEFAULTCHARS | C; 317 function_name = DEFAULT_NAME; 318 key_name = DEFAULT_KEY; 319 initializer_suffix = DEFAULT_INITIALIZER_SUFFIX; 320 hash_name = DEFAULT_HASH_NAME; 321 wordlist_name = DEFAULT_WORDLIST_NAME; 322 class_name = DEFAULT_CLASS_NAME; 323 total_switches = size = 1; 324 initial_asso_value = iterations = 0; 325} 326 327/* Dumps option status when debug is set. */ 328 329Options::~Options (void) 330{ 331 T (Trace t ("Options::~Options");) 332 if (option_word & DEBUG) 333 { 334 char *ptr; 335 336 fprintf (stderr, "\ndumping Options:" 337 "\nDEBUG is.......: %s" 338 "\nORDER is.......: %s" 339 "\nTYPE is........: %s" 340 "\nRANDOM is......: %s" 341 "\nDEFAULTCHARS is: %s" 342 "\nSWITCH is......: %s" 343 "\nNOLENGTH is....: %s" 344 "\nLENTABLE is....: %s" 345 "\nDUP is.........: %s" 346 "\nFAST is........: %s" 347 "\nCOMP is........: %s" 348 "\nNOTYPE is......: %s" 349 "\nGLOBAL is......: %s" 350 "\nCONST is.......: %s" 351 "\nKRC is.........: %s" 352 "\nC is...........: %s" 353 "\nANSIC is.......: %s" 354 "\nCPLUSPLUS is...: %s" 355 "\nENUM is........: %s" 356 "\nINCLUDE is.....: %s" 357 "\nSEVENBIT is....: %s" 358 "\niterations = %d" 359 "\nlookup function name = %s" 360 "\nhash function name = %s" 361 "\nword list name = %s" 362 "\nkey name = %s" 363 "\ninitializer suffix = %s" 364 "\njump value = %d" 365 "\nmax associated value = %d" 366 "\ninitial associated value = %d" 367 "\ndelimiters = %s" 368 "\nnumber of switch statements = %d\n", 369 option_word & DEBUG ? "enabled" : "disabled", 370 option_word & ORDER ? "enabled" : "disabled", 371 option_word & TYPE ? "enabled" : "disabled", 372 option_word & RANDOM ? "enabled" : "disabled", 373 option_word & DEFAULTCHARS ? "enabled" : "disabled", 374 option_word & SWITCH ? "enabled" : "disabled", 375 option_word & NOLENGTH ? "enabled" : "disabled", 376 option_word & LENTABLE ? "enabled" : "disabled", 377 option_word & DUP ? "enabled" : "disabled", 378 option_word & FAST ? "enabled" : "disabled", 379 option_word & COMP ? "enabled" : "disabled", 380 option_word & NOTYPE ? "enabled" : "disabled", 381 option_word & GLOBAL ? "enabled" : "disabled", 382 option_word & CONST ? "enabled" : "disabled", 383 option_word & KRC ? "enabled" : "disabled", 384 option_word & C ? "enabled" : "disabled", 385 option_word & ANSIC ? "enabled" : "disabled", 386 option_word & CPLUSPLUS ? "enabled" : "disabled", 387 option_word & ENUM ? "enabled" : "disabled", 388 option_word & INCLUDE ? "enabled" : "disabled", 389 option_word & SEVENBIT ? "enabled" : "disabled", 390 iterations, 391 function_name, hash_name, wordlist_name, key_name, 392 initializer_suffix, jump, size - 1, initial_asso_value, 393 delimiters, total_switches); 394 if (option_word & ALLCHARS) 395 fprintf (stderr, "all characters are used in the hash function\n"); 396 397 fprintf (stderr, "maximum keysig size = %d\nkey positions are: \n", 398 total_keysig_size); 399 400 for (ptr = key_positions; *ptr != EOS; ptr++) 401 if (*ptr == WORD_END) 402 fprintf (stderr, "$\n"); 403 else 404 fprintf (stderr, "%d\n", *ptr); 405 406 fprintf (stderr, "finished dumping Options\n"); 407 } 408} 409 410 411/* Parses the command line Options and sets appropriate flags in option_word. */ 412 413static const struct option long_options[] = 414{ 415 { "delimiters", required_argument, 0, 'e' }, 416 { "struct-type", no_argument, 0, 't' }, 417 { "language", required_argument, 0, 'L' }, 418 { "slot-name", required_argument, 0, 'K' }, 419 { "initializer-suffix", required_argument, 0, 'F' }, 420 { "hash-fn-name", required_argument, 0, 'H' }, 421 { "lookup-fn-name", required_argument, 0, 'N' }, 422 { "class-name", required_argument, 0, 'Z' }, 423 { "seven-bit", no_argument, 0, '7' }, 424 { "compare-strncmp", no_argument, 0, 'c' }, 425 { "readonly-tables", no_argument, 0, 'C' }, 426 { "enum", no_argument, 0, 'E' }, 427 { "includes", no_argument, 0, 'I' }, 428 { "global", no_argument, 0, 'G' }, 429 { "word-array-name", required_argument, 0, 'W' }, 430 { "switch", required_argument, 0, 'S' }, 431 { "omit-struct-type", no_argument, 0, 'T' }, 432 { "key-positions", required_argument, 0, 'k' }, 433 { "compare-strlen", no_argument, 0, 'l' }, 434 { "duplicates", no_argument, 0, 'D' }, 435 { "fast", required_argument, 0, 'f' }, 436 { "initial-asso", required_argument, 0, 'i' }, 437 { "jump", required_argument, 0, 'j' }, 438 { "no-strlen", no_argument, 0, 'n' }, 439 { "occurrence-sort", no_argument, 0, 'o' }, 440 { "random", no_argument, 0, 'r' }, 441 { "size-multiple", required_argument, 0, 's' }, 442 { "help", no_argument, 0, 'h' }, 443 { "version", no_argument, 0, 'v' }, 444 { "debug", no_argument, 0, 'd' }, 445 { 0, no_argument, 0, 0 } 446}; 447 448void 449Options::operator() (int argc, char *argv[]) 450{ 451 T (Trace t ("Options::operator()");) 452 int option_char; 453 454 program_name = argv[0]; 455 argument_count = argc; 456 argument_vector = argv; 457 458 while ((option_char = 459 getopt_long (argument_count, argument_vector, 460 "adcCDe:Ef:F:gGhH:i:Ij:k:K:lL:nN:oprs:S:tTvW:Z:7", 461 long_options, (int *)0)) 462 != -1) 463 { 464 switch (option_char) 465 { 466 case 'a': /* Generated code uses the ANSI prototype format. */ 467 break; /* This is now the default. */ 468 case 'c': /* Generate strncmp rather than strcmp. */ 469 { 470 option_word |= COMP; 471 break; 472 } 473 case 'C': /* Make the generated tables readonly (const). */ 474 { 475 option_word |= CONST; 476 break; 477 } 478 case 'd': /* Enable debugging option. */ 479 { 480 option_word |= DEBUG; 481 fprintf (stderr, "Starting program %s, version %s, with debugging on.\n", 482 program_name, version_string); 483 break; 484 } 485 case 'D': /* Enable duplicate option. */ 486 { 487 option_word |= DUP; 488 break; 489 } 490 case 'e': /* Allows user to provide keyword/attribute separator */ 491 { 492 option.delimiters = /*getopt*/optarg; 493 break; 494 } 495 case 'E': 496 { 497 option_word |= ENUM; 498 break; 499 } 500 case 'f': /* Generate the hash table ``fast.'' */ 501 { 502 option_word |= FAST; 503 if ((iterations = atoi (/*getopt*/optarg)) < 0) 504 { 505 fprintf (stderr, "iterations value must not be negative, assuming 0\n"); 506 iterations = 0; 507 } 508 break; 509 } 510 case 'F': 511 { 512 initializer_suffix = /*getopt*/optarg; 513 break; 514 } 515 case 'g': /* Use the ``inline'' keyword for generated sub-routines, ifdef __GNUC__. */ 516 break; /* This is now the default. */ 517 case 'G': /* Make the keyword table a global variable. */ 518 { 519 option_word |= GLOBAL; 520 break; 521 } 522 case 'h': /* Displays a list of helpful Options to the user. */ 523 { 524 long_usage (stdout); 525 exit (0); 526 } 527 case 'H': /* Sets the name for the hash function */ 528 { 529 hash_name = /*getopt*/optarg; 530 break; 531 } 532 case 'i': /* Sets the initial value for the associated values array. */ 533 { 534 if ((initial_asso_value = atoi (/*getopt*/optarg)) < 0) 535 fprintf (stderr, "Initial value %d should be non-zero, ignoring and continuing.\n", initial_asso_value); 536 if (option[RANDOM]) 537 fprintf (stderr, "warning, -r option superceeds -i, ignoring -i option and continuing\n"); 538 break; 539 } 540 case 'I': /* Enable #include statements. */ 541 { 542 option_word |= INCLUDE; 543 break; 544 } 545 case 'j': /* Sets the jump value, must be odd for later algorithms. */ 546 { 547 if ((jump = atoi (/*getopt*/optarg)) < 0) 548 { 549 fprintf (stderr, "Jump value %d must be a positive number.\n", jump); 550 short_usage (stderr); 551 exit (1); 552 } 553 else if (jump && ((jump % 2) == 0)) 554 fprintf (stderr, "Jump value %d should be odd, adding 1 and continuing...\n", jump++); 555 break; 556 } 557 case 'k': /* Sets key positions used for hash function. */ 558 { 559 const int BAD_VALUE = -1; 560 int value; 561 Iterator expand (/*getopt*/optarg, 1, MAX_KEY_POS - 1, WORD_END, BAD_VALUE, EOS); 562 563 if (/*getopt*/optarg [0] == '*') /* Use all the characters for hashing!!!! */ 564 option_word = (option_word & ~DEFAULTCHARS) | ALLCHARS; 565 else 566 { 567 char *key_pos; 568 569 for (key_pos = key_positions; (value = expand ()) != EOS; key_pos++) 570 if (value == BAD_VALUE) 571 { 572 fprintf (stderr, "Illegal key value or range, use 1,2,3-%d,'$' or '*'.\n", 573 MAX_KEY_POS - 1); 574 short_usage (stderr); 575 exit (1); 576 } 577 else 578 *key_pos = value;; 579 580 *key_pos = EOS; 581 582 if (! (total_keysig_size = (key_pos - key_positions))) 583 { 584 fprintf (stderr, "No keys selected.\n"); 585 short_usage (stderr); 586 exit (1); 587 } 588 else if (! key_sort (key_positions, total_keysig_size)) 589 { 590 fprintf (stderr, "Duplicate keys selected\n"); 591 short_usage (stderr); 592 exit (1); 593 } 594 595 if (total_keysig_size != 2 596 || (key_positions[0] != 1 || key_positions[1] != WORD_END)) 597 option_word &= ~DEFAULTCHARS; 598 } 599 break; 600 } 601 case 'K': /* Make this the keyname for the keyword component field. */ 602 { 603 key_name = /*getopt*/optarg; 604 break; 605 } 606 case 'l': /* Create length table to avoid extra string compares. */ 607 { 608 option_word |= LENTABLE; 609 break; 610 } 611 case 'L': /* Deal with different generated languages. */ 612 { 613 option_word &= ~(KRC | C | ANSIC | CPLUSPLUS); 614 if (!strcmp (/*getopt*/optarg, "KR-C")) 615 option_word |= KRC; 616 else if (!strcmp (/*getopt*/optarg, "C")) 617 option_word |= C; 618 else if (!strcmp (/*getopt*/optarg, "ANSI-C")) 619 option_word |= ANSIC; 620 else if (!strcmp (/*getopt*/optarg, "C++")) 621 option_word |= CPLUSPLUS; 622 else 623 { 624 fprintf (stderr, "unsupported language option %s, defaulting to C\n", /*getopt*/optarg); 625 option_word |= C; 626 } 627 break; 628 } 629 case 'n': /* Don't include the length when computing hash function. */ 630 { 631 option_word |= NOLENGTH; 632 break; 633 } 634 case 'N': /* Make generated lookup function name be optarg */ 635 { 636 function_name = /*getopt*/optarg; 637 break; 638 } 639 case 'o': /* Order input by frequency of key set occurrence. */ 640 { 641 option_word |= ORDER; 642 break; 643 } 644 case 'p': /* Generated lookup function a pointer instead of int. */ 645 break; /* This is now the default. */ 646 case 'r': /* Utilize randomness to initialize the associated values table. */ 647 { 648 option_word |= RANDOM; 649 if (option.initial_asso_value != 0) 650 fprintf (stderr, "warning, -r option superceeds -i, disabling -i option and continuing\n"); 651 break; 652 } 653 case 's': /* Range of associated values, determines size of final table. */ 654 { 655 if (abs (size = atoi (/*getopt*/optarg)) > 50) 656 fprintf (stderr, "%d is excessive, did you really mean this?! (try `%s --help' for help)\n", size, program_name); 657 break; 658 } 659 case 'S': /* Generate switch statement output, rather than lookup table. */ 660 { 661 option_word |= SWITCH; 662 if ((option.total_switches = atoi (/*getopt*/optarg)) <= 0) 663 { 664 fprintf (stderr, "number of switches %s must be a positive number\n", /*getopt*/optarg); 665 short_usage (stderr); 666 exit (1); 667 } 668 break; 669 } 670 case 't': /* Enable the TYPE mode, allowing arbitrary user structures. */ 671 { 672 option_word |= TYPE; 673 break; 674 } 675 case 'T': /* Don't print structure definition. */ 676 { 677 option_word |= NOTYPE; 678 break; 679 } 680 case 'v': /* Print out the version and quit. */ 681 fprintf (stdout, "GNU gperf %s\n", version_string); 682 exit (0); 683 case 'W': /* Sets the name for the hash table array */ 684 { 685 wordlist_name = /*getopt*/optarg; 686 break; 687 } 688 case 'Z': /* Set the class name. */ 689 { 690 class_name = /*getopt*/optarg; 691 break; 692 } 693 case '7': /* Assume 7-bit characters. */ 694 { 695 option_word |= SEVENBIT; 696 Vectors::ALPHA_SIZE = 128; 697 break; 698 } 699 default: 700 short_usage (stderr); 701 exit (1); 702 } 703 704 } 705 706 if (argv[/*getopt*/optind] && ! freopen (argv[/*getopt*/optind], "r", stdin)) 707 { 708 fprintf (stderr, "Cannot open keyword file `%s'\n", argv[/*getopt*/optind]); 709 short_usage (stderr); 710 exit (1); 711 } 712 713 if (++/*getopt*/optind < argc) 714 { 715 fprintf (stderr, "Extra trailing arguments to %s.\n", program_name); 716 short_usage (stderr); 717 exit (1); 718 } 719} 720 721#ifndef __OPTIMIZE__ 722 723#define INLINE /* not inline */ 724#include "options.icc" 725#undef INLINE 726 727#endif /* not defined __OPTIMIZE__ */ 728