summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog43
-rw-r--r--NEWS10
-rw-r--r--doc/gperf.texi67
-rw-r--r--src/input.cc15
-rw-r--r--src/options.cc45
-rw-r--r--src/options.h29
-rw-r--r--src/options.icc9
-rw-r--r--src/output.cc296
-rw-r--r--src/output.h11
-rw-r--r--tests/Makefile.in175
-rw-r--r--tests/jstest4.gperf147
-rw-r--r--tests/test-6.exp5
12 files changed, 709 insertions, 143 deletions
diff --git a/ChangeLog b/ChangeLog
index b9ba6bc..5681566 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,48 @@
2003-01-01 Bruno Haible <bruno@clisp.org>
+ * src/options.h (NULLSTRINGS): New enum value.
+ (Options::get_stringpool_name, Options::set_stringpool_name): New
+ method declarations.
+ (Options::_stringpool_name): New field.
+ * src/options.icc (Options::get_stringpool_name): New method.
+ * src/options.cc (DEFAULT_STRINGPOOL_NAME): New variable.
+ (Options::long_usage): Document -Q and --null-strings.
+ (Options::Options): Initialize _stringpool_name.
+ (Options::~Options): Output _stringpool_name, NULLSTRINGS values too.
+ (Options::set_stringpool_name): New method.
+ (long_options): Add options --string-pool-name, --null-strings.
+ (Options::parse_options): Implement options -P, -Q and --null-strings.
+ * src/input.cc (Input::read_input): Recognize declarations %pic,
+ %define string-pool-name, %null-strings.
+ * src/output.h (Output::output_string_pool,
+ Output::output_lookup_pools): New method declarations.
+ (Output::_wordlist_eltype): New field.
+ * src/output.cc (Output::output_keylength_table): Trivial
+ simplification.
+ (Output::output_string_pool): New method.
+ (output_keyword_entry): Add stringpool_index argument. For SHAREDLIB,
+ use struct offsets.
+ (output_keyword_blank_entries): For SHAREDLIB, use -1 instead of "".
+ (Output::output_keyword_table): Use _wordlist_eltype instead of
+ _struct_tag. Compute stringpool_index for output_keyword_entry.
+ (Output::output_lookup_pools): New method.
+ (Output::output_lookup_function_body): Use _wordlist_eltype instead of
+ _struct_tag. For SHAREDLIB, use "+ stringpool" to convert offsets to
+ strings. Use "o >= 0" to test for nonempty table entry.
+ (Output::output_lookup_function): Call output_lookup_pools.
+ (Output::output): Initialize _wordlist_eltype. Call
+ output_lookup_pools.
+ * tests/jstest4.gperf: New file.
+ * tests/test-6.exp: Update.
+ * tests/Makefile.in (check-lang-syntax): Drop test of -p. Add tests of
+ -P and -Q.
+ * doc/gperf.texi (User-supplied Struct): Mention that first field has
+ to be of type 'int' if -P is given.
+ (Gperf Declarations): Document %pic, %define string-pool-name,
+ %null-strings.
+ (Output Details): Update description of option -P. Document options -Q
+ and --null-strings.
+
* tests/Makefile.in (check-link-c, check-ada, check-pascal,
check-test): Omit option -p.
* tests/c-parse.exp: Regenerated.
diff --git a/NEWS b/NEWS
index 74acb0f..9ff7833 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,9 @@ New in 2.97:
%enum
%includes
%global-table
+ %pic
+ %define string-pool-name NAME
+ %null-strings
%define word-array-name NAME
%switch=COUNT
%omit-struct-type
@@ -41,8 +44,11 @@ New in 2.97:
the table's size will grow as needed. Earlier versions of gperf bailed
out with an "Internal error, duplicate hash code value".
* The options -f/--fast and -o/--occurrence-sort have no effect any more.
-* Added option -P/--pic that optimizes the generated code for use in shared
- libraries.
+* Added options -P/--pic and --null-strings that optimize the generated code
+ for use in shared libraries. -P/--pic does a perfect optimization but may
+ require some small code changes (see the documentation for details), whereas
+ --null-strings does only a half-hearted optimization but works without
+ needing any change to surrounding code.
* Added option --ignore-case that produces a case independent lookup function.
* Bug fixes.
diff --git a/doc/gperf.texi b/doc/gperf.texi
index 56676ce..0ebfd5d 100644
--- a/doc/gperf.texi
+++ b/doc/gperf.texi
@@ -7,7 +7,7 @@
@c some day we should @include version.texi instead of defining
@c these values at hand.
-@set UPDATED 8 December 2002
+@set UPDATED 1 January 2003
@set EDITION 2.7.2
@set VERSION 2.7.2
@c ---------------------
@@ -28,7 +28,7 @@
This file documents the features of the GNU Perfect Hash Function
Generator @value{VERSION}.
-Copyright @copyright{} 1989-2002 Free Software Foundation, Inc.
+Copyright @copyright{} 1989-2003 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
@@ -65,7 +65,7 @@ Software Foundation instead of in the original English.
@page
@vskip 0pt plus 1filll
-Copyright @copyright{} 1989-2002 Free Software Foundation, Inc.
+Copyright @copyright{} 1989-2003 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
@@ -365,10 +365,12 @@ act like command-line options, as well as for providing a user-supplied
If the @samp{-t} option (or, equivalently, the @samp{%struct-type} declaration)
@emph{is} enabled, you @emph{must} provide a C @code{struct} as the last
component in the declaration section from the input file. The first
-field in this struct must be a @code{char *} or @code{const char *}
-identifier called @samp{name}, although it is possible to modify this
-field's name with the @samp{-K} option (or, equivalently, the
-@samp{%define slot-name}) described below.
+field in this struct must be of type @code{char *} or @code{const char *}
+if the @samp{-P} option is not given, or of type @code{int} if the option
+@samp{-P} (or, equivalently, the @samp{%pic} declaration) is enabled.
+This first field must be called @samp{name}, although it is possible to modify
+its name with the @samp{-K} option (or, equivalently, the
+@samp{%define slot-name} declaration) described below.
Here is a simple example, using months of the year and their attributes as
input:
@@ -544,6 +546,34 @@ Generate the static table of keywords as a static global variable,
rather than hiding it inside of the lookup function (which is the
default behavior).
+@item %pic
+@cindex @samp{%pic}
+Optimize the generated table for inclusion in shared libraries. This
+reduces the startup time of programs using a shared library containing
+the generated code. If the @samp{%struct-type} declaration (or,
+equivalently, the option @samp{-t}) is also given, the first field of the
+user-defined struct must be of type @samp{int}, not @samp{char *}, because
+it will contain offsets into the string pool instead of actual strings.
+To convert such an offset to a string, you can use the expression
+@samp{stringpool + @var{o}}, where @var{o} is the offset. The string pool
+name can be changed through the @samp{%define string-pool-name} declaration.
+
+@item %define string-pool-name @var{name}
+@cindex @samp{%define string-pool-name}
+Allows you to specify the name of the generated string pool created by
+the declaration @samp{%pic} (or, equivalently, the option @samp{-P}).
+The default name is @samp{stringpool}. This declaration permits the use of
+two hash tables in the same file, with @samp{%pic} and even when the
+@samp{%global-table} declaration (or, equivalently, the option @samp{-G})
+is given.
+
+@item %null-strings
+@cindex @samp{%null-strings}
+Use NULL strings instead of empty strings for empty keyword table entries.
+This reduces the startup time of programs using a shared library containing
+the generated code (but not as much as the declaration @samp{%pic}), at the
+expense of one more test-and-branch instruction at run time.
+
@item %define word-array-name @var{name}
@cindex @samp{%define word-array-name}
Allows you to specify the name for the generated array containing the
@@ -952,8 +982,27 @@ default behavior).
@itemx --pic
Optimize the generated table for inclusion in shared libraries. This
reduces the startup time of programs using a shared library containing
-the generated code, at the expense of one more test-and-branch instruction
-at run time.
+the generated code. If the option @samp{-t} (or, equivalently, the
+@samp{%struct-type} declaration) is also given, the first field of the
+user-defined struct must be of type @samp{int}, not @samp{char *}, because
+it will contain offsets into the string pool instead of actual strings.
+To convert such an offset to a string, you can use the expression
+@samp{stringpool + @var{o}}, where @var{o} is the offset. The string pool
+name can be changed through the option @samp{--string-pool-name}.
+
+@item -Q @var{string-pool-name}
+@itemx --string-pool-name=@var{string-pool-name}
+Allows you to specify the name of the generated string pool created by
+option @samp{-P}. The default name is @samp{stringpool}. This option
+permits the use of two hash tables in the same file, with @samp{-P} and
+even when the option @samp{-G} (or, equivalently, the @samp{%global-table}
+declaration) is given.
+
+@item --null-strings
+Use NULL strings instead of empty strings for empty keyword table entries.
+This reduces the startup time of programs using a shared library containing
+the generated code (but not as much as option @samp{-P}), at the expense
+of one more test-and-branch instruction at run time.
@item -W @var{hash-table-array-name}
@itemx --word-array-name=@var{hash-table-array-name}
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;
diff --git a/tests/Makefile.in b/tests/Makefile.in
index 5e9eacc..2cd4f65 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -200,21 +200,31 @@ check-lang-syntax : force
$(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -S 10 -D -l
$(VALIDATE) KR-C,C,ANSI-C,C++ -k2 $(srcdir)/jstest1.gperf -S 10 -D -l
$(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -S 1000
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -p
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -p -C
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -p -l
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -p -D
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k2 $(srcdir)/jstest1.gperf -p -D
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -p -D -l
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k2 $(srcdir)/jstest1.gperf -p -D -l
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -p -S 10
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -p -S 10 -C
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -p -S 10 -l
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -p -S 10 -D
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k2 $(srcdir)/jstest1.gperf -p -S 10 -D
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -p -S 10 -D -l
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k2 $(srcdir)/jstest1.gperf -p -S 10 -D -l
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -p -S 1000
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -c
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -C
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -E
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -G
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -G -C
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -G -E
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -l
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -D
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k2 $(srcdir)/jstest1.gperf -P -D
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -D -l
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k2 $(srcdir)/jstest1.gperf -P -D -l
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -S 10
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -S 10 -c
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -S 10 -C
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -S 10 -E
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -S 10 -G
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -S 10 -l
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -S 10 -D
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k2 $(srcdir)/jstest1.gperf -P -S 10 -D
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -S 10 -D -l
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k2 $(srcdir)/jstest1.gperf -P -S 10 -D -l
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -S 1000
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -Q auxstrings
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -P -Q auxstrings -S 10
$(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -K key_name
$(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -H hash_function_name
$(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest1.gperf -W word_list_name
@@ -222,66 +232,93 @@ check-lang-syntax : force
$(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 tmp-jstest1.gperf -N lookup_function_name
sed -e 's,Perfect_Hash,class_name,g' < $(srcdir)/jstest1.gperf > tmp-jstest1.gperf && \
$(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 tmp-jstest1.gperf -Z class_name
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -c
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -C
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -E
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -G
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -G -C
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -G -E
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -l
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -D
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k2 $(srcdir)/jstest2.gperf -t -p -D
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -D -l
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k2 $(srcdir)/jstest2.gperf -t -p -D -l
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -S 10
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -S 10 -c
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -S 10 -C
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -S 10 -E
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -S 10 -G
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -S 10 -l
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -S 10 -D
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k2 $(srcdir)/jstest2.gperf -t -p -S 10 -D
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -S 10 -D -l
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k2 $(srcdir)/jstest2.gperf -t -p -S 10 -D -l
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -S 1000
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -c
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -C
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -E
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -G
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -G -C
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -G -E
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -l
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -D
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k2 $(srcdir)/jstest2.gperf -t -D
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -D -l
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k2 $(srcdir)/jstest2.gperf -t -D -l
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -S 10
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -S 10 -c
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -S 10 -C
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -S 10 -E
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -S 10 -G
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -S 10 -l
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -S 10 -D
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k2 $(srcdir)/jstest2.gperf -t -S 10 -D
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -S 10 -D -l
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k2 $(srcdir)/jstest2.gperf -t -S 10 -D -l
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -S 1000
sed -e 's,name,key_name,g' < $(srcdir)/jstest2.gperf > tmp-jstest2.gperf && \
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 tmp-jstest2.gperf -t -p -K key_name
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -p -H hash_function_name
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 tmp-jstest2.gperf -t -K key_name
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 $(srcdir)/jstest2.gperf -t -H hash_function_name
sed -e 's,in_word_set,lookup_function_name,g' < $(srcdir)/jstest2.gperf > tmp-jstest2.gperf && \
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 tmp-jstest2.gperf -t -p -N lookup_function_name
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 tmp-jstest2.gperf -t -N lookup_function_name
sed -e 's,Perfect_Hash,class_name,g' < $(srcdir)/jstest2.gperf > tmp-jstest2.gperf && \
- $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 tmp-jstest2.gperf -t -p -Z class_name
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -c
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -C
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -E
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -G
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -G -C
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -G -E
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -l
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -D
- $(VALIDATE) C,ANSI-C,C++ -k2 $(srcdir)/jstest3.gperf -t -p -D
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -D -l
- $(VALIDATE) C,ANSI-C,C++ -k2 $(srcdir)/jstest3.gperf -t -p -D -l
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -S 10
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -S 10 -c
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -S 10 -C
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -S 10 -E
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -S 10 -G
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -S 10 -l
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -S 10 -D
- $(VALIDATE) C,ANSI-C,C++ -k2 $(srcdir)/jstest3.gperf -t -p -S 10 -D
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -S 10 -D -l
- $(VALIDATE) C,ANSI-C,C++ -k2 $(srcdir)/jstest3.gperf -t -p -S 10 -D -l
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -S 1000
+ $(VALIDATE) KR-C,C,ANSI-C,C++ -k1,2 tmp-jstest2.gperf -t -Z class_name
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -c
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -C
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -E
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -G
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -G -C
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -G -E
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -l
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -D
+ $(VALIDATE) C,ANSI-C,C++ -k2 $(srcdir)/jstest3.gperf -t -D
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -D -l
+ $(VALIDATE) C,ANSI-C,C++ -k2 $(srcdir)/jstest3.gperf -t -D -l
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -S 10
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -S 10 -c
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -S 10 -C
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -S 10 -E
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -S 10 -G
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -S 10 -l
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -S 10 -D
+ $(VALIDATE) C,ANSI-C,C++ -k2 $(srcdir)/jstest3.gperf -t -S 10 -D
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -S 10 -D -l
+ $(VALIDATE) C,ANSI-C,C++ -k2 $(srcdir)/jstest3.gperf -t -S 10 -D -l
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -S 1000
sed -e 's,name,key_name,g' < $(srcdir)/jstest3.gperf > tmp-jstest3.gperf && \
- $(VALIDATE) C,ANSI-C,C++ -k1,2 tmp-jstest3.gperf -t -p -K key_name
- $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -p -H hash_function_name
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 tmp-jstest3.gperf -t -K key_name
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest3.gperf -t -H hash_function_name
sed -e 's,in_word_set,lookup_function_name,g' < $(srcdir)/jstest3.gperf > tmp-jstest3.gperf && \
- $(VALIDATE) C,ANSI-C,C++ -k1,2 tmp-jstest3.gperf -t -p -N lookup_function_name
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 tmp-jstest3.gperf -t -N lookup_function_name
sed -e 's,Perfect_Hash,class_name,g' < $(srcdir)/jstest3.gperf > tmp-jstest3.gperf && \
- $(VALIDATE) C,ANSI-C,C++ -k1,2 tmp-jstest3.gperf -t -p -Z class_name
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 tmp-jstest3.gperf -t -Z class_name
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -c
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -C
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -E
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -G
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -G -C
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -G -E
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -l
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -D
+ $(VALIDATE) C,ANSI-C,C++ -k2 $(srcdir)/jstest4.gperf -t -P -D
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -D -l
+ $(VALIDATE) C,ANSI-C,C++ -k2 $(srcdir)/jstest4.gperf -t -P -D -l
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -S 10
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -S 10 -c
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -S 10 -C
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -S 10 -E
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -S 10 -G
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -S 10 -l
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -S 10 -D
+ $(VALIDATE) C,ANSI-C,C++ -k2 $(srcdir)/jstest4.gperf -t -P -S 10 -D
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -S 10 -D -l
+ $(VALIDATE) C,ANSI-C,C++ -k2 $(srcdir)/jstest4.gperf -t -P -S 10 -D -l
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 $(srcdir)/jstest4.gperf -t -P -S 1000
+ sed -e 's,stringpool,auxstrings,g' < $(srcdir)/jstest4.gperf > tmp-jstest4.gperf && \
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 tmp-jstest4.gperf -t -P -Q auxstrings
+ sed -e 's,stringpool,auxstrings,g' < $(srcdir)/jstest4.gperf > tmp-jstest4.gperf && \
+ $(VALIDATE) C,ANSI-C,C++ -k1,2 tmp-jstest4.gperf -t -P -Q auxstrings -S 10
mostlyclean : clean
diff --git a/tests/jstest4.gperf b/tests/jstest4.gperf
new file mode 100644
index 0000000..b02617c
--- /dev/null
+++ b/tests/jstest4.gperf
@@ -0,0 +1,147 @@
+struct js_keyword {
+ int name;
+ int token;
+}
+%%
+abstract, 1
+boolean, 2
+break, 3
+byte, 4
+case, 5
+catch, 6
+char, 7
+class, 8
+const, 9
+continue, 10
+default, 11
+do, 12
+double, 13
+else, 14
+extends, 15
+false, 16
+final, 17
+finally, 18
+float, 19
+for, 20
+function, 21
+goto, 22
+if, 23
+implements, 24
+import, 25
+in, 26
+instanceof, 27
+int, 28
+interface, 29
+long, 30
+native, 31
+new, 32
+null, 33
+package, 34
+private, 35
+protected, 36
+public, 37
+return, 38
+short, 39
+static, 40
+super, 41
+switch, 42
+synchronized, 43
+this, 44
+throw, 45
+throws, 46
+transient, 47
+true, 48
+try, 49
+var, 50
+void, 51
+while, 52
+with, 53
+%%
+#include <stdlib.h>
+#include <string.h>
+#if defined(__STDC__) || defined(__cplusplus)
+#define CONST const
+#else
+#define CONST
+#endif
+static CONST char* testdata[] = {
+ "bogus",
+ "abstract",
+ "boolean",
+ "break",
+ "byte",
+ "case",
+ "catch",
+ "char",
+ "class",
+ "const",
+ "continue",
+ "default",
+ "do",
+ "double",
+ "else",
+ "extends",
+ "false",
+ "final",
+ "finally",
+ "float",
+ "for",
+ "function",
+ "goto",
+ "if",
+ "implements",
+ "import",
+ "in",
+ "instanceof",
+ "int",
+ "interface",
+ "long",
+ "native",
+ "new",
+ "null",
+ "package",
+ "private",
+ "protected",
+ "public",
+ "return",
+ "short",
+ "static",
+ "super",
+ "switch",
+ "synchronized",
+ "this",
+ "throw",
+ "throws",
+ "transient",
+ "true",
+ "try",
+ "var",
+ "void",
+ "while",
+ "with"
+};
+int main ()
+{
+ int i;
+ for (i = 0; i < sizeof(testdata)/sizeof(testdata[0]); i++)
+ {
+#ifdef CPLUSPLUS_TEST
+ CONST struct js_keyword * resword = Perfect_Hash::in_word_set(testdata[i],strlen(testdata[i]));
+#else
+ CONST struct js_keyword * resword = in_word_set(testdata[i],strlen(testdata[i]));
+#endif
+ if (i > 0)
+ {
+ if (!resword)
+ exit (1);
+ if (strcmp(testdata[i],stringpool+resword->name))
+ exit (1);
+ }
+ else
+ {
+ if (resword)
+ exit (1);
+ }
+ }
+ return 0;
+}
diff --git a/tests/test-6.exp b/tests/test-6.exp
index cabbe9c..d0e3f21 100644
--- a/tests/test-6.exp
+++ b/tests/test-6.exp
@@ -63,6 +63,11 @@ Details in the output code:
-P, --pic Optimize the generated table for inclusion in shared
libraries. This reduces the startup time of programs
using a shared library containing the generated code.
+ -Q, --string-pool-name=NAME
+ Specify name of string pool generated by option --pic.
+ Default name is 'stringpool'.
+ --null-strings Use NULL strings instead of empty strings for empty
+ keyword table entries.
-W, --word-array-name=NAME
Specify name of word list array. Default name is
'wordlist'.