[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [bug-gperf] --global-table bug
From: |
Bruce Korb |
Subject: |
Re: [bug-gperf] --global-table bug |
Date: |
Wed, 11 Aug 2010 15:46:55 -0700 |
Hi Bruno,
On Wed, Aug 11, 2010 at 3:04 PM, Bruno Haible <address@hidden> wrote:
>> is made global instead of remaining within the wordlist function.
>
> Yes, --global-table causes these values to become global, because
> you want to do something with them. They are meta-information about
> the hash function which you wanted to be global.
The wordlist table. Anyway, there's an option to make these values an enum
and not a #define specifically so that the values won't conflict with #defines
from other gperf sources. Then, when you say "make the table global", these
values again become global to the compilation unit.
> You have multiple ways of avoid name clashes. Use #define and #undef.
> Or use different compilation units.
Or post process with "sed". There are many ways to fix it. I prefer --prefix
>> I suppose it would be a
>> lot of bother to just say, "--prefix=foo" and prefix all global names
>> with "foo_"? e.g.
> I'm not asking for a patch. But if you could describe your use case better,
Primarily, it is a laziness issue. gperf has the following options:
`%define slot-name NAME'
`%define hash-function-name NAME'
`%define lookup-function-name NAME'
`%define string-pool-name NAME'
`%define word-array-name NAME'
`%enum'
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.
with the same fundamental purpose: to allow multiple of these things in the
same file. Without post processing or other somersaults, %global-table
basically defeats the purpose of %enum. --prefix would basically be
an option to prefix *all* externally visible names with some character-case-
appropriate variation of the prefix, including any globally visible
meta information
about the word list table. It would also eliminate the need for the
slot/hash/lookup/string-pool/word-array name options.
> it may convince me to add a new option for that. What are you attempting to
> do that requires --global-table?
"requires" is too strong of a word, since post-processing or #define
renaming can fix it:
> %{
> #define TOTAL_KEYWORDS FOO_TOTAL_KEYWORDS
> %}
> %%
> .........
> %%
> #undef TOTAL_KEYWORDS
But that seems really dodgy to me.
> Why are different compilation units inadequate? Why are #defines inadequate?
I can get along (and have gotten along for a long time) with things as they are.
It just seems unaesthetic to create the --enum option only to have its stated
purpose ("different lookup functions can reside in the same file") defeated with
the --global-table option.
> Most of gperf's options are made for the case where it generates an entire
> compilation unit. If you #include gperf's generated code from another file,
> you need less options from gperf because you can achieve the same effects
> with code in the main file.
I usually use it as a separately compiled module, post processed when needed.
I glue two functions to the end of the source for converting strings
to enumeration
values and back again, a la:
cat >&4 <<- _EOF_
%%
static int const ${base_name}_wordlist_sz =
sizeof(${base_name}_wordlist) / sizeof(${base_name}_wordlist[0]);
${base_name}_enum_t
str2${base_name}(char const * name) {
struct ${base_name}_index const * pI =
${base_name}_find(name, strlen(name));
if (pI == NULL)
return ${ABBREV}_INVALID_${BASE};
return (${base_name}_enum_t)pI->idx;
}
char const *
${base_name}2str(${base_name}_enum_t v) {
static char const invalid_str[] = "* invalid *";
const struct tms_events_index * wl = ${base_name}_wordlist;
if ((unsigned)v >= ${ABBREV}_INVALID_${BASE})
return invalid_str;
do {
if (wl->idx == v)
return wl->name;
wl++;
} while (wl < ${base_name}_wordlist + ${base_name}_wordlist_sz);
return invalid_str;
}
_EOF_
Actually, I always post process because the .gperf file is a temp file that
gets blown away after the .c and .h are built. (The .h being part of the
post processing.) I remove the "#line" directives.