bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: gperf wrapper


From: Bruno Haible
Subject: Re: gperf wrapper
Date: Wed, 14 Nov 2007 01:08:54 +0100
User-agent: KMail/1.5.4

Hi Bruce,

CCing bug-gnu-gperf.

> 99% of the time I have a use for gperf, it is simply for mapping a string into
> some sort of enumeration.  I have no need of a pointer to some funny mapping
> structure.  Just an enum.  Often, I use that enum to index an array of 
> procedure
> pointers.  Bit by bit I've polished the thing.  I'll give it to
> "gperf" if you think it
> might be helpful:
> 
>   bash mk-str2enum --base=my-names \
>     --dispatch='ret_t do_%s_handler(int a1, void *a2)' \
>     one two three four five six
> 
> and then you have a header (below) and the gperf generated .c file.
> The .c file containing this dispatch routine:
> 
> ret_t
> disp_my_names(char * str, unsigned int len, int a1, void *a2)
> {
>     my_names_handler_t
>         do_invalid_handler, do_one_handler,     do_two_handler,
>         do_three_handler,   do_four_handler,    do_five_handler,
>         do_six_handler;
> 
>     static my_names_handler_t * const dispatch[] = {
>         do_invalid_handler, do_one_handler,     do_two_handler,
>         do_three_handler,   do_four_handler,    do_five_handler,
>         do_six_handler };
>     my_names_enum_t id = find_my_names_id(str, len);
>     return dispatch[id](a1, a2);
> }
> 
> $ cat my-names.h
> /*
>  *  Generated header for gperf generated source Tue Nov 13 10:18:41 PST 2007
>  *  This file enumerates the list of names and declares the
>  *  procedure for mapping string names to the enum value.
>  */
> #ifndef CP3_MY_NAMES_H_GUARD
> #define CP3_MY_NAMES_H_GUARD 1
> 
> typedef enum {
>     MY_KWD_INVALID,
>     MY_KWD_ONE,
>     MY_KWD_TWO,
>     MY_KWD_THREE,
>     MY_KWD_FOUR,
>     MY_KWD_FIVE,
>     MY_KWD_SIX,
>     MY_COUNT_KWD
> } my_names_enum_t;
> 
> extern my_names_enum_t
> find_my_names_id(char const * str, unsigned int len);
> 
> extern char const *
> my_names_id_to_name(my_names_enum_t id);
> 
> typedef ret_t (my_names_handler_t)(int a1, void *a2);
> 
> extern ret_t
> disp_my_names(char * str, unsigned int len, int a1, void *a2);
> #endif /* CP3_MY_NAMES_H_GUARD */

This is certainly a good use of gperf, and since the same coding pattern
occurs several times in your environment, it sure is good to have a tool
for it (may be a C program, shell script, or substitution into some template
files, or similar).

Your question is whether this would be useful to be packaged as part of
"gperf". So let's consider:
  1) How many people have the same problem as you have?
  2) How many of those would be happy with what your tool generates?
  3) How hard would it be for them to not use your tool?


Ad 1) How many people have the same problem as you have?

Just for comparison, the 4 uses that I've made of gperf recently:

  struct alias { int name; unsigned int encoding_index; };
  struct mapping { int standard_name; const char vendor_name[10 + 1]; };
  struct named_property { const char *name; uc_property_t property; };
  struct named_script { const char *name; unsigned int index; };

So, 2 out of 4 uses map the string to a nonnegative index. In these cases,
the index was then an index into a private table. I didn't need an 'enum'
type in these cases.

But when someone needs an enum type (i.e. when a public API without
extensibility is required), your approach is OK.


Ad 2) How many of those would be happy with what your tool generates?

Lots of code would not need to do a lookup of a function pointer and call
the function immediately, but rather do this in separate steps. Your
generated code would be more generally useful if it returned a function
pointer:
   return dispatch[id];
instead of
   return dispatch[id](a1, a2);

Some code goes into shared libraries and would require to use %pic.

Some header files need to be usable in a mixed C/C++ environment and
therefore need conditional 'extern "C"' markers.

Some projects would want to copy the declarations into an existing header
file, rather than creating a new one.


Ad 3) How hard would it be for them to not use your tool?

Is using gperf directly that hard? No, the documentation and --help
message explain the use of gperf quite well, IMO.

Is generating a function template or header file template hard? No. It
does not even need automation. Many people can certainly also do it
in a text editor, with copy and query-replace.


Bruno





reply via email to

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