Index: gperf/src/gperf/3.0.1/gperf-3.0.1-src/src/options.cc |
=================================================================== |
--- gperf/src/gperf/3.0.1/gperf-3.0.1-src/src/options.cc (revision 0) |
+++ gperf/src/gperf/3.0.1/gperf-3.0.1-src/src/options.cc (revision 0) |
@@ -0,0 +1,1050 @@ |
+/* Handles parsing the Options provided to the user. |
+ Copyright (C) 1989-1998, 2000, 2002-2003 Free Software Foundation, Inc. |
+ Written by Douglas C. Schmidt <schmidt@ics.uci.edu> |
+ and Bruno Haible <bruno@clisp.org>. |
+ |
+ This file is part of GNU GPERF. |
+ |
+ GNU GPERF is free software; you can redistribute it and/or modify |
+ it under the terms of the GNU General Public License as published by |
+ the Free Software Foundation; either version 2, or (at your option) |
+ any later version. |
+ |
+ GNU GPERF is distributed in the hope that it will be useful, |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ GNU General Public License for more details. |
+ |
+ You should have received a copy of the GNU General Public License |
+ along with this program; see the file COPYING. |
+ If not, write to the Free Software Foundation, Inc., |
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
+ |
+/* Specification. */ |
+#include "options.h" |
+ |
+#include <stdio.h> |
+#include <stdlib.h> /* declares atoi(), abs(), exit() */ |
+#include <string.h> /* declares strcmp() */ |
+#include <ctype.h> /* declares isdigit() */ |
+#include <limits.h> /* defines CHAR_MAX */ |
+#include "getopt.h" |
+#include "version.h" |
+ |
+/* Global option coordinator for the entire program. */ |
+Options option; |
+ |
+/* Records the program name. */ |
+const char *program_name; |
+ |
+/* Size to jump on a collision. */ |
+static const int DEFAULT_JUMP_VALUE = 5; |
+ |
+/* Default name for generated lookup function. */ |
+static const char *const DEFAULT_FUNCTION_NAME = "in_word_set"; |
+ |
+/* Default name for the key component. */ |
+static const char *const DEFAULT_SLOT_NAME = "name"; |
+ |
+/* Default struct initializer suffix. */ |
+static const char *const DEFAULT_INITIALIZER_SUFFIX = ""; |
+ |
+/* Default name for the generated class. */ |
+static const char *const DEFAULT_CLASS_NAME = "Perfect_Hash"; |
+ |
+/* Default name for generated hash function. */ |
+static const char *const DEFAULT_HASH_NAME = "hash"; |
+ |
+/* Default name for generated hash table array. */ |
+static const char *const DEFAULT_WORDLIST_NAME = "wordlist"; |
+ |
+/* Default name for string pool. */ |
+static const char *const DEFAULT_STRINGPOOL_NAME = "stringpool"; |
+ |
+/* Default delimiters that separate keywords from their attributes. */ |
+static const char *const DEFAULT_DELIMITERS = ","; |
+ |
+/* Prints program usage to given stream. */ |
+ |
+void |
+Options::short_usage (FILE * stream) |
+{ |
+ fprintf (stream, |
+ "Try '%s --help' for more information.\n", program_name); |
+} |
+ |
+void |
+Options::long_usage (FILE * stream) |
+{ |
+ fprintf (stream, |
+ "GNU 'gperf' generates perfect hash functions.\n"); |
+ fprintf (stream, "\n"); |
+ fprintf (stream, |
+ "Usage: %s [OPTION]... [INPUT-FILE]\n", |
+ program_name); |
+ fprintf (stream, "\n"); |
+ fprintf (stream, |
+ "If a long option shows an argument as mandatory, then it is mandatory\n" |
+ "for the equivalent short option also.\n"); |
+ fprintf (stream, "\n"); |
+ fprintf (stream, |
+ "Output file location:\n"); |
+ fprintf (stream, |
+ " --output-file=FILE Write output to specified file.\n"); |
+ fprintf (stream, |
+ "The results are written to standard output if no output file is specified\n" |
+ "or if it is -.\n"); |
+ fprintf (stream, "\n"); |
+ fprintf (stream, |
+ "Input file interpretation:\n"); |
+ fprintf (stream, |
+ " -e, --delimiters=DELIMITER-LIST\n" |
+ " Allow user to provide a string containing delimiters\n" |
+ " used to separate keywords from their attributes.\n" |
+ " Default is \",\".\n"); |
+ fprintf (stream, |
+ " -t, --struct-type Allows the user to include a structured type\n" |
+ " declaration for generated code. Any text before %%%%\n" |
+ " is considered part of the type declaration. Key\n" |
+ " words and additional fields may follow this, one\n" |
+ " group of fields per line.\n"); |
+ fprintf (stream, |
+ " --ignore-case Consider upper and lower case ASCII characters as\n" |
+ " equivalent. Note that locale dependent case mappings\n" |
+ " are ignored.\n"); |
+ fprintf (stream, "\n"); |
+ fprintf (stream, |
+ "Language for the output code:\n"); |
+ fprintf (stream, |
+ " -L, --language=LANGUAGE-NAME\n" |
+ " Generates code in the specified language. Languages\n" |
+ " handled are currently C++, ANSI-C, C, and KR-C. The\n" |
+ " default is C.\n"); |
+ fprintf (stream, "\n"); |
+ fprintf (stream, |
+ "Details in the output code:\n"); |
+ fprintf (stream, |
+ " -K, --slot-name=NAME Select name of the keyword component in the keyword\n" |
+ " structure.\n"); |
+ fprintf (stream, |
+ " -F, --initializer-suffix=INITIALIZERS\n" |
+ " Initializers for additional components in the keyword\n" |
+ " structure.\n"); |
+ fprintf (stream, |
+ " -H, --hash-function-name=NAME\n" |
+ " Specify name of generated hash function. Default is\n" |
+ " 'hash'.\n"); |
+ fprintf (stream, |
+ " -N, --lookup-function-name=NAME\n" |
+ " Specify name of generated lookup function. Default\n" |
+ " name is 'in_word_set'.\n"); |
+ fprintf (stream, |
+ " -Z, --class-name=NAME Specify name of generated C++ class. Default name is\n" |
+ " 'Perfect_Hash'.\n"); |
+ fprintf (stream, |
+ " -7, --seven-bit Assume 7-bit characters.\n"); |
+ fprintf (stream, |
+ " -l, --compare-lengths Compare key lengths before trying a string\n" |
+ " comparison. This is necessary if the keywords\n" |
+ " contain NUL bytes. It also helps cut down on the\n" |
+ " number of string comparisons made during the lookup.\n"); |
+ fprintf (stream, |
+ " -c, --compare-strncmp Generate comparison code using strncmp rather than\n" |
+ " strcmp.\n"); |
+ fprintf (stream, |
+ " -C, --readonly-tables Make the contents of generated lookup tables\n" |
+ " constant, i.e., readonly.\n"); |
+ fprintf (stream, |
+ " -E, --enum Define constant values using an enum local to the\n" |
+ " lookup function rather than with defines.\n"); |
+ fprintf (stream, |
+ " -I, --includes Include the necessary system include file <string.h>\n" |
+ " at the beginning of the code.\n"); |
+ fprintf (stream, |
+ " -G, --global-table Generate the static table of keywords as a static\n" |
+ " global variable, rather than hiding it inside of the\n" |
+ " lookup function (which is the default behavior).\n"); |
+ fprintf (stream, |
+ " -P, --pic Optimize the generated table for inclusion in shared\n" |
+ " libraries. This reduces the startup time of programs\n" |
+ " using a shared library containing the generated code.\n"); |
+ fprintf (stream, |
+ " -Q, --string-pool-name=NAME\n" |
+ " Specify name of string pool generated by option --pic.\n" |
+ " Default name is 'stringpool'.\n"); |
+ fprintf (stream, |
+ " --null-strings Use NULL strings instead of empty strings for empty\n" |
+ " keyword table entries.\n"); |
+ fprintf (stream, |
+ " -W, --word-array-name=NAME\n" |
+ " Specify name of word list array. Default name is\n" |
+ " 'wordlist'.\n"); |
+ fprintf (stream, |
+ " -S, --switch=COUNT Causes the generated C code to use a switch\n" |
+ " statement scheme, rather than an array lookup table.\n" |
+ " This can lead to a reduction in both time and space\n" |
+ " requirements for some keyfiles. The COUNT argument\n" |
+ " determines how many switch statements are generated.\n" |
+ " A value of 1 generates 1 switch containing all the\n" |
+ " elements, a value of 2 generates 2 tables with 1/2\n" |
+ " the elements in each table, etc. If COUNT is very\n" |
+ " large, say 1000000, the generated C code does a\n" |
+ " binary search.\n"); |
+ fprintf (stream, |
+ " -T, --omit-struct-type\n" |
+ " Prevents the transfer of the type declaration to the\n" |
+ " output file. Use this option if the type is already\n" |
+ " defined elsewhere.\n"); |
+ fprintf (stream, "\n"); |
+ fprintf (stream, |
+ "Algorithm employed by gperf:\n"); |
+ fprintf (stream, |
+ " -k, --key-positions=KEYS\n" |
+ " Select the key positions used in the hash function.\n" |
+ " The allowable choices range between 1-%d, inclusive.\n" |
+ " The positions are separated by commas, ranges may be\n" |
+ " used, and key positions may occur in any order.\n" |
+ " Also, the meta-character '*' causes the generated\n" |
+ " hash function to consider ALL key positions, and $\n" |
+ " indicates the \"final character\" of a key, e.g.,\n" |
+ " $,1,2,4,6-10.\n", |
+ Positions::MAX_KEY_POS); |
+ fprintf (stream, |
+ " -D, --duplicates Handle keywords that hash to duplicate values. This\n" |
+ " is useful for certain highly redundant keyword sets.\n"); |
+ fprintf (stream, |
+ " -m, --multiple-iterations=ITERATIONS\n" |
+ " Perform multiple choices of the -i and -j values,\n" |
+ " and choose the best results. This increases the\n" |
+ " running time by a factor of ITERATIONS but does a\n" |
+ " good job minimizing the generated table size.\n"); |
+ fprintf (stream, |
+ " -i, --initial-asso=N Provide an initial value for the associate values\n" |
+ " array. Default is 0. Setting this value larger helps\n" |
+ " inflate the size of the final table.\n"); |
+ fprintf (stream, |
+ " -j, --jump=JUMP-VALUE Affects the \"jump value\", i.e., how far to advance\n" |
+ " the associated character value upon collisions. Must\n" |
+ " be an odd number, default is %d.\n", |
+ DEFAULT_JUMP_VALUE); |
+ fprintf (stream, |
+ " -n, --no-strlen Do not include the length of the keyword when\n" |
+ " computing the hash function.\n"); |
+ fprintf (stream, |
+ " -r, --random Utilizes randomness to initialize the associated\n" |
+ " values table.\n"); |
+ fprintf (stream, |
+ " -s, --size-multiple=N Affects the size of the generated hash table. The\n" |
+ " numeric argument N indicates \"how many times larger\n" |
+ " or smaller\" the associated value range should be,\n" |
+ " in relationship to the number of keys, e.g. a value\n" |
+ " of 3 means \"allow the maximum associated value to\n" |
+ " be about 3 times larger than the number of input\n" |
+ " keys\". Conversely, a value of 1/3 means \"make the\n" |
+ " maximum associated value about 3 times smaller than\n" |
+ " the number of input keys\". A larger table should\n" |
+ " decrease the time required for an unsuccessful\n" |
+ " search, at the expense of extra table space. Default\n" |
+ " value is 1.\n"); |
+ fprintf (stream, "\n"); |
+ fprintf (stream, |
+ "Informative output:\n" |
+ " -h, --help Print this message.\n" |
+ " -v, --version Print the gperf version number.\n" |
+ " -d, --debug Enables the debugging option (produces verbose\n" |
+ " output to the standard error).\n"); |
+ fprintf (stream, "\n"); |
+ fprintf (stream, |
+ "Report bugs to <bug-gnu-gperf@gnu.org>.\n"); |
+} |
+ |
+/* Prints the given options. */ |
+ |
+void |
+Options::print_options () const |
+{ |
+ printf ("/* Command-line: "); |
+ |
+ for (int i = 0; i < _argument_count; i++) |
+ { |
+ const char *arg = _argument_vector[i]; |
+ |
+ /* Escape arg if it contains shell metacharacters. */ |
+ if (*arg == '-') |
+ { |
+ putchar (*arg); |
+ arg++; |
+ if (*arg >= 'A' && *arg <= 'Z' || *arg >= 'a' && *arg <= 'z') |
+ { |
+ putchar (*arg); |
+ arg++; |
+ } |
+ else if (*arg == '-') |
+ { |
+ do |
+ { |
+ putchar (*arg); |
+ arg++; |
+ } |
+ while (*arg >= 'A' && *arg <= 'Z' || *arg >= 'a' && *arg <= 'z' || *arg == '-'); |
+ if (*arg == '=') |
+ { |
+ putchar (*arg); |
+ arg++; |
+ } |
+ } |
+ } |
+ if (strpbrk (arg, "\t\n !\"#$&'()*;<>?[\\]`{|}~") != NULL) |
+ { |
+ if (strchr (arg, '\'') != NULL) |
+ { |
+ putchar ('"'); |
+ for (; *arg; arg++) |
+ { |
+ if (*arg == '\"' || *arg == '\\' || *arg == '$' || *arg == '`') |
+ putchar ('\\'); |
+ putchar (*arg); |
+ } |
+ putchar ('"'); |
+ } |
+ else |
+ { |
+ putchar ('\''); |
+ for (; *arg; arg++) |
+ { |
+ if (*arg == '\\') |
+ putchar ('\\'); |
+ putchar (*arg); |
+ } |
+ putchar ('\''); |
+ } |
+ } |
+ else |
+ printf ("%s", arg); |
+ |
+ printf (" "); |
+ } |
+ |
+ printf (" */"); |
+} |
+ |
+/* ------------------------------------------------------------------------- */ |
+ |
+/* Parses a string denoting key positions. */ |
+ |
+class PositionStringParser |
+{ |
+public: |
+ /* Initializes a key position string parser for string STR. */ |
+ PositionStringParser (const char *str, |
+ int low_bound, int high_bound, |
+ int end_word_marker, int error_value, int end_marker); |
+ /* Returns the next key position from the given string. */ |
+ int nextPosition (); |
+private: |
+ /* A pointer to the string provided by the user. */ |
+ const char * _str; |
+ /* Smallest possible value, inclusive. */ |
+ int const _low_bound; |
+ /* Greatest possible value, inclusive. */ |
+ int const _high_bound; |
+ /* A value marking the abstract "end of word" ( usually '$'). */ |
+ int const _end_word_marker; |
+ /* Error value returned when input is syntactically erroneous. */ |
+ int const _error_value; |
+ /* Value returned after last key is processed. */ |
+ int const _end_marker; |
+ /* Intermediate state for producing a range of positions. */ |
+ bool _in_range; /* True while producing a range of positions. */ |
+ int _range_upper_bound; /* Upper bound (inclusive) of the range. */ |
+ int _range_curr_value; /* Last value returned. */ |
+}; |
+ |
+/* Initializes a key position strng parser for string STR. */ |
+PositionStringParser::PositionStringParser (const char *str, |
+ int low_bound, int high_bound, |
+ int end_word_marker, int error_value, int end_marker) |
+ : _str (str), |
+ _low_bound (low_bound), |
+ _high_bound (high_bound), |
+ _end_word_marker (end_word_marker), |
+ _error_value (error_value), |
+ _end_marker (end_marker), |
+ _in_range (false) |
+{ |
+} |
+ |
+/* Returns the next key position from the given string. */ |
+int |
+PositionStringParser::nextPosition () |
+{ |
+ if (_in_range) |
+ { |
+ /* We are inside a range. Return the next value from the range. */ |
+ if (++_range_curr_value >= _range_upper_bound) |
+ _in_range = false; |
+ return _range_curr_value; |
+ } |
+ else |
+ { |
+ /* Continue parsing the given string. */ |
+ while (*_str) |
+ switch (*_str) |
+ { |
+ case ',': |
+ /* Skip the comma. */ |
+ _str++; |
+ break; |
+ case '$': |
+ /* Valid key position. */ |
+ _str++; |
+ return _end_word_marker; |
+ case '0': case '1': case '2': case '3': case '4': |
+ case '5': case '6': case '7': case '8': case '9': |
+ /* Valid key position. */ |
+ { |
+ int curr_value; |
+ for (curr_value = 0; isdigit (static_cast<unsigned char>(*_str)); _str++) |
+ curr_value = curr_value * 10 + (*_str - '0'); |
+ |
+ if (*_str == '-') |
+ { |
+ _str++; |
+ /* Starting a range of key positions. */ |
+ _in_range = true; |
+ |
+ for (_range_upper_bound = 0; |
+ isdigit (static_cast<unsigned char>(*_str)); |
+ _str++) |
+ _range_upper_bound = _range_upper_bound * 10 + (*_str - '0'); |
+ |
+ /* Verify range's upper bound. */ |
+ if (!(_range_upper_bound > curr_value && _range_upper_bound <= _high_bound)) |
+ return _error_value; |
+ _range_curr_value = curr_value; |
+ } |
+ |
+ /* Verify range's lower bound. */ |
+ if (!(curr_value >= _low_bound && curr_value <= _high_bound)) |
+ return _error_value; |
+ return curr_value; |
+ } |
+ default: |
+ /* Invalid syntax. */ |
+ return _error_value; |
+ } |
+ |
+ return _end_marker; |
+ } |
+} |
+ |
+/* ------------------------------------------------------------------------- */ |
+ |
+/* Sets the default Options. */ |
+ |
+Options::Options () |
+ : _option_word (C), |
+ _input_file_name (NULL), |
+ _output_file_name (NULL), |
+ _language (NULL), |
+ _jump (DEFAULT_JUMP_VALUE), |
+ _initial_asso_value (0), |
+ _asso_iterations (0), |
+ _total_switches (1), |
+ _size_multiple (1), |
+ _function_name (DEFAULT_FUNCTION_NAME), |
+ _slot_name (DEFAULT_SLOT_NAME), |
+ _initializer_suffix (DEFAULT_INITIALIZER_SUFFIX), |
+ _class_name (DEFAULT_CLASS_NAME), |
+ _hash_name (DEFAULT_HASH_NAME), |
+ _wordlist_name (DEFAULT_WORDLIST_NAME), |
+ _stringpool_name (DEFAULT_STRINGPOOL_NAME), |
+ _delimiters (DEFAULT_DELIMITERS), |
+ _key_positions () |
+{ |
+} |
+ |
+/* Dumps option status when debugging is enabled. */ |
+ |
+Options::~Options () |
+{ |
+ if (_option_word & DEBUG) |
+ { |
+ fprintf (stderr, "\ndumping Options:" |
+ "\nTYPE is........: %s" |
+ "\nUPPERLOWER is..: %s" |
+ "\nKRC is.........: %s" |
+ "\nC is...........: %s" |
+ "\nANSIC is.......: %s" |
+ "\nCPLUSPLUS is...: %s" |
+ "\nSEVENBIT is....: %s" |
+ "\nLENTABLE is....: %s" |
+ "\nCOMP is........: %s" |
+ "\nCONST is.......: %s" |
+ "\nENUM is........: %s" |
+ "\nINCLUDE is.....: %s" |
+ "\nGLOBAL is......: %s" |
+ "\nNULLSTRINGS is.: %s" |
+ "\nSHAREDLIB is...: %s" |
+ "\nSWITCH is......: %s" |
+ "\nNOTYPE is......: %s" |
+ "\nDUP is.........: %s" |
+ "\nNOLENGTH is....: %s" |
+ "\nRANDOM is......: %s" |
+ "\nDEBUG is.......: %s" |
+ "\nlookup function name = %s" |
+ "\nhash function name = %s" |
+ "\nword list name = %s" |
+ "\nstring pool name = %s" |
+ "\nslot name = %s" |
+ "\ninitializer suffix = %s" |
+ "\nasso_values iterations = %d" |
+ "\njump value = %d" |
+ "\nhash table size multiplier = %g" |
+ "\ninitial associated value = %d" |
+ "\ndelimiters = %s" |
+ "\nnumber of switch statements = %d\n", |
+ _option_word & TYPE ? "enabled" : "disabled", |
+ _option_word & UPPERLOWER ? "enabled" : "disabled", |
+ _option_word & KRC ? "enabled" : "disabled", |
+ _option_word & C ? "enabled" : "disabled", |
+ _option_word & ANSIC ? "enabled" : "disabled", |
+ _option_word & CPLUSPLUS ? "enabled" : "disabled", |
+ _option_word & SEVENBIT ? "enabled" : "disabled", |
+ _option_word & LENTABLE ? "enabled" : "disabled", |
+ _option_word & COMP ? "enabled" : "disabled", |
+ _option_word & CONST ? "enabled" : "disabled", |
+ _option_word & ENUM ? "enabled" : "disabled", |
+ _option_word & INCLUDE ? "enabled" : "disabled", |
+ _option_word & GLOBAL ? "enabled" : "disabled", |
+ _option_word & NULLSTRINGS ? "enabled" : "disabled", |
+ _option_word & SHAREDLIB ? "enabled" : "disabled", |
+ _option_word & SWITCH ? "enabled" : "disabled", |
+ _option_word & NOTYPE ? "enabled" : "disabled", |
+ _option_word & DUP ? "enabled" : "disabled", |
+ _option_word & NOLENGTH ? "enabled" : "disabled", |
+ _option_word & RANDOM ? "enabled" : "disabled", |
+ _option_word & DEBUG ? "enabled" : "disabled", |
+ _function_name, _hash_name, _wordlist_name, _stringpool_name, |
+ _slot_name, _initializer_suffix, _asso_iterations, _jump, |
+ _size_multiple, _initial_asso_value, _delimiters, |
+ _total_switches); |
+ if (_key_positions.is_useall()) |
+ fprintf (stderr, "all characters are used in the hash function\n"); |
+ else |
+ { |
+ fprintf (stderr, "maximum keysig size = %d\nkey positions are: \n", |
+ _key_positions.get_size()); |
+ |
+ PositionIterator iter = _key_positions.iterator(); |
+ for (int pos; (pos = iter.next()) != PositionIterator::EOS; ) |
+ if (pos == Positions::LASTCHAR) |
+ fprintf (stderr, "$\n"); |
+ else |
+ fprintf (stderr, "%d\n", pos + 1); |
+ } |
+ |
+ fprintf (stderr, "finished dumping Options\n"); |
+ } |
+} |
+ |
+ |
+/* Sets the output language, if not already set. */ |
+void |
+Options::set_language (const char *language) |
+{ |
+ if (_language == NULL) |
+ { |
+ _language = language; |
+ _option_word &= ~(KRC | C | ANSIC | CPLUSPLUS); |
+ if (!strcmp (language, "KR-C")) |
+ _option_word |= KRC; |
+ else if (!strcmp (language, "C")) |
+ _option_word |= C; |
+ else if (!strcmp (language, "ANSI-C")) |
+ _option_word |= ANSIC; |
+ else if (!strcmp (language, "C++")) |
+ _option_word |= CPLUSPLUS; |
+ else |
+ { |
+ fprintf (stderr, "unsupported language option %s, defaulting to C\n", |
+ language); |
+ _option_word |= C; |
+ } |
+ } |
+} |
+ |
+/* Sets the total number of switch statements, if not already set. */ |
+void |
+Options::set_total_switches (int total_switches) |
+{ |
+ if (!(_option_word & SWITCH)) |
+ { |
+ _option_word |= SWITCH; |
+ _total_switches = total_switches; |
+ } |
+} |
+ |
+/* Sets the generated function name, if not already set. */ |
+void |
+Options::set_function_name (const char *name) |
+{ |
+ if (_function_name == DEFAULT_FUNCTION_NAME) |
+ _function_name = name; |
+} |
+ |
+/* Sets the keyword key name, if not already set. */ |
+void |
+Options::set_slot_name (const char *name) |
+{ |
+ if (_slot_name == DEFAULT_SLOT_NAME) |
+ _slot_name = name; |
+} |
+ |
+/* Sets the struct initializer suffix, if not already set. */ |
+void |
+Options::set_initializer_suffix (const char *initializers) |
+{ |
+ if (_initializer_suffix == DEFAULT_INITIALIZER_SUFFIX) |
+ _initializer_suffix = initializers; |
+} |
+ |
+/* Sets the generated class name, if not already set. */ |
+void |
+Options::set_class_name (const char *name) |
+{ |
+ if (_class_name == DEFAULT_CLASS_NAME) |
+ _class_name = name; |
+} |
+ |
+/* Sets the hash function name, if not already set. */ |
+void |
+Options::set_hash_name (const char *name) |
+{ |
+ if (_hash_name == DEFAULT_HASH_NAME) |
+ _hash_name = name; |
+} |
+ |
+/* Sets the hash table array name, if not already set. */ |
+void |
+Options::set_wordlist_name (const char *name) |
+{ |
+ if (_wordlist_name == DEFAULT_WORDLIST_NAME) |
+ _wordlist_name = name; |
+} |
+ |
+/* Sets the string pool name, if not already set. */ |
+void |
+Options::set_stringpool_name (const char *name) |
+{ |
+ if (_stringpool_name == DEFAULT_STRINGPOOL_NAME) |
+ _stringpool_name = name; |
+} |
+ |
+/* Sets the delimiters string, if not already set. */ |
+void |
+Options::set_delimiters (const char *delimiters) |
+{ |
+ if (_delimiters == DEFAULT_DELIMITERS) |
+ _delimiters = delimiters; |
+} |
+ |
+ |
+/* Parses the command line Options and sets appropriate flags in option_word. */ |
+ |
+static const struct option long_options[] = |
+{ |
+ { "output-file", required_argument, NULL, CHAR_MAX + 1 }, |
+ { "ignore-case", no_argument, NULL, CHAR_MAX + 2 }, |
+ { "delimiters", required_argument, NULL, 'e' }, |
+ { "struct-type", no_argument, NULL, 't' }, |
+ { "language", required_argument, NULL, 'L' }, |
+ { "slot-name", required_argument, NULL, 'K' }, |
+ { "initializer-suffix", required_argument, NULL, 'F' }, |
+ { "hash-fn-name", required_argument, NULL, 'H' }, /* backward compatibility */ |
+ { "hash-function-name", required_argument, NULL, 'H' }, |
+ { "lookup-fn-name", required_argument, NULL, 'N' }, /* backward compatibility */ |
+ { "lookup-function-name", required_argument, NULL, 'N' }, |
+ { "class-name", required_argument, NULL, 'Z' }, |
+ { "seven-bit", no_argument, NULL, '7' }, |
+ { "compare-strncmp", no_argument, NULL, 'c' }, |
+ { "readonly-tables", no_argument, NULL, 'C' }, |
+ { "enum", no_argument, NULL, 'E' }, |
+ { "includes", no_argument, NULL, 'I' }, |
+ { "global-table", no_argument, NULL, 'G' }, |
+ { "word-array-name", required_argument, NULL, 'W' }, |
+ { "switch", required_argument, NULL, 'S' }, |
+ { "omit-struct-type", no_argument, NULL, 'T' }, |
+ { "key-positions", required_argument, NULL, 'k' }, |
+ { "compare-strlen", no_argument, NULL, 'l' }, /* backward compatibility */ |
+ { "compare-lengths", no_argument, NULL, 'l' }, |
+ { "duplicates", no_argument, NULL, 'D' }, |
+ { "fast", required_argument, NULL, 'f' }, |
+ { "initial-asso", required_argument, NULL, 'i' }, |
+ { "jump", required_argument, NULL, 'j' }, |
+ { "multiple-iterations", required_argument, NULL, 'm' }, |
+ { "no-strlen", no_argument, NULL, 'n' }, |
+ { "occurrence-sort", no_argument, NULL, 'o' }, |
+ { "optimized-collision-resolution", no_argument, NULL, 'O' }, |
+ { "pic", no_argument, NULL, 'P' }, |
+ { "string-pool-name", required_argument, NULL, 'Q' }, |
+ { "null-strings", no_argument, NULL, CHAR_MAX + 3 }, |
+ { "random", no_argument, NULL, 'r' }, |
+ { "size-multiple", required_argument, NULL, 's' }, |
+ { "help", no_argument, NULL, 'h' }, |
+ { "version", no_argument, NULL, 'v' }, |
+ { "debug", no_argument, NULL, 'd' }, |
+ { NULL, no_argument, NULL, 0 } |
+}; |
+ |
+void |
+Options::parse_options (int argc, char *argv[]) |
+{ |
+ int option_char; |
+ |
+ program_name = argv[0]; |
+ _argument_count = argc; |
+ _argument_vector = argv; |
+ |
+ while ((option_char = |
+ getopt_long (_argument_count, _argument_vector, |
+ "acCdDe:Ef:F:gGhH:i:Ij:k:K:lL:m:nN:oOpPQ:rs:S:tTvW:Z:7", |
+ long_options, NULL)) |
+ != -1) |
+ { |
+ switch (option_char) |
+ { |
+ case 'a': /* Generated code uses the ANSI prototype format. */ |
+ break; /* This is now the default. */ |
+ case 'c': /* Generate strncmp rather than strcmp. */ |
+ { |
+ _option_word |= COMP; |
+ break; |
+ } |
+ case 'C': /* Make the generated tables readonly (const). */ |
+ { |
+ _option_word |= CONST; |
+ break; |
+ } |
+ case 'd': /* Enable debugging option. */ |
+ { |
+ _option_word |= DEBUG; |
+ fprintf (stderr, "Starting program %s, version %s, with debugging on.\n", |
+ program_name, version_string); |
+ break; |
+ } |
+ case 'D': /* Enable duplicate option. */ |
+ { |
+ _option_word |= DUP; |
+ break; |
+ } |
+ case 'e': /* Specify keyword/attribute separator */ |
+ { |
+ _delimiters = /*getopt*/optarg; |
+ break; |
+ } |
+ case 'E': |
+ { |
+ _option_word |= ENUM; |
+ break; |
+ } |
+ case 'f': /* Generate the hash table "fast". */ |
+ break; /* Not needed any more. */ |
+ case 'F': |
+ { |
+ _initializer_suffix = /*getopt*/optarg; |
+ break; |
+ } |
+ case 'g': /* Use the 'inline' keyword for generated sub-routines, ifdef __GNUC__. */ |
+ break; /* This is now the default. */ |
+ case 'G': /* Make the keyword table a global variable. */ |
+ { |
+ _option_word |= GLOBAL; |
+ break; |
+ } |
+ case 'h': /* Displays a list of helpful Options to the user. */ |
+ { |
+ long_usage (stdout); |
+ exit (0); |
+ } |
+ case 'H': /* Sets the name for the hash function. */ |
+ { |
+ _hash_name = /*getopt*/optarg; |
+ break; |
+ } |
+ case 'i': /* Sets the initial value for the associated values array. */ |
+ { |
+ if ((_initial_asso_value = atoi (/*getopt*/optarg)) < 0) |
+ fprintf (stderr, "Initial value %d should be non-zero, ignoring and continuing.\n", _initial_asso_value); |
+ if (option[RANDOM]) |
+ fprintf (stderr, "warning, -r option superceeds -i, ignoring -i option and continuing\n"); |
+ break; |
+ } |
+ case 'I': /* Enable #include statements. */ |
+ { |
+ _option_word |= INCLUDE; |
+ break; |
+ } |
+ case 'j': /* Sets the jump value, must be odd for later algorithms. */ |
+ { |
+ if ((_jump = atoi (/*getopt*/optarg)) < 0) |
+ { |
+ fprintf (stderr, "Jump value %d must be a positive number.\n", _jump); |
+ short_usage (stderr); |
+ exit (1); |
+ } |
+ else if (_jump && ((_jump % 2) == 0)) |
+ fprintf (stderr, "Jump value %d should be odd, adding 1 and continuing...\n", _jump++); |
+ break; |
+ } |
+ case 'k': /* Sets key positions used for hash function. */ |
+ { |
+ _option_word |= POSITIONS; |
+ const int BAD_VALUE = -3; |
+ const int EOS = PositionIterator::EOS; |
+ int value; |
+ PositionStringParser sparser (/*getopt*/optarg, 1, Positions::MAX_KEY_POS, Positions::LASTCHAR, BAD_VALUE, EOS); |
+ |
+ if (/*getopt*/optarg [0] == '*') /* Use all the characters for hashing!!!! */ |
+ _key_positions.set_useall(true); |
+ else |
+ { |
+ _key_positions.set_useall(false); |
+ int *key_positions = _key_positions.pointer(); |
+ int *key_pos; |
+ |
+ for (key_pos = key_positions; (value = sparser.nextPosition()) != EOS; key_pos++) |
+ { |
+ if (value == BAD_VALUE) |
+ { |
+ fprintf (stderr, "Invalid position value or range, use 1,2,3-%d,'$' or '*'.\n", |
+ Positions::MAX_KEY_POS); |
+ short_usage (stderr); |
+ exit (1); |
+ } |
+ if (key_pos - key_positions == Positions::MAX_SIZE) |
+ { |
+ /* More than Positions::MAX_SIZE key positions. |
+ Since all key positions are in the range |
+ 0..Positions::MAX_KEY_POS-1 or == Positions::LASTCHAR, |
+ there must be duplicates. */ |
+ fprintf (stderr, "Duplicate key positions selected\n"); |
+ short_usage (stderr); |
+ exit (1); |
+ } |
+ if (value != Positions::LASTCHAR) |
+ /* We use 0-based indices in the class Positions. */ |
+ value = value - 1; |
+ *key_pos = value; |
+ } |
+ |
+ unsigned int total_keysig_size = key_pos - key_positions; |
+ if (total_keysig_size == 0) |
+ { |
+ fprintf (stderr, "No key positions selected.\n"); |
+ short_usage (stderr); |
+ exit (1); |
+ } |
+ _key_positions.set_size (total_keysig_size); |
+ |
+ /* Sorts the key positions *IN REVERSE ORDER!!* |
+ This makes further routines more efficient. Especially |
+ when generating code. */ |
+ if (! _key_positions.sort()) |
+ { |
+ fprintf (stderr, "Duplicate key positions selected\n"); |
+ short_usage (stderr); |
+ exit (1); |
+ } |
+ } |
+ break; |
+ } |
+ case 'K': /* Make this the keyname for the keyword component field. */ |
+ { |
+ _slot_name = /*getopt*/optarg; |
+ break; |
+ } |
+ case 'l': /* Create length table to avoid extra string compares. */ |
+ { |
+ _option_word |= LENTABLE; |
+ break; |
+ } |
+ case 'L': /* Deal with different generated languages. */ |
+ { |
+ _language = NULL; |
+ set_language (/*getopt*/optarg); |
+ break; |
+ } |
+ case 'm': /* Multiple iterations for finding good asso_values. */ |
+ { |
+ if ((_asso_iterations = atoi (/*getopt*/optarg)) < 0) |
+ { |
+ fprintf (stderr, "asso_iterations value must not be negative, assuming 0\n"); |
+ _asso_iterations = 0; |
+ } |
+ break; |
+ } |
+ case 'n': /* Don't include the length when computing hash function. */ |
+ { |
+ _option_word |= NOLENGTH; |
+ break; |
+ } |
+ case 'N': /* Make generated lookup function name be optarg. */ |
+ { |
+ _function_name = /*getopt*/optarg; |
+ break; |
+ } |
+ case 'o': /* Order input by frequency of key set occurrence. */ |
+ break; /* Not needed any more. */ |
+ case 'O': /* Optimized choice during collision resolution. */ |
+ break; /* Not needed any more. */ |
+ case 'p': /* Generated lookup function a pointer instead of int. */ |
+ break; /* This is now the default. */ |
+ case 'P': /* Optimize for position-independent code. */ |
+ { |
+ _option_word |= SHAREDLIB; |
+ break; |
+ } |
+ case 'Q': /* Sets the name for the string pool. */ |
+ { |
+ _stringpool_name = /*getopt*/optarg; |
+ break; |
+ } |
+ case 'r': /* Utilize randomness to initialize the associated values table. */ |
+ { |
+ _option_word |= RANDOM; |
+ if (_initial_asso_value != 0) |
+ fprintf (stderr, "warning, -r option supersedes -i, disabling -i option and continuing\n"); |
+ break; |
+ } |
+ case 's': /* Range of associated values, determines size of final table. */ |
+ { |
+ float numerator; |
+ float denominator = 1; |
+ bool invalid = false; |
+ char *endptr; |
+ |
+ numerator = strtod (/*getopt*/optarg, &endptr); |
+ if (endptr == /*getopt*/optarg) |
+ invalid = true; |
+ else if (*endptr != '\0') |
+ { |
+ if (*endptr == '/') |
+ { |
+ char *denomptr = endptr + 1; |
+ denominator = strtod (denomptr, &endptr); |
+ if (endptr == denomptr || *endptr != '\0') |
+ invalid = true; |
+ } |
+ else |
+ invalid = true; |
+ } |
+ if (invalid) |
+ { |
+ fprintf (stderr, "Invalid value for option -s.\n"); |
+ short_usage (stderr); |
+ exit (1); |
+ } |
+ _size_multiple = numerator / denominator; |
+ /* Backward compatibility: -3 means 1/3. */ |
+ if (_size_multiple < 0) |
+ _size_multiple = 1 / (-_size_multiple); |
+ /* Catch stupid users. */ |
+ if (_size_multiple == 0) |
+ _size_multiple = 1; |
+ /* Warnings. */ |
+ if (_size_multiple > 50) |
+ fprintf (stderr, "Size multiple %g is excessive, did you really mean this?! (try '%s --help' for help)\n", _size_multiple, program_name); |
+ else if (_size_multiple < 0.01f) |
+ fprintf (stderr, "Size multiple %g is extremely small, did you really mean this?! (try '%s --help' for help)\n", _size_multiple, program_name); |
+ break; |
+ } |
+ case 'S': /* Generate switch statement output, rather than lookup table. */ |
+ { |
+ _option_word |= SWITCH; |
+ _total_switches = atoi (/*getopt*/optarg); |
+ if (_total_switches <= 0) |
+ { |
+ fprintf (stderr, "number of switches %s must be a positive number\n", /*getopt*/optarg); |
+ short_usage (stderr); |
+ exit (1); |
+ } |
+ break; |
+ } |
+ case 't': /* Enable the TYPE mode, allowing arbitrary user structures. */ |
+ { |
+ _option_word |= TYPE; |
+ break; |
+ } |
+ case 'T': /* Don't print structure definition. */ |
+ { |
+ _option_word |= NOTYPE; |
+ break; |
+ } |
+ case 'v': /* Print out the version and quit. */ |
+ fprintf (stdout, "GNU gperf %s\n", version_string); |
+ fprintf (stdout, "Copyright (C) %s Free Software Foundation, Inc.\n\ |
+This is free software; see the source for copying conditions. There is NO\n\ |
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ |
+", |
+ "1989-1998, 2000-2003"); |
+ fprintf (stdout, "Written by %s and %s.\n", |
+ "Douglas C. Schmidt", "Bruno Haible"); |
+ exit (0); |
+ case 'W': /* Sets the name for the hash table array. */ |
+ { |
+ _wordlist_name = /*getopt*/optarg; |
+ break; |
+ } |
+ case 'Z': /* Set the class name. */ |
+ { |
+ _class_name = /*getopt*/optarg; |
+ break; |
+ } |
+ case '7': /* Assume 7-bit characters. */ |
+ { |
+ _option_word |= SEVENBIT; |
+ break; |
+ } |
+ case CHAR_MAX + 1: /* Set the output file name. */ |
+ { |
+ _output_file_name = /*getopt*/optarg; |
+ break; |
+ } |
+ case CHAR_MAX + 2: /* Case insignificant. */ |
+ { |
+ _option_word |= UPPERLOWER; |
+ break; |
+ } |
+ case CHAR_MAX + 3: /* Use NULL instead of "". */ |
+ { |
+ _option_word |= NULLSTRINGS; |
+ break; |
+ } |
+ default: |
+ short_usage (stderr); |
+ exit (1); |
+ } |
+ |
+ } |
+ |
+ if (/*getopt*/optind < argc) |
+ _input_file_name = argv[/*getopt*/optind++]; |
+ |
+ if (/*getopt*/optind < argc) |
+ { |
+ fprintf (stderr, "Extra trailing arguments to %s.\n", program_name); |
+ short_usage (stderr); |
+ exit (1); |
+ } |
+} |
+ |
+/* ------------------------------------------------------------------------- */ |
+ |
+#ifndef __OPTIMIZE__ |
+ |
+#define INLINE /* not inline */ |
+#include "options.icc" |
+#undef INLINE |
+ |
+#endif /* not defined __OPTIMIZE__ */ |
Property changes on: gperf\src\gperf\3.0.1\gperf-3.0.1-src\src\options.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |