Make setthetime() static per the prototype.
[dragonfly.git] / contrib / gperf / src / options.cc
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
5 This file is part of GNU GPERF.
6
7 GNU GPERF is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 1, or (at your option)
10 any later version.
11
12 GNU GPERF is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU GPERF; see the file COPYING.  If not, write to the Free
19 Software 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. */
32 Options option;
33
34 /* Records the program name. */
35 const char *program_name;
36
37 /* Size to jump on a collision. */
38 static const int DEFAULT_JUMP_VALUE = 5;
39
40 /* Default name for generated lookup function. */
41 static const char *const DEFAULT_NAME = "in_word_set";
42
43 /* Default name for the key component. */
44 static const char *const DEFAULT_KEY = "name";
45
46 /* Default struct initializer suffix. */
47 static const char *const DEFAULT_INITIALIZER_SUFFIX = "";
48
49 /* Default name for the generated class. */
50 static const char *const DEFAULT_CLASS_NAME = "Perfect_Hash";
51
52 /* Default name for generated hash function. */
53 static const char *const DEFAULT_HASH_NAME = "hash";
54
55 /* Default name for generated hash table array. */
56 static const char *const DEFAULT_WORDLIST_NAME = "wordlist";
57
58 /* Default delimiters that separate keywords from their attributes. */
59 static const char *const DEFAULT_DELIMITERS = ",\n";
60
61 int Options::option_word;
62 int Options::total_switches;
63 int Options::total_keysig_size;
64 int Options::size;
65 int Options::key_pos;
66 int Options::jump;
67 int Options::initial_asso_value;
68 int Options::argument_count;
69 int Options::iterations;
70 char **Options::argument_vector;
71 const char *Options::function_name;
72 const char *Options::key_name;
73 const char *Options::initializer_suffix;
74 const char *Options::class_name;
75 const char *Options::hash_name;
76 const char *Options::wordlist_name;
77 const char *Options::delimiters;
78 char Options::key_positions[MAX_KEY_POS];
79
80 /* Prints program usage to given stream. */
81
82 void
83 Options::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
91 void
92 Options::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
223 void
224 Options::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
285 inline int
286 Options::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
307 Options::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
329 Options::~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
413 static 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
448 void
449 Options::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__ */