diff options
author | Bruno Haible <bruno@clisp.org> | 2003-04-16 10:07:23 +0000 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2003-04-16 10:07:23 +0000 |
commit | b49d12d9843f3f2be0eb38327cb15af761d668d8 (patch) | |
tree | 2e62b1f04edb9ec0a57671a5c03f047453f401fe /src | |
parent | fa9b5b99bff5a086623ac15e4001cddb4d1fba9b (diff) | |
download | gperf-b49d12d9843f3f2be0eb38327cb15af761d668d8.tar.gz |
Improve option --pic. New options --string-pool-name, --null-strings.
Diffstat (limited to 'src')
-rw-r--r-- | src/input.cc | 15 | ||||
-rw-r--r-- | src/options.cc | 45 | ||||
-rw-r--r-- | src/options.h | 29 | ||||
-rw-r--r-- | src/options.icc | 9 | ||||
-rw-r--r-- | src/output.cc | 296 | ||||
-rw-r--r-- | src/output.h | 11 |
6 files changed, 342 insertions, 63 deletions
diff --git a/src/input.cc b/src/input.cc index 933911e..4a968ae 100644 --- a/src/input.cc +++ b/src/input.cc @@ -1,5 +1,5 @@ /* Input routines. - Copyright (C) 1989-1998, 2002 Free Software Foundation, Inc. + Copyright (C) 1989-1998, 2002-2003 Free Software Foundation, Inc. Written by Douglas C. Schmidt <schmidt@ics.uci.edu> and Bruno Haible <bruno@clisp.org>. @@ -529,6 +529,19 @@ Input::read_input () option.set (GLOBAL); else + if (is_declaration (line, line_end, lineno, "pic")) + option.set (SHAREDLIB); + else + + if (is_define_declaration (line, line_end, lineno, + "string-pool-name", &arg)) + option.set_stringpool_name (arg); + else + + if (is_declaration (line, line_end, lineno, "null-strings")) + option.set (NULLSTRINGS); + else + if (is_define_declaration (line, line_end, lineno, "word-array-name", &arg)) option.set_wordlist_name (arg); diff --git a/src/options.cc b/src/options.cc index 8880858..02258a0 100644 --- a/src/options.cc +++ b/src/options.cc @@ -1,5 +1,5 @@ /* Handles parsing the Options provided to the user. - Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc. + 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>. @@ -58,6 +58,9 @@ 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 = ","; @@ -166,6 +169,13 @@ Options::long_usage (FILE * stream) " 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"); @@ -448,6 +458,7 @@ Options::Options () _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 () { @@ -473,6 +484,7 @@ Options::~Options () "\nENUM is........: %s" "\nINCLUDE is.....: %s" "\nGLOBAL is......: %s" + "\nNULLSTRINGS is.: %s" "\nSHAREDLIB is...: %s" "\nSWITCH is......: %s" "\nNOTYPE is......: %s" @@ -483,6 +495,7 @@ Options::~Options () "\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" @@ -504,6 +517,7 @@ Options::~Options () _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", @@ -511,9 +525,10 @@ Options::~Options () _option_word & NOLENGTH ? "enabled" : "disabled", _option_word & RANDOM ? "enabled" : "disabled", _option_word & DEBUG ? "enabled" : "disabled", - _function_name, _hash_name, _wordlist_name, _slot_name, - _initializer_suffix, _asso_iterations, _jump, _size_multiple, - _initial_asso_value, _delimiters, _total_switches); + _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 @@ -610,6 +625,14 @@ Options::set_wordlist_name (const char *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) @@ -656,6 +679,8 @@ static const struct option long_options[] = { "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' }, @@ -675,7 +700,7 @@ Options::parse_options (int argc, char *argv[]) while ((option_char = getopt_long (_argument_count, _argument_vector, - "acCdDe:Ef:F:gGhH:i:Ij:k:K:lL:m:nN:oOpPrs:S:tTvW:Z:7", + "acCdDe:Ef:F:gGhH:i:Ij:k:K:lL:m:nN:oOpPQ:rs:S:tTvW:Z:7", long_options, NULL)) != -1) { @@ -872,6 +897,11 @@ Options::parse_options (int argc, char *argv[]) _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; @@ -978,6 +1008,11 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ _option_word |= UPPERLOWER; break; } + case CHAR_MAX + 3: /* Use NULL instead of "". */ + { + _option_word |= NULLSTRINGS; + break; + } default: short_usage (stderr); exit (1); diff --git a/src/options.h b/src/options.h index 0bde55c..d153436 100644 --- a/src/options.h +++ b/src/options.h @@ -2,7 +2,7 @@ /* Handles parsing the Options provided to the user. - Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc. + 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>. @@ -81,34 +81,37 @@ enum Option_Type /* Make the keyword table a global variable. */ GLOBAL = 1 << 12, + /* Use NULL strings instead of empty strings for empty table entries. */ + NULLSTRINGS = 1 << 13, + /* Optimize for position-independent code. */ - SHAREDLIB = 1 << 13, + SHAREDLIB = 1 << 14, /* Generate switch output to save space. */ - SWITCH = 1 << 14, + SWITCH = 1 << 15, /* Don't include user-defined type definition in output -- it's already defined elsewhere. */ - NOTYPE = 1 << 15, + NOTYPE = 1 << 16, /* --- Algorithm employed by gperf --- */ /* Use the given key positions. */ - POSITIONS = 1 << 16, + POSITIONS = 1 << 17, /* Handle duplicate hash values for keywords. */ - DUP = 1 << 17, + DUP = 1 << 18, /* Don't include keyword length in hash computations. */ - NOLENGTH = 1 << 18, + NOLENGTH = 1 << 19, /* Randomly initialize the associated values table. */ - RANDOM = 1 << 19, + RANDOM = 1 << 20, /* --- Informative output --- */ /* Enable debugging (prints diagnostics to stderr). */ - DEBUG = 1 << 20 + DEBUG = 1 << 21 }; /* Class manager for gperf program Options. */ @@ -189,6 +192,11 @@ public: /* Sets the hash table array name, if not already set. */ void set_wordlist_name (const char *name); + /* Returns the string pool name. */ + const char * get_stringpool_name () const; + /* Sets the string pool name, if not already set. */ + void set_stringpool_name (const char *name); + /* Returns the string used to delimit keywords from other attributes. */ const char * get_delimiters () const; /* Sets the delimiters string, if not already set. */ @@ -255,6 +263,9 @@ private: /* Name used for hash table array. */ const char * _wordlist_name; + /* Name used for the string pool. */ + const char * _stringpool_name; + /* Separates keywords from other attributes. */ const char * _delimiters; diff --git a/src/options.icc b/src/options.icc index f519133..1d21cc5 100644 --- a/src/options.icc +++ b/src/options.icc @@ -1,6 +1,6 @@ /* Inline Functions for options.{h,cc}. - Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc. + 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>. @@ -128,6 +128,13 @@ Options::get_wordlist_name () const return _wordlist_name; } +/* Returns the string pool name. */ +INLINE const char * +Options::get_stringpool_name () const +{ + return _stringpool_name; +} + /* Returns the string used to delimit keywords from other attributes. */ INLINE const char * Options::get_delimiters () const diff --git a/src/output.cc b/src/output.cc index 40bfb44..484d583 100644 --- a/src/output.cc +++ b/src/output.cc @@ -832,16 +832,18 @@ Output::output_keylength_table () const column = 0; for (temp = _head, index = 0; temp; temp = temp->rest()) { + KeywordExt *keyword = temp->first(); + /* If generating a switch statement, and there is no user defined type, we generate non-duplicates directly in the code. Only duplicates go into the table. */ - if (option[SWITCH] && !option[TYPE] && !temp->first()->_duplicate_link) + if (option[SWITCH] && !option[TYPE] && !keyword->_duplicate_link) continue; - if (index < temp->first()->_hash_value && !option[SWITCH] && !option[DUP]) + if (index < keyword->_hash_value && !option[SWITCH] && !option[DUP]) { /* Some blank entries. */ - for ( ; index < temp->first()->_hash_value; index++) + for ( ; index < keyword->_hash_value; index++) { if (index > 0) printf (","); @@ -855,12 +857,12 @@ Output::output_keylength_table () const printf (","); if ((column++ % columns) == 0) printf("\n%s ", indent); - printf ("%3d", temp->first()->_allchars_length); + printf ("%3d", keyword->_allchars_length); index++; /* Deal with duplicates specially. */ - if (temp->first()->_duplicate_link) // implies option[DUP] - for (KeywordExt *links = temp->first()->_duplicate_link; links; links = links->_duplicate_link) + if (keyword->_duplicate_link) // implies option[DUP] + for (KeywordExt *links = keyword->_duplicate_link; links; links = links->_duplicate_link) { printf (","); if ((column++ % columns) == 0) @@ -877,8 +879,111 @@ Output::output_keylength_table () const /* ------------------------------------------------------------------------- */ +/* Prints out the string pool, containing the strings of the keyword table. + Only called if option[SHAREDLIB]. */ + +void +Output::output_string_pool () const +{ + const char * const indent = option[TYPE] || option[GLOBAL] ? "" : " "; + int index; + KeywordExt_List *temp; + + printf ("%sstruct %s_t\n" + "%s {\n", + indent, option.get_stringpool_name (), indent); + for (temp = _head, index = 0; temp; temp = temp->rest()) + { + KeywordExt *keyword = temp->first(); + + /* If generating a switch statement, and there is no user defined type, + we generate non-duplicates directly in the code. Only duplicates go + into the table. */ + if (option[SWITCH] && !option[TYPE] && !keyword->_duplicate_link) + continue; + + if (!option[SWITCH] && !option[DUP]) + index = keyword->_hash_value; + + printf ("%s char %s_str%d[sizeof(", + indent, option.get_stringpool_name (), index); + output_string (keyword->_allchars, keyword->_allchars_length); + printf (")];\n"); + + /* Deal with duplicates specially. */ + if (keyword->_duplicate_link) // implies option[DUP] + for (KeywordExt *links = keyword->_duplicate_link; links; links = links->_duplicate_link) + if (!(links->_allchars_length == keyword->_allchars_length + && memcmp (links->_allchars, keyword->_allchars, + keyword->_allchars_length) == 0)) + { + index++; + printf ("%s char %s_str%d[sizeof(", + indent, option.get_stringpool_name (), index); + output_string (links->_allchars, links->_allchars_length); + printf (")];\n"); + } + + index++; + } + printf ("%s };\n", + indent); + + printf ("%sstatic %sstruct %s_t %s_contents =\n" + "%s {\n", + indent, const_readonly_array, option.get_stringpool_name (), + option.get_stringpool_name (), indent); + for (temp = _head, index = 0; temp; temp = temp->rest()) + { + KeywordExt *keyword = temp->first(); + + /* If generating a switch statement, and there is no user defined type, + we generate non-duplicates directly in the code. Only duplicates go + into the table. */ + if (option[SWITCH] && !option[TYPE] && !keyword->_duplicate_link) + continue; + + if (index > 0) + printf (",\n"); + + if (!option[SWITCH] && !option[DUP]) + index = keyword->_hash_value; + + printf ("%s ", + indent); + output_string (keyword->_allchars, keyword->_allchars_length); + + /* Deal with duplicates specially. */ + if (keyword->_duplicate_link) // implies option[DUP] + for (KeywordExt *links = keyword->_duplicate_link; links; links = links->_duplicate_link) + if (!(links->_allchars_length == keyword->_allchars_length + && memcmp (links->_allchars, keyword->_allchars, + keyword->_allchars_length) == 0)) + { + index++; + printf (",\n"); + printf ("%s ", + indent); + output_string (links->_allchars, links->_allchars_length); + } + + index++; + } + if (index > 0) + printf ("\n"); + printf ("%s };\n", + indent); + printf ("%s#define %s ((%schar *) &%s_contents)\n", + indent, option.get_stringpool_name (), const_always, + option.get_stringpool_name ()); + if (option[GLOBAL]) + printf ("\n"); +} + +/* ------------------------------------------------------------------------- */ + static void -output_keyword_entry (KeywordExt *temp, const char *indent) +output_keyword_entry (KeywordExt *temp, int stringpool_index, const char *indent) { if (option[TYPE] && option.get_input_file_name ()) printf ("#line %u \"%s\"\n", @@ -886,7 +991,12 @@ output_keyword_entry (KeywordExt *temp, const char *indent) printf ("%s ", indent); if (option[TYPE]) printf ("{"); - output_string (temp->_allchars, temp->_allchars_length); + if (option[SHAREDLIB]) + printf ("(int)(long)&((struct %s_t *)0)->%s_str%d", + option.get_stringpool_name (), option.get_stringpool_name (), + stringpool_index); + else + output_string (temp->_allchars, temp->_allchars_length); if (option[TYPE]) { if (strlen (temp->_rest) > 0) @@ -904,14 +1014,14 @@ output_keyword_blank_entries (int count, const char *indent) int columns; if (option[TYPE]) { - columns = 58 / (4 + (option[SHAREDLIB] ? 8 : 2) + columns = 58 / (4 + (option[SHAREDLIB] ? 2 : option[NULLSTRINGS] ? 8 : 2) + strlen (option.get_initializer_suffix())); if (columns == 0) columns = 1; } else { - columns = (option[SHAREDLIB] ? 4 : 9); + columns = (option[SHAREDLIB] ? 9 : option[NULLSTRINGS] ? 4 : 9); } int column = 0; for (int i = 0; i < count; i++) @@ -930,9 +1040,14 @@ output_keyword_blank_entries (int count, const char *indent) if (option[TYPE]) printf ("{"); if (option[SHAREDLIB]) - printf ("(char*)0"); + printf ("-1"); else - printf ("\"\""); + { + if (option[NULLSTRINGS]) + printf ("(char*)0"); + else + printf ("\"\""); + } if (option[TYPE]) printf ("%s}", option.get_initializer_suffix()); column++; @@ -945,12 +1060,12 @@ void Output::output_keyword_table () const { const char *indent = option[GLOBAL] ? "" : " "; - int index; + int index; KeywordExt_List *temp; printf ("%sstatic ", indent); - output_const_type (const_readonly_array, _struct_tag); + output_const_type (const_readonly_array, _wordlist_eltype); printf ("%s[] =\n" "%s {\n", option.get_wordlist_name (), @@ -960,31 +1075,42 @@ Output::output_keyword_table () const for (temp = _head, index = 0; temp; temp = temp->rest()) { - if (option[SWITCH] && !option[TYPE] && !temp->first()->_duplicate_link) + KeywordExt *keyword = temp->first(); + + /* If generating a switch statement, and there is no user defined type, + we generate non-duplicates directly in the code. Only duplicates go + into the table. */ + if (option[SWITCH] && !option[TYPE] && !keyword->_duplicate_link) continue; if (index > 0) printf (",\n"); - if (index < temp->first()->_hash_value && !option[SWITCH] && !option[DUP]) + if (index < keyword->_hash_value && !option[SWITCH] && !option[DUP]) { /* Some blank entries. */ - output_keyword_blank_entries (temp->first()->_hash_value - index, indent); + output_keyword_blank_entries (keyword->_hash_value - index, indent); printf (",\n"); - index = temp->first()->_hash_value; + index = keyword->_hash_value; } - temp->first()->_final_index = index; + keyword->_final_index = index; - output_keyword_entry (temp->first(), indent); + output_keyword_entry (keyword, index, indent); /* Deal with duplicates specially. */ - if (temp->first()->_duplicate_link) // implies option[DUP] - for (KeywordExt *links = temp->first()->_duplicate_link; links; links = links->_duplicate_link) + if (keyword->_duplicate_link) // implies option[DUP] + for (KeywordExt *links = keyword->_duplicate_link; links; links = links->_duplicate_link) { links->_final_index = ++index; printf (",\n"); - output_keyword_entry (links, indent); + int stringpool_index = + (links->_allchars_length == keyword->_allchars_length + && memcmp (links->_allchars, keyword->_allchars, + keyword->_allchars_length) == 0 + ? keyword->_final_index + : links->_final_index); + output_keyword_entry (links, stringpool_index, indent); } index++; @@ -1147,6 +1273,22 @@ Output::output_lookup_array () const /* ------------------------------------------------------------------------- */ +/* Generate all pools needed for the lookup function. */ + +void +Output::output_lookup_pools () const +{ + if (option[SWITCH]) + { + if (option[TYPE] || (option[DUP] && _total_duplicates > 0)) + output_string_pool (); + } + else + { + output_string_pool (); + } +} + /* Generate all the tables needed for the lookup function. */ void @@ -1340,10 +1482,10 @@ Output::output_lookup_function_body (const Output_Compare& comparison) const printf (" register %s%s *lengthptr;\n", const_always, smallest_integral_type (_max_key_len)); printf (" register "); - output_const_type (const_readonly_array, _struct_tag); + output_const_type (const_readonly_array, _wordlist_eltype); printf ("*wordptr;\n"); printf (" register "); - output_const_type (const_readonly_array, _struct_tag); + output_const_type (const_readonly_array, _wordlist_eltype); printf ("*wordendptr;\n"); } if (option[TYPE]) @@ -1358,14 +1500,14 @@ Output::output_lookup_function_body (const Output_Compare& comparison) const output_switches (_head, num_switches, switch_size, _min_hash_value, _max_hash_value, 10); + printf (" return 0;\n"); if (option[DUP] && _total_duplicates > 0) { int indent = 8; - printf ("%*s return 0;\n" - "%*smulticompare:\n" + printf ("%*smulticompare:\n" "%*s while (wordptr < wordendptr)\n" "%*s {\n", - indent, "", indent, "", indent, "", indent, ""); + indent, "", indent, "", indent, ""); if (option[LENTABLE]) { printf ("%*s if (len == *lengthptr)\n" @@ -1379,6 +1521,9 @@ Output::output_lookup_function_body (const Output_Compare& comparison) const printf ("wordptr->%s", option.get_slot_name ()); else printf ("*wordptr"); + if (option[SHAREDLIB]) + printf (" + %s", + option.get_stringpool_name ()); printf (";\n\n" "%*s if (", indent, ""); @@ -1397,17 +1542,21 @@ Output::output_lookup_function_body (const Output_Compare& comparison) const printf ("%*s lengthptr++;\n", indent, ""); printf ("%*s wordptr++;\n" - "%*s }\n", - indent, "", indent, ""); + "%*s }\n" + "%*s return 0;\n", + indent, "", indent, "", indent, ""); } - printf (" return 0;\n" - " compare:\n"); + printf (" compare:\n"); if (option[TYPE]) { printf (" {\n" - " register %schar *s = resword->%s;\n\n" - " if (", + " register %schar *s = resword->%s", const_always, option.get_slot_name ()); + if (option[SHAREDLIB]) + printf (" + %s", + option.get_stringpool_name ()); + printf (";\n\n" + " if ("); comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s")); printf (")\n" " return resword;\n" @@ -1446,6 +1595,9 @@ Output::output_lookup_function_body (const Output_Compare& comparison) const indent, "", const_always, option.get_wordlist_name ()); if (option[TYPE]) printf (".%s", option.get_slot_name ()); + if (option[SHAREDLIB]) + printf (" + %s", + option.get_stringpool_name ()); printf (";\n\n" "%*s if (", indent, ""); @@ -1476,12 +1628,12 @@ Output::output_lookup_function_body (const Output_Compare& comparison) const indent, "", const_always, smallest_integral_type (_max_key_len)); printf ("%*s register ", indent, ""); - output_const_type (const_readonly_array, _struct_tag); + output_const_type (const_readonly_array, _wordlist_eltype); printf ("*wordptr = &%s[TOTAL_KEYWORDS + lookup[offset]];\n", option.get_wordlist_name ()); printf ("%*s register ", indent, ""); - output_const_type (const_readonly_array, _struct_tag); + output_const_type (const_readonly_array, _wordlist_eltype); printf ("*wordendptr = wordptr + -lookup[offset + 1];\n\n"); printf ("%*s while (wordptr < wordendptr)\n" "%*s {\n", @@ -1499,6 +1651,9 @@ Output::output_lookup_function_body (const Output_Compare& comparison) const printf ("wordptr->%s", option.get_slot_name ()); else printf ("*wordptr"); + if (option[SHAREDLIB]) + printf (" + %s", + option.get_stringpool_name ()); printf (";\n\n" "%*s if (", indent, ""); @@ -1534,18 +1689,55 @@ Output::output_lookup_function_body (const Output_Compare& comparison) const indent += 2; } - printf ("%*s{\n" - "%*s register %schar *s = %s[key]", - indent, "", - indent, "", const_always, option.get_wordlist_name ()); - - if (option[TYPE]) - printf (".%s", option.get_slot_name ()); + if (option[SHAREDLIB]) + { + if (!option[LENTABLE]) + { + printf ("%*s{\n" + "%*s register int o = %s[key]", + indent, "", + indent, "", option.get_wordlist_name ()); + if (option[TYPE]) + printf (".%s", option.get_slot_name ()); + printf (";\n" + "%*s if (o >= 0)\n" + "%*s {\n", + indent, "", + indent, ""); + indent += 4; + printf ("%*s register %schar *s = o", + indent, "", const_always); + } + else + { + /* No need for the (o >= 0) test, because the + (len == lengthtable[key]) test already guarantees that + key points to nonempty table entry. */ + printf ("%*s{\n" + "%*s register %schar *s = %s[key]", + indent, "", + indent, "", const_always, + option.get_wordlist_name ()); + if (option[TYPE]) + printf (".%s", option.get_slot_name ()); + } + printf (" + %s", + option.get_stringpool_name ()); + } + else + { + printf ("%*s{\n" + "%*s register %schar *s = %s[key]", + indent, "", + indent, "", const_always, option.get_wordlist_name ()); + if (option[TYPE]) + printf (".%s", option.get_slot_name ()); + } printf (";\n\n" "%*s if (", indent, ""); - if (option[SHAREDLIB]) + if (!option[SHAREDLIB] && option[NULLSTRINGS]) printf ("s && "); comparison.output_comparison (Output_Expr1 ("str"), Output_Expr1 ("s")); printf (")\n" @@ -1555,8 +1747,14 @@ Output::output_lookup_function_body (const Output_Compare& comparison) const printf ("&%s[key]", option.get_wordlist_name ()); else printf ("s"); - printf (";\n" - "%*s}\n", + printf (";\n"); + if (option[SHAREDLIB] && !option[LENTABLE]) + { + indent -= 4; + printf ("%*s }\n", + indent, ""); + } + printf ("%*s}\n", indent, ""); } } @@ -1601,6 +1799,8 @@ Output::output_lookup_function () const output_constants (style); } + if (option[SHAREDLIB] && !(option[GLOBAL] || option[TYPE])) + output_lookup_pools (); if (!option[GLOBAL]) output_lookup_tables (); @@ -1646,6 +1846,8 @@ Output::output () _struct_tag = (const_always[0] ? "const char *" : "char *"); } + _wordlist_eltype = (option[SHAREDLIB] && !option[TYPE] ? "int" : _struct_tag); + printf ("/* "); if (option[KRC]) printf ("KR-C"); @@ -1726,6 +1928,8 @@ Output::output () output_hash_function (); + if (option[SHAREDLIB] && (option[GLOBAL] || option[TYPE])) + output_lookup_pools (); if (option[GLOBAL]) output_lookup_tables (); diff --git a/src/output.h b/src/output.h index 7631110..3650f9e 100644 --- a/src/output.h +++ b/src/output.h @@ -2,7 +2,7 @@ /* Output routines. - Copyright (C) 1989-1998, 2000, 2002 Free Software Foundation, Inc. + 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>. @@ -82,6 +82,10 @@ private: comparison code in generated function 'in_word_set'. */ void output_keylength_table () const; + /* Prints out the string pool, containing the strings of the keyword table. + */ + void output_string_pool () const; + /* Prints out the array containing the keywords for the hash function. */ void output_keyword_table () const; @@ -89,6 +93,9 @@ private: the smaller, contiguous range of the keyword table. */ void output_lookup_array () const; + /* Generate all pools needed for the lookup function. */ + void output_lookup_pools () const; + /* Generate all the tables needed for the lookup function. */ void output_lookup_tables () const; @@ -108,6 +115,8 @@ private: const char * _return_type; /* Shorthand for user-defined struct tag type. */ const char * _struct_tag; + /* Element type of keyword array. */ + const char * _wordlist_eltype; /* The C code from the declarations section. */ const char * const _verbatim_declarations; const char * const _verbatim_declarations_end; |