1
0
mirror of https://git.savannah.gnu.org/git/gperf.git synced 2025-12-02 13:09:22 +00:00

New option --constants-prefix.

This commit is contained in:
Bruno Haible
2011-01-16 16:43:45 +01:00
parent 61edba6dde
commit 5ac5f15a74
8 changed files with 189 additions and 26 deletions

View File

@@ -1,3 +1,28 @@
2011-01-11 Bruno Haible <bruno@clisp.org>
New option --constants-prefix.
* src/options.h (Options): Add member functions get_constants_prefix,
set_constants_prefix. Add member _constants_prefix.
* src/options.icc (Options::get_constants_prefix): New functions.
* src/options.cc (DEFAULT_CONSTANTS_PREFIX): New constant.
(Options::long_usage): Document --constants-prefix option.
(Options::Options): Initialize _constants_prefix member.
(Options::set_constants_prefix): New function.
(long_options): Add --constants-prefix option.
(Options::parse_options): Handle --constants-prefix option.
* src/input.cc (Input::read_input): Handle %define constants-prefix
declaration.
* src/output.cc (output_constant): New function.
(Output::output_constants): Invoke it.
(Output::output_lookup_function_body): Prefix each reference to a
constant with the constants prefix.
* doc/gperf.texi: Bump copyright year.
(Gperf Declarations): Document %define constants-prefix.
(Controlling Identifiers): New section.
(Output Details): Document --constants-prefix option.
* NEWS: Mention the changes.
Reported by Julian Zubek <zubekj@gmail.com>.
2011-01-11 Bruno Haible <bruno@clisp.org>
* configure: Regenerated with autoconf-2.68.

2
NEWS
View File

@@ -2,6 +2,8 @@ New in 3.1:
* The generated C code is now in ANSI-C by default. If you want to support
pre-ANSI-C compilers, you need to provide the option --language=C on the
command line or %language=C in the source file.
* Added option --constants-prefix.
* Added declaration %define constants-prefix.
New in 3.0.4:

View File

