bug-gperf
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]