*** gperf/gperf.texi Thu Mar 17 23:35:13 1994 --- gperf-hacked/gperf.texi Thu May 18 18:45:13 1995 *************** *** 854,859 **** --- 854,863 ---- This option is probably most useful when used in conjunction with options @samp{-D} and/or @samp{-S} for @emph{large} keyword sets. + @item -F + Define constant values using global @code{const int} rather than with + @code{#define} or @code{enum} (@samp{-E}). + @item -g Assume a GNU compiler, @emph{e.g.}, @code{g++} or @code{gcc}. This makes all generated routines use the ``inline'' keyword to remove the *************** *** 882,887 **** --- 886,898 ---- option is not particularly useful when @samp{-S} is used. Also, @samp{-i} is overriden when the @samp{-r} option is used. + @item -I + Changes the return value of the generated function @code{in_word_set()} + from boolean (@emph{i.e.}, 0 or 1), to the index into the @code{wordlist} + array. In conjunction with the @samp{-t} and @samp{-V} options you can + access a keyword by @code{const char *} name (via @code{in_word_set()}) + or by @code{int} constant. + @item -j @var{jump value} Affects the ``jump value,'' @emph{i.e.}, how far to advance the associated character value upon collisions. @var{Jump value} is rounded *************** *** 1024,1029 **** --- 1035,1051 ---- @item -v Prints out the current version number. + + @item -V @var{pattern} + Outputs all valid indices into the @code{wordlist} array as constants. + Definition occurs by @code{#define}, @code{enum} or @code{const int} + depending on the @samp{-E} and @samp{-F} options. The name of the + command is generated from the @var{pattern} argument by replacing the + first occurence of @samp{%} or @samp{&} with the respective keyword. + This is useful if you want to identify a keyword by an @code{int} value, + which may be used in @code{switch} statements. (The @samp{-F}, @samp{-I} + and @samp{-V} options have been implemented by Gunther Schadow + ) @item -Z @var{class name} Allow user to specify name of generated C++ class. Default name is *** gperf/src/key-list.cc Sun Sep 18 07:03:27 1994 --- gperf-hacked/src/key-list.cc Thu May 18 17:57:54 1995 *************** *** 212,217 **** --- 212,220 ---- } else if (option[POINTER]) /* Return a char *. */ return_type = default_array_type; + + if (option[INDEX]) /* Return an int */ + return_type = "int "; } /* Reads in all keys from standard input and creates a linked list pointed *************** *** 470,480 **** min_hash_value = head->hash_value; max_hash_value = temp->hash_value; ! if (!option[ENUM]) printf ("\n#define TOTAL_KEYWORDS %d\n#define MIN_WORD_LENGTH %d" "\n#define MAX_WORD_LENGTH %d\n#define MIN_HASH_VALUE %d" "\n#define MAX_HASH_VALUE %d\n", total_keys, min_key_len, max_key_len, min_hash_value, max_hash_value); printf ("/* maximum key range = %d, duplicates = %d */\n\n", max_hash_value - min_hash_value + 1, total_duplicates); } --- 473,492 ---- min_hash_value = head->hash_value; max_hash_value = temp->hash_value; ! if (option[CONSTCONST]) ! printf ("\nconst int TOTAL_KEYWORDS = %d;" ! "\nconst int MIN_WORD_LENGTH = %d;" ! "\nconst int MAX_WORD_LENGTH = %d;" ! "\nconst int MIN_HASH_VALUE = %d;" ! "\nconst int MAX_HASH_VALUE = %d;\n", ! total_keys, min_key_len, ! max_key_len, min_hash_value, max_hash_value); ! else if (!option[ENUM]) printf ("\n#define TOTAL_KEYWORDS %d\n#define MIN_WORD_LENGTH %d" "\n#define MAX_WORD_LENGTH %d\n#define MIN_HASH_VALUE %d" "\n#define MAX_HASH_VALUE %d\n", total_keys, min_key_len, max_key_len, min_hash_value, max_hash_value); + printf ("/* maximum key range = %d, duplicates = %d */\n\n", max_hash_value - min_hash_value + 1, total_duplicates); } *************** *** 495,504 **** T (Trace t ("Key_List::output_switch");) char *comp_buffer; List_Node *curr = head; ! int pointer_and_type_enabled = option[POINTER] && option[TYPE]; int total_switches = option.get_total_switches (); int switch_size = keyword_list_length () / total_switches; if (pointer_and_type_enabled) { comp_buffer = (char *) alloca (strlen ("*str == *resword->%s && !strncmp (str + 1, resword->%s + 1, len - 1)") --- 507,518 ---- T (Trace t ("Key_List::output_switch");) char *comp_buffer; List_Node *curr = head; ! int pointer_and_type_enabled = ( option[POINTER] && option[TYPE] ) ! || option[INDEX]; int total_switches = option.get_total_switches (); int switch_size = keyword_list_length () / total_switches; + if (pointer_and_type_enabled) { comp_buffer = (char *) alloca (strlen ("*str == *resword->%s && !strncmp (str + 1, resword->%s + 1, len - 1)") *************** *** 540,553 **** /* Output each keyword as part of a switch statement indexed by hash value. */ ! if (option[POINTER] || option[DUP]) { int i = 0; printf (" %s%s *resword; %s\n\n", option[CONST] ? "const " : "", pointer_and_type_enabled ? struct_tag : "char", option[LENTABLE] && !option[DUP] ? "int key_len;" : ""); if (total_switches == 1) { printf (" switch (key)\n {\n"); --- 554,571 ---- /* Output each keyword as part of a switch statement indexed by hash value. */ ! if (option[POINTER] || option[DUP] || option[INDEX]) { int i = 0; + if(option[INDEX]) + printf (" int res;\n"); + printf (" %s%s *resword; %s\n\n", option[CONST] ? "const " : "", pointer_and_type_enabled ? struct_tag : "char", option[LENTABLE] && !option[DUP] ? "int key_len;" : ""); + if (total_switches == 1) { printf (" switch (key)\n {\n"); *************** *** 571,581 **** for (links = temp; links; links = links->link) { if (pointer_and_type_enabled) ! printf (" resword = &wordlist[%d];\n", links->index); else printf (" resword = \"%s\";\n", links->key); ! printf (" if (%s) return resword;\n", comp_buffer); } } /* Handle unresolved duplicate hash values. These are guaranteed --- 589,609 ---- for (links = temp; links; links = links->link) { + if (option[INDEX]) + printf (" res = %d;\n", + links->index); if (pointer_and_type_enabled) ! printf (" resword = &wordlist[%d];\n", ! links->index); else printf (" resword = \"%s\";\n", links->key); ! ! if (option[INDEX]) ! printf (" if (%s) return res;\n", ! comp_buffer); ! else ! printf (" if (%s) return resword;\n", ! comp_buffer); } } /* Handle unresolved duplicate hash values. These are guaranteed *************** *** 587,608 **** for ( ; temp->next && temp->hash_value == temp->next->hash_value; temp = temp->next) { if (pointer_and_type_enabled) printf (" resword = &wordlist[%d];\n", temp->index); else printf (" resword = \"%s\";\n", temp->key); ! printf (" if (%s) return resword;\n", comp_buffer); ! } if (pointer_and_type_enabled) printf (" resword = &wordlist[%d];\n", temp->index); else ! printf (" resword = \"%s\";\n", temp->key); ! printf (" return %s ? resword : 0;\n", comp_buffer); } else if (temp->link) ! printf (" return 0;\n"); else { if (pointer_and_type_enabled) printf (" resword = &wordlist[%d];", temp->index); else --- 615,659 ---- for ( ; temp->next && temp->hash_value == temp->next->hash_value; temp = temp->next) { + if (option[INDEX]) + printf (" res = %d;\n", + temp->index); if (pointer_and_type_enabled) printf (" resword = &wordlist[%d];\n", temp->index); else printf (" resword = \"%s\";\n", temp->key); ! ! if (option[INDEX]) ! printf (" if (%s) return res;\n", ! comp_buffer); ! else ! printf (" if (%s) return resword;\n", ! comp_buffer); ! } ! if (option[INDEX]) ! printf (" res = %d;\n", ! temp->index); if (pointer_and_type_enabled) printf (" resword = &wordlist[%d];\n", temp->index); else ! printf (" resword = \"%s\";\n", ! temp->key); ! ! if (option[INDEX]) ! printf (" return %s ? res : -1;\n", ! comp_buffer); ! else ! printf (" return %s ? resword : 0;\n", ! comp_buffer); } else if (temp->link) ! printf (" return %d;\n", ! option[INDEX] ? -1 : 0); else { + if (option[INDEX]) + printf (" res = %d;\n", + temp->index); if (pointer_and_type_enabled) printf (" resword = &wordlist[%d];", temp->index); else *************** *** 612,622 **** printf (" break;\n"); } } ! printf (" default: return 0;\n }\n"); printf (option[LENTABLE] && !option[DUP] ! ? " if (len == key_len && %s)\n return resword;\n" ! : " if (%s)\n return resword;\n", comp_buffer); ! printf (" return 0;\n }\n"); curr = temp; } else /* Nothing special required here. */ --- 663,677 ---- printf (" break;\n"); } } ! printf (" default: return %d;\n }\n", ! option[INDEX] ? -1 : 0); printf (option[LENTABLE] && !option[DUP] ! ? " if (len == key_len && %s)\n return %s;\n" ! : " if (%s)\n return %s;\n", ! comp_buffer, ! option[INDEX] ? "res" : "resword"); ! printf (" return %d;\n }\n", ! option[INDEX] ? -1 : 0); curr = temp; } else /* Nothing special required here. */ *************** *** 641,647 **** curr = temp; } } ! printf (" }\n }\n return 0;\n}\n"); } /* Prints out a table of keyword lengths, for use with the --- 696,703 ---- curr = temp; } } ! printf (" }\n }\n return %d;\n}\n", ! option[INDEX] ? -1 : 0); } /* Prints out a table of keyword lengths, for use with the *************** *** 677,682 **** --- 733,739 ---- printf ("\n%s%s};\n", indent, indent); } } + /* Prints out the array containing the key words for the Gen_Perf hash function. */ *************** *** 748,753 **** --- 805,879 ---- printf ("%s%s};\n\n", indent, indent); } + /* Prints out constants for keyword indices. */ + + void + Key_List::output_index_consts (void) + { + T (Trace t ("Key_List::output_index_consts");) + int index = head->hash_value; + List_Node *temp; + char *format; + + { + const char *pfx, *ifx, *sfx; + + /* initializes {pre,in,suf}fixes */ + + if(option[ENUM]) + { pfx = " "; ifx = " = "; sfx = ","; } + else if(option[CONSTCONST]) + { pfx = "const int "; ifx = " = "; sfx = ";"; } + else /* defines */ + { pfx = "#define "; ifx = " "; sfx = ""; } + + /* initialize format */ + + char *const_pattern = strdup(option.get_const_pattern()); + format = new char [strlen(pfx) + strlen(const_pattern) + + strlen(ifx) + strlen(sfx) + 6]; + strcpy(format, pfx); + char *fx = strsep(&const_pattern, "%&"); + strcat(format, fx != NULL ? fx : "" ); + strcat(format, "%s"); + fx = strsep(&const_pattern, ""); + strcat(format, fx != NULL ? fx : "" ); + strcat(format, ifx); + strcat(format, "%d"); + strcat(format, sfx); + strcat(format, "\n"); + + delete [] const_pattern; + } + + printf ("\n"); + + if(option[ENUM]) + printf ("enum indices {\n"); + + /* Generate constant definitions of valid indices. */ + + for (temp = head ; temp; temp = temp->next, index++) + { + if (!option[SWITCH] && (total_duplicates == 0 || !option[DUP]) && index < temp->hash_value) + { + index = temp->hash_value; + printf (format, temp->key, index); + continue; + } + + printf (format, temp->key, index); + + /* Deal with links specially. */ + if (temp->link) + for (List_Node *links = temp->link; links; links = links->link) + printf (format, links->key, ++index); + } + + if(option[ENUM]) + printf ("};"); + } + /* Generates C code for the hash function that returns the proper encoding for each key word. */ *************** *** 1032,1040 **** printf (";\n\n if (%s*s == *str && !%s)\n return %s;\n }\n", option[LENTABLE] ? "len == lengthtable[key]\n && " : "", option[COMP] ? "strncmp (str + 1, s + 1, len - 1)" : "strcmp (str + 1, s + 1)", option[TYPE] && option[POINTER] ? "&wordlist[index]" : "s"); printf (" else if (index < 0 && index >= -MAX_HASH_VALUE)\n" ! " return 0;\n else\n {\n" " register int offset = key + index + (index > 0 ? -MAX_HASH_VALUE : MAX_HASH_VALUE);\n" " register %s%s*base = &wordlist[-lookup[offset]];\n" " register %s%s*ptr = base + -lookup[offset + 1];\n\n" --- 1158,1170 ---- printf (";\n\n if (%s*s == *str && !%s)\n return %s;\n }\n", option[LENTABLE] ? "len == lengthtable[key]\n && " : "", option[COMP] ? "strncmp (str + 1, s + 1, len - 1)" : "strcmp (str + 1, s + 1)", + option[INDEX] ? "index" : option[TYPE] && option[POINTER] ? "&wordlist[index]" : "s"); printf (" else if (index < 0 && index >= -MAX_HASH_VALUE)\n" ! " return %s;\n", ! option[INDEX] ? "-1" : ! option[POINTER] ? "NULL" : "0"); ! printf (" else\n {\n" " register int offset = key + index + (index > 0 ? -MAX_HASH_VALUE : MAX_HASH_VALUE);\n" " register %s%s*base = &wordlist[-lookup[offset]];\n" " register %s%s*ptr = base + -lookup[offset + 1];\n\n" *************** *** 1047,1055 **** else printf ("if (*str == **ptr && !strcmp (str + 1, *ptr + 1"); ! printf ("))\n return %sptr;" ! "\n }\n }\n }\n return 0;\n}\n", array_type == default_array_type ? "*" : ""); ! } else { --- 1177,1189 ---- else printf ("if (*str == **ptr && !strcmp (str + 1, *ptr + 1"); ! printf ("))\n return %sptr%s;", ! option[INDEX] ? "" : ! array_type == default_array_type ? "*" : "", ! option[INDEX] ? " - &wordlist[0]" : ""); ! printf ("\n }\n }\n }\n return %s;\n}\n", ! option[INDEX] ? "-1" : ! option[POINTER] ? "NULL" : "0"); } else { *************** *** 1061,1068 **** printf (";\n\n if (%s*s == *str && !%s)\n return %s", option[LENTABLE] ? "len == lengthtable[key]\n && " : "", option[COMP] ? "strncmp (str + 1, s + 1, len - 1)" : "strcmp (str + 1, s + 1)", option[TYPE] && option[POINTER] ? "&wordlist[key]" : "s"); ! printf (";\n }\n }\n return 0;\n}\n"); } } --- 1195,1205 ---- printf (";\n\n if (%s*s == *str && !%s)\n return %s", option[LENTABLE] ? "len == lengthtable[key]\n && " : "", option[COMP] ? "strncmp (str + 1, s + 1, len - 1)" : "strcmp (str + 1, s + 1)", + option[INDEX] ? "key" : option[TYPE] && option[POINTER] ? "&wordlist[key]" : "s"); ! printf (";\n }\n }\n return %s;\n}\n", ! option[INDEX] ? "-1" : ! option[POINTER] ? "NULL" : "0"); } } *************** *** 1084,1090 **** printf ("class %s\n{\nprivate:\n" " static unsigned int hash (const char *str, int len);\npublic:\n" " static %s%s%s (const char *str, int len);\n};\n\n", ! option.get_class_name (), option[CONST] ? "const " : "", return_type, option.get_function_name ()); output_hash_function (); --- 1221,1228 ---- printf ("class %s\n{\nprivate:\n" " static unsigned int hash (const char *str, int len);\npublic:\n" " static %s%s%s (const char *str, int len);\n};\n\n", ! option.get_class_name (), ! option[CONST] && !option[INDEX] ? "const " : "", return_type, option.get_function_name ()); output_hash_function (); *************** *** 1094,1100 **** { if (option[LENTABLE] && option[DUP]) output_keylength_table (); ! if (option[POINTER] && option[TYPE]) output_keyword_table (); } else --- 1232,1238 ---- { if (option[LENTABLE] && option[DUP]) output_keylength_table (); ! if ((option[POINTER] && option[TYPE]) || option[INDEX]) output_keyword_table (); } else *************** *** 1108,1114 **** if (option[GNU]) /* Use the inline keyword to remove function overhead. */ printf ("#ifdef __GNUC__\ninline\n#endif\n"); ! printf ("%s%s\n", option[CONST] ? "const " : "", return_type); if (option[CPLUSPLUS]) printf ("%s::", option.get_class_name ()); --- 1246,1253 ---- if (option[GNU]) /* Use the inline keyword to remove function overhead. */ printf ("#ifdef __GNUC__\ninline\n#endif\n"); ! printf ("%s%s\n", ! option[CONST] && !option[INDEX] ? "const " : "", return_type); if (option[CPLUSPLUS]) printf ("%s::", option.get_class_name ()); *************** *** 1117,1123 **** : "%s (str, len)\n register char *str;\n register unsigned int len;\n{\n", option.get_function_name ()); ! if (option[ENUM]) printf (" enum\n {\n" " TOTAL_KEYWORDS = %d,\n" " MIN_WORD_LENGTH = %d,\n" --- 1256,1262 ---- : "%s (str, len)\n register char *str;\n register unsigned int len;\n{\n", option.get_function_name ()); ! if (option[ENUM] && !option[CONSTCONST]) printf (" enum\n {\n" " TOTAL_KEYWORDS = %d,\n" " MIN_WORD_LENGTH = %d,\n" *************** *** 1134,1140 **** { if (option[LENTABLE] && option[DUP]) output_keylength_table (); ! if (option[POINTER] && option[TYPE]) output_keyword_table (); } output_switch (); --- 1273,1279 ---- { if (option[LENTABLE] && option[DUP]) output_keylength_table (); ! if ((option[POINTER] && option[TYPE]) || option[INDEX]) output_keyword_table (); } output_switch (); *************** *** 1153,1158 **** --- 1292,1300 ---- output_lookup_function (); } + if (option[INDEXCONST]) + output_index_consts (); + if (additional_code) for (int c; (c = getchar ()) != EOF; putchar (c)) ; *** gperf/src/key-list.h Sat May 8 05:28:04 1993 --- gperf-hacked/src/key-list.h Thu May 18 16:40:47 1995 *************** *** 58,63 **** --- 58,64 ---- void output_min_max (void); void output_switch (void); void output_keyword_table (void); + void output_index_consts (void); void output_keylength_table (void); void output_hash_function (void); void output_lookup_function (void); *** gperf/src/options.cc Fri Nov 6 23:01:31 1992 --- gperf-hacked/src/options.cc Thu May 18 18:16:44 1995 *************** *** 64,69 **** --- 64,70 ---- const char *Options::class_name; const char *Options::hash_name; const char *Options::delimiters; + const char *Options::const_pattern = NULL; char Options::key_positions[MAX_KEY_POS]; /* Prints program usage to standard error stream. */ *************** *** 72,78 **** Options::usage (void) { T (Trace t ("Options::usage");) ! report_error ("Usage: %n [-acCdDef[num]gGhHijkKlLnNoprsStTvZ].\n" "(type %n -h for help)\n"); } --- 73,79 ---- Options::usage (void) { T (Trace t ("Options::usage");) ! report_error ("Usage: %n [-acCdDeEf[num]FgGhHiIjkKlLnNoprsStTvVZ].\n" "(type %n -h for help)\n"); } *************** *** 146,161 **** { char *ptr; ! fprintf (stderr, "\ndumping Options:\nDEBUG is.......: %s\nORDER is.......: %s" "\nANSI is........: %s\nTYPE is........: %s\nGNU is.........: %s" "\nRANDOM is......: %s\nDEFAULTCHARS is: %s\nSWITCH is......: %s" "\nPOINTER is.....: %s\nNOLENGTH is....: %s\nLENTABLE is....: %s" ! "\nDUP is.........: %s\nFAST is........: %s\nCOMP is.....: %s" ! "\nNOTYPE is......: %s\nGLOBAL is......: %s\nCONST is....: %s" ! "\nCPLUSPLUS is...: %s\nC is...........: %s\nENUM is.....: %s" "\niterations = %d\nlookup function name = %s\nhash function name = %s" "\nkey name = %s\njump value = %d\nmax associcated value = %d" ! "\ninitial associated value = %d\ndelimiters = %s\nnumber of switch statements = %d\n", option_word & DEBUG ? "enabled" : "disabled", option_word & ORDER ? "enabled" : "disabled", option_word & ANSI ? "enabled" : "disabled", --- 147,166 ---- { char *ptr; ! fprintf (stderr, "\ndumping Options:" ! "\nDEBUG is.......: %s\nORDER is.......: %s" "\nANSI is........: %s\nTYPE is........: %s\nGNU is.........: %s" "\nRANDOM is......: %s\nDEFAULTCHARS is: %s\nSWITCH is......: %s" "\nPOINTER is.....: %s\nNOLENGTH is....: %s\nLENTABLE is....: %s" ! "\nDUP is.........: %s\nFAST is........: %s\nCOMP is........: %s" ! "\nNOTYPE is......: %s\nGLOBAL is......: %s\nCONST is.......: %s" ! "\nCPLUSPLUS is...: %s\nC is...........: %s\nENUM is........: %s" ! "\nCONSTCONST is..: %s\nINDEX is ......: %s\nINDEXCONST is..: %s" "\niterations = %d\nlookup function name = %s\nhash function name = %s" "\nkey name = %s\njump value = %d\nmax associcated value = %d" ! "\ninitial associated value = %d\ndelimiters = %s" ! "\nnumber of switch statements = %d\n" ! "\npattern for index constants = `%s'\n", option_word & DEBUG ? "enabled" : "disabled", option_word & ORDER ? "enabled" : "disabled", option_word & ANSI ? "enabled" : "disabled", *************** *** 176,183 **** option_word & CPLUSPLUS ? "enabled" : "disabled", option_word & C ? "enabled" : "disabled", option_word & ENUM ? "enabled" : "disabled", iterations, function_name, hash_name, key_name, jump, size - 1, ! initial_asso_value, delimiters, total_switches); if (option_word & ALLCHARS) fprintf (stderr, "all characters are used in the hash function\n"); --- 181,191 ---- option_word & CPLUSPLUS ? "enabled" : "disabled", option_word & C ? "enabled" : "disabled", option_word & ENUM ? "enabled" : "disabled", + option_word & CONSTCONST ? "enabled" : "disabled", + option_word & INDEX ? "enabled" : "disabled", + option_word & INDEXCONST ? "enabled" : "disabled", iterations, function_name, hash_name, key_name, jump, size - 1, ! initial_asso_value, delimiters, total_switches, const_pattern); if (option_word & ALLCHARS) fprintf (stderr, "all characters are used in the hash function\n"); *************** *** 201,207 **** Options::operator() (int argc, char *argv[]) { T (Trace t ("Options::operator()");) ! GetOpt getopt (argc, argv, "adcCDe:Ef:gGhH:i:j:k:K:lL:nN:oprs:S:tTvZ:"); int option_char; set_program_name (argv[0]); --- 209,215 ---- Options::operator() (int argc, char *argv[]) { T (Trace t ("Options::operator()");) ! GetOpt getopt (argc, argv, "adcCDe:Ef:FgGhH:i:Ij:k:K:lL:nN:oprs:S:tTvV:Z:"); int option_char; set_program_name (argv[0]); *************** *** 247,252 **** --- 255,261 ---- case 'E': { option_word |= ENUM; + option_word &= ~CONSTCONST; break; } case 'f': /* Generate the hash table ``fast.'' */ *************** *** 259,264 **** --- 268,279 ---- } break; } + case 'F': + { + option_word |= CONSTCONST; + option_word &= ~ENUM; + break; + } case 'g': /* Use the ``inline'' keyword for generated sub-routines. */ { option_word |= GNU; *************** *** 286,291 **** --- 301,308 ---- "\trunning time at the cost of minimizing generated table-size.\n" "\tThe numeric argument represents the number of times to iterate when\n" "\tresolving a collision. `0' means ``iterate by the number of keywords.''\n" + "-F\tDefine constant values using global ``const'' declaration rather\n" + "\tthan with defines.\n" "-g\tAssume a GNU compiler, e.g., g++ or gcc. This makes all generated\n" "\troutines use the ``inline'' keyword to remove cost of function calls.\n" "-G\tGenerate the static table of keywords as a static global variable,\n" *************** *** 296,301 **** --- 313,321 ---- "\tis `hash'.\n" "-i\tProvide an initial value for the associate values array. Default is 0.\n" "\tSetting this value larger helps inflate the size of the final table.\n" + "-I\tChanges the return value of the generated function ``in_word_set''\n" + "\tfrom its default boolean value (i.e., 0 or 1) to the index into\n" + "\tthe wordlist array (needs -G to be useful).\n" "-j\tAffects the ``jump value,'' i.e., how far to advance the associated\n" "\tcharacter value upon collisions. Must be an odd number, default is %d.\n" "-k\tAllows selection of the key positions used in the hash function.\n" *************** *** 342,347 **** --- 362,371 ---- "-T\tPrevents the transfer of the type declaration to the output file.\n" "\tUse this option if the type is already defined elsewhere.\n" "-v\tPrints out the current version number\n" + "-V\t Output valid indices into the wordlist array as constants. Use\n" + "\t``define'', ``enum'' or ``const int'' depending on -E and -F. The\n" + "\tsymbols are named by replacing ``%%'' or ``&'' in the string argument\n" + "\twith the respective keyword.\n" "-Z\tAllow user to specify name of generated C++ class. Default\n" "\tname is `Perfect_Hash.'\n%e%a", DEFAULT_JUMP_VALUE, (MAX_KEY_POS - 1), usage, 1); } *************** *** 358,363 **** --- 382,393 ---- report_error ("warning, -r option superceeds -i, ignoring -i option and continuing\n"); break; } + case 'I': /* Generated lookup function now the index into the wordlist. */ + { + option_word |= INDEX; + option_word &= ~POINTER; + break; + } case 'j': /* Sets the jump value, must be odd for later algorithms. */ { if ((jump = atoi (getopt.optarg)) < 0) *************** *** 440,445 **** --- 470,476 ---- case 'p': /* Generated lookup function now a pointer instead of int. */ { option_word |= POINTER; + option_word &= ~INDEX; break; } case 'r': /* Utilize randomness to initialize the associated values table. */ *************** *** 474,479 **** --- 505,516 ---- } case 'v': /* Print out the version and quit. */ report_error ("%n: version %s\n%e\n%a", version_string, usage, 1); + case 'V': /* Output constants for valid indices into wordlist */ + { + option_word |= INDEXCONST; + const_pattern = getopt.optarg; + break; + } case 'Z': /* Set the class name. */ { class_name = getopt.optarg; *************** *** 628,633 **** --- 665,678 ---- { T (Trace t ("Options::get_delimiter");) return delimiters; + } + + /* Returns the pattern string used to generate index constants. */ + const char * + Options::get_const_pattern () + { + T (Trace t ("Options::get_const_pattern");) + return const_pattern; } /* Gets the total number of switch statements to generate. */ *** gperf/src/options.h Wed May 11 09:53:19 1994 --- gperf-hacked/src/options.h Thu May 18 18:04:27 1995 *************** *** 59,65 **** CONST = 0400000, /* Make the generated tables readonly (const). */ CPLUSPLUS = 01000000, /* Generate C++ code. */ C = 02000000, /* Generate C code. */ ! ENUM = 04000000 /* Use enum for constants. */ }; /* Define some useful constants (these don't really belong here, but I'm --- 59,76 ---- CONST = 0400000, /* Make the generated tables readonly (const). */ CPLUSPLUS = 01000000, /* Generate C++ code. */ C = 02000000, /* Generate C code. */ ! ENUM = 04000000, /* Use enum for constants. */ ! ! /* Gunther Schadow's options: */ ! ! CONSTCONST = 010000000, /* Use const for constants. */ ! INDEX = 020000000, /* Have in_word_set function return index ! into wordlist, not boolean */ ! INDEXCONST = 040000000, /* Output valid indices as constants. Use ! defines, enum or const depending on ENUM ! and CONSTCONST. The symbols are named by ! replacement of a percent (`%') in the ! string parameter with the keyword */ }; /* Define some useful constants (these don't really belong here, but I'm *************** *** 101,108 **** --- 112,121 ---- static const char *get_class_name (void); static const char *get_hash_name (void); static const char *get_delimiter (void); + static const char *get_const_pattern (void); private: + static const char *const_pattern; /* Holds the pattern for indexconst symbols */ static int option_word; /* Holds the user-specified Options. */ static int total_switches; /* Number of switch statements to generate. */ static int total_keysig_size; /* Total number of distinct key_positions. */ *************** *** 248,253 **** --- 261,273 ---- { T (Trace t ("Options::get_delimiter");) return delimiters; + } + + inline const char * + Options::get_const_pattern () /* Returns the pattern string used to generate index constants. */ + { + T (Trace t ("Options::get_const_pattern");) + return const_pattern; } inline int