@@ -17,7 +17,7 @@
@c some day we should @include version.texi instead of defining
@c these values at hand.
@set UPDATED 20 December 2009
@set UPDATED 11 January 2011
@set EDITION 3.1
@set VERSION 3.1
@c ---------------------
@@ -40,7 +40,7 @@
This file documents the features of the GNU Perfect Hash Function
Generator @value{VERSION}.
Copyright @copyright{} 1989-2009 Free Software Foundation, Inc.
Copyright @copyright{} 1989-2011 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
@@ -78,7 +78,7 @@ Software Foundation instead of in the original English.
@page
@vskip 0pt plus 1filll
Copyright @copyright{} 1989-2009 Free Software Foundation, Inc.
Copyright @copyright{} 1989-2011 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
@@ -133,6 +133,7 @@ High-Level Description of GNU @code{gperf}
* Input Format:: Input Format to @code{gperf}
* Output Format:: Output Format for Generated C Code with @code{gperf}
* Binary Strings:: Use of NUL bytes
* Controlling Identifiers:: Avoiding collisions of identifiers
* Output Copyright:: The Copyright of the Output.
Input Format to @code{gperf}
@@ -291,6 +292,7 @@ efficiently identify their respective reserved keywords.
* Input Format:: Input Format to @code{gperf}
* Output Format:: Output Format for Generated C Code with @code{gperf}
* Binary Strings:: Use of NUL bytes
* Controlling Identifiers:: Avoiding collisions of identifiers
* Output Copyright:: The Copyright of the Output.
@end menu
@@ -618,6 +620,15 @@ 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 constants-prefix @var{prefix}
@cindex @samp{%define constants-prefix}
Allows you to specify a prefix for the constants @code{TOTAL_KEYWORDS},
@code{MIN_WORD_LENGTH}, @code{MAX_WORD_LENGTH}, and so on. This option
permits the use of two hash tables in the same file, even when the option
@samp{-E} (or, equivalently, the @samp{%enum} declaration) is not given or
the option @samp{-G} (or, equivalently, the @samp{%global-table} declaration)
is given.
@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
@@ -846,7 +857,7 @@ with the various input and output options, and timing the resulting C
code, you can determine the best option choices for different keyword
set characteristics.
@node Binary Strings, Output Copyright, Output Format, Description
@node Binary Strings, Controlling Identifiers, Output Format, Description
@section Use of NUL bytes
@cindex NUL
@@ -871,7 +882,65 @@ generated by @code{gperf} will treat NUL like any other byte.
Also, in this case the @samp{-c} option (or, equivalently, the
@samp{%compare-strncmp} declaration) is ignored.
@node Output Copyright, , Binary Strings, Description
@node Controlling Identifiers, Output Copyright, Binary Strings, Description
@section Controlling Identifiers
The identifiers of the functions, tables, and constants defined by the code
generated by @code{gperf} can be controlled through @code{gperf} declarations
or the equivalent command-line options. This is useful for three purposes:
@itemize
@item
Esthetics of the generated code.
For this purpose, just use the available declarations or options at will.
@item
Controlling the exported identifiers of a library.
Assume you include code generated by @code{gperf} in a library, and to
avoid collisions with other libraries, you want to ensure that all exported
identifiers of this library start with a certain prefix.
By default, the only exported identifier is the lookup function. You can
therefore use the option @samp{-N} (or, equivalently, the
@samp{%define lookup-function-name} declaration).
When you use the option @samp{-L C++} (or, equivalently, the
@samp{%language=C++} declaration), the only exported entity is a class.
You control its name through the option @samp{-Z} (or, equivalently, the
@samp{%define class-name} declaration).
@item
Allowing multiple @code{gperf} generated codes in a single compilation unit.
Assume you invoke @code{gperf} multiple times, with different input files,
and want the generated code to included from the same source file. In this
case, you have to customize not only the exported identifiers, but also the
names of functions with @samp{static} scope, types, and constants.
By default, you will have to deal with the lookup function, the hash
function, and the constants. You should therefore use the option @samp{-N}
(or, equivalently, the @samp{%define lookup-function-name} declaration),
the option @samp{-H} (or, equivalently, the
@samp{%define hash-function-name} declaration), and the option
@samp{--constants-prefix} (or, equivalently, the
@samp{%define constants-prefix} declaration).
If you use the option @samp{-G} (or, equivalently, the @samp{%global-table}
declaration), you will also have to deal with the word array, the length
table if present, and the string pool if present. This means: You should
use the option @samp{-W} (or, equivalently, the
@samp{%define word-array-name} declaration). If you use the option
@samp{-l} (or, equivalently, the @samp{%compare-lengths} declaration), you
should use the option @samp{--length-table-name} (or, equivalently, the
@samp{%define length-table-name} declaration). If you use the option
@samp{-P} (or, equivalently, the @samp{%pic} declaration), you should use
the option @samp{-Q} (or, equivalently, the @samp{%define string-pool-name}
declaration).
@end itemize
@node Output Copyright, , Controlling Identifiers, Description
@section The Copyright of the Output
@cindex Copyright
@@ -1078,6 +1147,7 @@ by putting the tables in readonly memory.
@item -E
@itemx --enum
@cindex Constants definition
Define constant values using an enum local to the lookup function rather
than with #defines. This also means that different lookup functions can
reside in the same file. Thanks to James Clark @code{<jjc@@ai.mit.edu>}.
@@ -1120,6 +1190,15 @@ 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.
@itemx --constants-prefix=@var{prefix}
@cindex Constants prefix
Allows you to specify a prefix for the constants @code{TOTAL_KEYWORDS},
@code{MIN_WORD_LENGTH}, @code{MAX_WORD_LENGTH}, and so on. This option
permits the use of two hash tables in the same file, even when the option
@samp{-E} (or, equivalently, the @samp{%enum} declaration) is not given or
the option @samp{-G} (or, equivalently, the @samp{%global-table} declaration)
is given.
@item -W @var{hash-table-array-name}
@itemx --word-array-name=@var{hash-table-array-name}
@cindex Array name

View File

