From 5ac5f15a74858f03b2f987a785ae2c9d10b6a28c Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 16 Jan 2011 16:43:45 +0100 Subject: New option --constants-prefix. --- ChangeLog | 25 ++++++++++++++++ NEWS | 2 ++ doc/gperf.texi | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/input.cc | 7 ++++- src/options.cc | 23 ++++++++++++++- src/options.h | 10 ++++++- src/options.icc | 9 +++++- src/output.cc | 50 +++++++++++++++++++++----------- 8 files changed, 189 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9d64ee1..9fca007 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2011-01-11 Bruno Haible + + 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 . + 2011-01-11 Bruno Haible * configure: Regenerated with autoconf-2.68. diff --git a/NEWS b/NEWS index a15b9b1..bcac2f3 100644 --- a/NEWS +++ b/NEWS @@ -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: diff --git a/doc/gperf.texi b/doc/gperf.texi index 0dc1fbe..51282e9 100644 --- a/doc/gperf.texi +++ b/doc/gperf.texi @@ -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{}. @@ -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 diff --git a/src/input.cc b/src/input.cc index e8a7831..c751e4c 100644 --- a/src/input.cc +++ b/src/input.cc @@ -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 and Bruno Haible . @@ -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); diff --git a/src/options.cc b/src/options.cc index 3da2b0e..145ea13 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-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 and Bruno Haible . @@ -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); diff --git a/src/options.h b/src/options.h index be1b29f..2ac53b8 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-2004 Free Software Foundation, Inc. + Copyright (C) 1989-1998, 2000, 2002-2004, 2011 Free Software Foundation, Inc. Written by Douglas C. Schmidt and Bruno Haible . @@ -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; diff --git a/src/options.icc b/src/options.icc index 6b8bc43..f766ec3 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-2004 Free Software Foundation, Inc. + Copyright (C) 1989-1998, 2000, 2002-2004, 2011 Free Software Foundation, Inc. Written by Douglas C. Schmidt and Bruno Haible . @@ -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 diff --git a/src/output.cc b/src/output.cc index 4b0e4c6..d887233 100644 --- a/src/output.cc +++ b/src/output.cc @@ -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 and Bruno Haible . @@ -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); -- cgit v1.2.1