@@ -1,5 +1,5 @@
/* Input routines.
Copyright (C) 1989-1998, 2002-2004 Free Software Foundation, Inc.
Copyright (C) 1989-1998, 2002-2004, 2011 Free Software Foundation, Inc.
Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
and Bruno Haible <bruno@clisp.org>.
@@ -545,6 +545,11 @@ Input::read_input ()
option.set (NULLSTRINGS);
else
if (is_define_declaration (line, line_end, lineno,
"constants-prefix", &arg))
option.set_constants_prefix (arg);
else
if (is_define_declaration (line, line_end, lineno,
"word-array-name", &arg))
option.set_wordlist_name (arg);

View File

@@ -1,5 +1,5 @@
/* Handles parsing the Options provided to the user.
Copyright (C) 1989-1998, 2000, 2002-2004, 2006-2009 Free Software Foundation, Inc.
Copyright (C) 1989-1998, 2000, 2002-2004, 2006-2009, 2011 Free Software Foundation, Inc.
Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
and Bruno Haible <bruno@clisp.org>.
@@ -62,6 +62,9 @@ static const char *const DEFAULT_LENGTHTABLE_NAME = "lengthtable";
/* Default name for string pool. */
static const char *const DEFAULT_STRINGPOOL_NAME = "stringpool";
/* Default prefix for constants. */
static const char *const DEFAULT_CONSTANTS_PREFIX = "";
/* Default delimiters that separate keywords from their attributes. */
static const char *const DEFAULT_DELIMITERS = ",";
@@ -176,6 +179,9 @@ Options::long_usage (FILE * stream)
fprintf (stream,
" --null-strings Use NULL strings instead of empty strings for empty\n"
" keyword table entries.\n");
fprintf (stream,
" --constants-prefix=PREFIX\n"
" Specify prefix for the constants like TOTAL_KEYWORDS.\n");
fprintf (stream,
" -W, --word-array-name=NAME\n"
" Specify name of word list array. Default name is\n"
@@ -465,6 +471,7 @@ Options::Options ()
_wordlist_name (DEFAULT_WORDLIST_NAME),
_lengthtable_name (DEFAULT_LENGTHTABLE_NAME),
_stringpool_name (DEFAULT_STRINGPOOL_NAME),
_constants_prefix (DEFAULT_CONSTANTS_PREFIX),
_delimiters (DEFAULT_DELIMITERS),
_key_positions ()
{
@@ -649,6 +656,14 @@ Options::set_lengthtable_name (const char *name)
_lengthtable_name = name;
}
/* Sets the prefix for the constants, if not already set. */
void
Options::set_constants_prefix (const char *prefix)
{
if (_constants_prefix == DEFAULT_CONSTANTS_PREFIX)
_constants_prefix = prefix;
}
/* Sets the string pool name, if not already set. */
void
Options::set_stringpool_name (const char *name)
@@ -688,6 +703,7 @@ static const struct option long_options[] =
{ "enum", no_argument, NULL, 'E' },
{ "includes", no_argument, NULL, 'I' },
{ "global-table", no_argument, NULL, 'G' },
{ "constants-prefix", required_argument, NULL, CHAR_MAX + 5 },
{ "word-array-name", required_argument, NULL, 'W' },
{ "length-table-name", required_argument, NULL, CHAR_MAX + 4 },
{ "switch", required_argument, NULL, 'S' },
@@ -1044,6 +1060,11 @@ There is NO WARRANTY, to the extent permitted by law.\n\
_lengthtable_name = /*getopt*/optarg;
break;
}
case CHAR_MAX + 5: /* Sets the prefix for the constants. */
{
_constants_prefix = /*getopt*/optarg;
break;
}
default:
short_usage (stderr);
exit (1);

View File

@@ -2,7 +2,7 @@
/* Handles parsing the Options provided to the user.
Copyright (C) 1989-1998, 2000, 2002-2004 Free Software Foundation, Inc.
Copyright (C) 1989-1998, 2000, 2002-2004, 2011 Free Software Foundation, Inc.
Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
and Bruno Haible <bruno@clisp.org>.
@@ -202,6 +202,11 @@ public:
/* Sets the string pool name, if not already set. */
void set_stringpool_name (const char *name);
/* Returns the prefix for the constants. */
const char * get_constants_prefix () const;
/* Sets the prefix for the constants, if not already set. */
void set_constants_prefix (const char *prefix);
/* Returns the string used to delimit keywords from other attributes. */
const char * get_delimiters () const;
/* Sets the delimiters string, if not already set. */
@@ -274,6 +279,9 @@ private:
/* Name used for the string pool. */
const char * _stringpool_name;
/* Prefix for the constants. */
const char * _constants_prefix;
/* Separates keywords from other attributes. */
const char * _delimiters;

View File

@@ -1,6 +1,6 @@
/* Inline Functions for options.{h,cc}.
Copyright (C) 1989-1998, 2000, 2002-2004 Free Software Foundation, Inc.
Copyright (C) 1989-1998, 2000, 2002-2004, 2011 Free Software Foundation, Inc.
Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
and Bruno Haible <bruno@clisp.org>.
@@ -140,6 +140,13 @@ Options::get_stringpool_name () const
return _stringpool_name;
}
/* Returns the prefix for the constants. */
INLINE const char *
Options::get_constants_prefix () const
{
return _constants_prefix;
}
/* Returns the string used to delimit keywords from other attributes. */
INLINE const char *
Options::get_delimiters () const

View File

@@ -1,5 +1,5 @@
/* Output routines.
Copyright (C) 1989-1998, 2000, 2002-2004, 2006-2007, 2009 Free Software Foundation, Inc.
Copyright (C) 1989-1998, 2000, 2002-2004, 2006-2007, 2009, 2011 Free Software Foundation, Inc.
Written by Douglas C. Schmidt <schmidt@ics.uci.edu>
and Bruno Haible <bruno@clisp.org>.
@@ -214,17 +214,29 @@ void Output_Enum::output_end ()
printf ("%s };\n\n", _indentation);
}
/* Outputs a constant in the given style. */
static void
output_constant (struct Output_Constants& style, const char *name, int value)
{
const char *prefix = option.get_constants_prefix ();
char combined_name[strlen (prefix) + strlen (name) + 1];
strcpy (combined_name, prefix);
strcpy (combined_name + strlen (prefix), name);
style.output_item (combined_name, value);
}
/* Outputs the maximum and minimum hash values etc. */
void
Output::output_constants (struct Output_Constants& style) const
{
style.output_start ();
style.output_item ("TOTAL_KEYWORDS", _total_keys);
style.output_item ("MIN_WORD_LENGTH", _min_key_len);
style.output_item ("MAX_WORD_LENGTH", _max_key_len);
style.output_item ("MIN_HASH_VALUE", _min_hash_value);
style.output_item ("MAX_HASH_VALUE", _max_hash_value);
output_constant (style, "TOTAL_KEYWORDS", _total_keys);
output_constant (style, "MIN_WORD_LENGTH", _min_key_len);
output_constant (style, "MAX_WORD_LENGTH", _max_key_len);
output_constant (style, "MIN_HASH_VALUE", _min_hash_value);
output_constant (style, "MAX_HASH_VALUE", _max_hash_value);
style.output_end ();
}
@@ -1575,9 +1587,10 @@ output_switches (KeywordExt_List *list, int num_switches, int size, int min_hash
void
Output::output_lookup_function_body (const Output_Compare& comparison) const
{
printf (" if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)\n"
printf (" if (len <= %sMAX_WORD_LENGTH && len >= %sMIN_WORD_LENGTH)\n"
" {\n"
" register int key = %s (str, len);\n\n",
option.get_constants_prefix (), option.get_constants_prefix (),
option.get_hash_name ());
if (option[SWITCH])
@@ -1587,8 +1600,9 @@ Output::output_lookup_function_body (const Output_Compare& comparison) const
if (num_switches > switch_size)
num_switches = switch_size;
printf (" if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)\n"
" {\n");
printf (" if (key <= %sMAX_HASH_VALUE && key >= %sMIN_HASH_VALUE)\n"
" {\n",
option.get_constants_prefix (), option.get_constants_prefix ());
if (option[DUP] && _total_duplicates > 0)
{
if (option[LENTABLE])
@@ -1686,7 +1700,8 @@ Output::output_lookup_function_body (const Output_Compare& comparison) const
}
else
{
printf (" if (key <= MAX_HASH_VALUE && key >= 0)\n");
printf (" if (key <= %sMAX_HASH_VALUE && key >= 0)\n",
option.get_constants_prefix ());
if (option[DUP])
{
@@ -1732,19 +1747,20 @@ Output::output_lookup_function_body (const Output_Compare& comparison) const
}
if (_total_duplicates > 0)
{
printf ("%*s else if (index < -TOTAL_KEYWORDS)\n"
printf ("%*s else if (index < -%sTOTAL_KEYWORDS)\n"
"%*s {\n"
"%*s register int offset = - 1 - TOTAL_KEYWORDS - index;\n",
indent, "", indent, "", indent, "");
"%*s register int offset = - 1 - %sTOTAL_KEYWORDS - index;\n",
indent, "", option.get_constants_prefix (), indent, "",
indent, "", option.get_constants_prefix ());
if (option[LENTABLE])
printf ("%*s register %s%s *lengthptr = &%s[TOTAL_KEYWORDS + lookup[offset]];\n",
printf ("%*s register %s%s *lengthptr = &%s[%sTOTAL_KEYWORDS + lookup[offset]];\n",
indent, "", const_always, smallest_integral_type (_max_key_len),
option.get_lengthtable_name ());
option.get_lengthtable_name (), option.get_constants_prefix ());
printf ("%*s register ",
indent, "");
output_const_type (const_readonly_array, _wordlist_eltype);
printf ("*wordptr = &%s[TOTAL_KEYWORDS + lookup[offset]];\n",
option.get_wordlist_name ());
printf ("*wordptr = &%s[%sTOTAL_KEYWORDS + lookup[offset]];\n",
option.get_wordlist_name (), option.get_constants_prefix ());
printf ("%*s register ",
indent, "");
output_const_type (const_readonly_array, _wordlist_eltype);