Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #24302 > unrolled thread

Preprocessor automation to define/declare array of strings

Started bypozzugno@gmail.com (pozz)
First post2012-08-06 16:23 +0200
Last post2012-08-11 06:09 +0000
Articles 14 — 9 participants

Back to article view | Back to comp.lang.c


Contents

  Preprocessor automation to define/declare array of strings pozzugno@gmail.com (pozz) - 2012-08-06 16:23 +0200
    Re: Preprocessor automation to define/declare array of strings Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-08-06 10:51 -0400
      Re: Preprocessor automation to define/declare array of strings Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-08-06 11:01 -0400
      Re: Preprocessor automation to define/declare array of strings pozzugno@gmail.com (pozz) - 2012-08-06 17:10 +0200
        Re: Preprocessor automation to define/declare array of strings Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-08-06 12:51 -0400
        Re: Preprocessor automation to define/declare array of strings Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-08-06 18:27 +0100
          Re: Preprocessor automation to define/declare array of strings Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-08-10 11:35 +0300
            OT (Re: Preprocessor automation to define/declare array of strings) Mark Bluemel <mark_bluemel@pobox.com> - 2012-08-10 09:56 +0100
              Re: OT (Re: Preprocessor automation to define/declare array of strings) Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-08-12 02:38 +0300
            Re: Preprocessor automation to define/declare array of strings Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-08-10 12:45 +0100
        Re: Preprocessor automation to define/declare array of strings Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-08-07 00:16 -0700
          Re: Preprocessor automation to define/declare array of strings Tim Rentsch <txr@alumni.caltech.edu> - 2012-09-07 13:49 -0700
    Re: Preprocessor automation to define/declare array of strings Ike Naar <ike@faeroes.freeshell.org> - 2012-08-06 14:55 +0000
    Re: Preprocessor automation to define/declare array of strings Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-08-11 06:09 +0000

#24302 — Preprocessor automation to define/declare array of strings

Frompozzugno@gmail.com (pozz)
Date2012-08-06 16:23 +0200
SubjectPreprocessor automation to define/declare array of strings
Message-ID<jvojvp$vlg$1@news.newsland.it>
I have a lot of array of strings defined in strings.c and declared in
strings.h.

--- strings.c ---
const char *strlist_month[] = { "Jan", "Feb", ... };
const char *strlist_day[] = { "Mon", "Thu", ... };
const char *strlist_onoff[] = { "ON", "OFF" };

--- strings.h ---
extern const char *strlist_month[];
extern const char *strlist_day[];
extern const char *strlist_onoff[];

They are used to write a list of possible values for certain user-defined
parameters:

  print_list(const char *strlist[], size_t size) {
    size_t i;
    for (i = 0; i < size; i++) {
      printf("%sn", list[i];
    }
  }

As you can understand, maintain synchronized strings.c and strings.h can
be tedious: when I add a list in strings.c, I have to remember to add it
in strings.h also and I have to take care to use the same name.

I was thinking to automate the declaration/definition of lists of strings
through C preprocessor. For example:

--- defstrings.def ---
STRINGLIST(strlist_month, { "Jan", "Feb", ... } );
STRINGLIST(strlist_day, { "Mon", "Thu", ... } );
STRINGLIST(strlist_onoff, { "ON", "OFF", ... } );
--- defstrings.c ---
#define STRINGLIST(name, list) const char *name[] = list;
#include "defstrings.def"
--- defstrings.h ---
#define STRINGLIST(name, list) extern const char *name[];

Have you a better suggestion?

-- 

questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news segnala gli abusi ad abuse@newsland.it

[toc] | [next] | [standalone]


#24304

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-08-06 10:51 -0400
Message-ID<jvolm6$jti$1@dont-email.me>
In reply to#24302
On 8/6/2012 10:23 AM, pozz wrote:
> I have a lot of array of strings defined in strings.c and declared in
> strings.h.
>
> --- strings.c ---
> const char *strlist_month[] = { "Jan", "Feb", ... };
> const char *strlist_day[] = { "Mon", "Thu", ... };

     Calendar reform?

> const char *strlist_onoff[] = { "ON", "OFF" };

     It's too bad that strlist_onoff[false] is "ON" ...

>[...]
> As you can understand, maintain synchronized strings.c and strings.h can
> be tedious: when I add a list in strings.c, I have to remember to add it
> in strings.h also and I have to take care to use the same name.
>
> I was thinking to automate the declaration/definition of lists of strings
> through C preprocessor. For example:
>
> --- defstrings.def ---
> STRINGLIST(strlist_month, { "Jan", "Feb", ... } );
> STRINGLIST(strlist_day, { "Mon", "Thu", ... } );
> STRINGLIST(strlist_onoff, { "ON", "OFF", ... } );
> --- defstrings.c ---
> #define STRINGLIST(name, list) const char *name[] = list;
> #include "defstrings.def"
> --- defstrings.h ---
> #define STRINGLIST(name, list) extern const char *name[];
>
> Have you a better suggestion?

     You're on the right track, but the execution is faulty.  The
problem is the "list" piece, for which I think the best solution
is a C99-style variadic macro.  The two versions would be

	#define STRINGLIST(name,...) \
	    const char *name[] = { __VA_ARGS__ }  // BTW, no ;
and
	#define STRINGLIST(name,...) \
	    extern const char *name[]  // no ;

You'd invoke them as

	STRINGLIST(strlist_onoff, "ON", "OFF", "HEISENBERG");

     See also Question 10.26 in the FAQ at <http://www.c-faq.com/>.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#24306

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-08-06 11:01 -0400
Message-ID<jvom8g$mi1$1@dont-email.me>
In reply to#24304
On 8/6/2012 10:51 AM, Eric Sosman wrote:
>[...]
>      See also Question 10.26 in the FAQ at <http://www.c-faq.com/>.

     Typo: "Question 10.25" -- sorry!

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#24307

Frompozzugno@gmail.com (pozz)
Date2012-08-06 17:10 +0200
Message-ID<jvomna$48e$1@news.newsland.it>
In reply to#24304
Eric Sosman ha scritto:
> On 8/6/2012 10:23 AM, pozz wrote:
> > I have a lot of array of strings defined in strings.c and declared in
> > strings.h.
> >
> > --- strings.c ---
> > const char *strlist_month[] = { "Jan", "Feb", ... };
> > const char *strlist_day[] = { "Mon", "Thu", ... };
>
>      Calendar reform?

Ooops... :-)


> > const char *strlist_onoff[] = { "ON", "OFF" };
>
>      It's too bad that strlist_onoff[false] is "ON" ...

You are right.


> >[...]
> > As you can understand, maintain synchronized strings.c and strings.h can
> > be tedious: when I add a list in strings.c, I have to remember to add it
> > in strings.h also and I have to take care to use the same name.
> >
> > I was thinking to automate the declaration/definition of lists of strings
> > through C preprocessor. For example:
> >
> > --- defstrings.def ---
> > STRINGLIST(strlist_month, { "Jan", "Feb", ... } );
> > STRINGLIST(strlist_day, { "Mon", "Thu", ... } );
> > STRINGLIST(strlist_onoff, { "ON", "OFF", ... } );
> > --- defstrings.c ---
> > #define STRINGLIST(name, list) const char *name[] = list;
> > #include "defstrings.def"
> > --- defstrings.h ---
> > #define STRINGLIST(name, list) extern const char *name[];
> >
> > Have you a better suggestion?
>
>      You're on the right track, but the execution is faulty.  The
> problem is the "list" piece, for which I think the best solution
> is a C99-style variadic macro.  The two versions would be
>
> 	#define STRINGLIST(name,...) 
> 	    const char *name[] = { __VA_ARGS__ }  // BTW, no ;
> and
> 	#define STRINGLIST(name,...) 
> 	    extern const char *name[]  // no ;
>
> You'd invoke them as
>
> 	STRINGLIST(strlist_onoff, "ON", "OFF", "HEISENBERG");

And what if my "very old microcontroller" compiler doesn't support
variadic macros?


>      See also Question 10.26 in the FAQ at <http://www.c-faq.com/>.

Ok, I read 10.25. Are you suggesting to migrate toward another
preprocessor tool instead of insisting with C preprocessor? Is my request
so far from C preprocessor features?
How can I use m4 to solve this problem?



-- 

questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news segnala gli abusi ad abuse@newsland.it

[toc] | [prev] | [next] | [standalone]


#24309

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-08-06 12:51 -0400
Message-ID<jvosmb$1ct$1@dont-email.me>
In reply to#24307
On 8/6/2012 11:10 AM, pozz wrote:
> Eric Sosman ha scritto:
>> On 8/6/2012 10:23 AM, pozz wrote:
>>> I have a lot of array of strings defined in strings.c and declared in
>>> strings.h.
>>>
>>> --- strings.c ---
>>> const char *strlist_month[] = { "Jan", "Feb", ... };
>>> const char *strlist_day[] = { "Mon", "Thu", ... };
>>
>>       Calendar reform?
>
> Ooops... :-)
>
>
>>> const char *strlist_onoff[] = { "ON", "OFF" };
>>
>>       It's too bad that strlist_onoff[false] is "ON" ...
>
> You are right.
>
>
>>> [...]
>>> As you can understand, maintain synchronized strings.c and strings.h can
>>> be tedious: when I add a list in strings.c, I have to remember to add it
>>> in strings.h also and I have to take care to use the same name.
>>>
>>> I was thinking to automate the declaration/definition of lists of strings
>>> through C preprocessor. For example:
>>>
>>> --- defstrings.def ---
>>> STRINGLIST(strlist_month, { "Jan", "Feb", ... } );
>>> STRINGLIST(strlist_day, { "Mon", "Thu", ... } );
>>> STRINGLIST(strlist_onoff, { "ON", "OFF", ... } );
>>> --- defstrings.c ---
>>> #define STRINGLIST(name, list) const char *name[] = list;
>>> #include "defstrings.def"
>>> --- defstrings.h ---
>>> #define STRINGLIST(name, list) extern const char *name[];
>>>
>>> Have you a better suggestion?
>>
>>       You're on the right track, but the execution is faulty.  The
>> problem is the "list" piece, for which I think the best solution
>> is a C99-style variadic macro.  The two versions would be
>>
>> 	#define STRINGLIST(name,...)
>> 	    const char *name[] = { __VA_ARGS__ }  // BTW, no ;
>> and
>> 	#define STRINGLIST(name,...)
>> 	    extern const char *name[]  // no ;
>>
>> You'd invoke them as
>>
>> 	STRINGLIST(strlist_onoff, "ON", "OFF", "HEISENBERG");
>
> And what if my "very old microcontroller" compiler doesn't support
> variadic macros?

     Then I think you're out of luck.

>>       See also Question 10.26 in the FAQ at <http://www.c-faq.com/>.
>
> Ok, I read 10.25. Are you suggesting to migrate toward another
> preprocessor tool instead of insisting with C preprocessor? Is my request
> so far from C preprocessor features?

     I'm suggesting that this may be about as far as you want
to try to take the preprocessor, even if it could (with effort)
be taken further.  Even taking it this far requires[*] a feature
introduced in C99, so if you can't use C99 capabilities you may
already be beyond the pale.

     [*] "Requires" may be too strong. Some people can make the
preprocessor whistle "Dixie" while riding a bicycle backwards
and juggling lit blowtorches (Hallvard Furuseth comes to mind).
Perhaps a wizard can figure out a way to do what you want using
only C90 features, which would mean that "requires" is wrong.

> How can I use m4 to solve this problem?

     Dunno; I've only used m4 in "prepackaged" settings.  If I
were in your situation, unable to use C99 macros, I'd probably
either bite the bullet and maintain the two files in parallel,
or write a little twenty-line program to parse a single input
file and write .c and .h files as output.  Maybe with m4 you
can do it in fewer than twenty lines.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#24311

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-08-06 18:27 +0100
Message-ID<0.2dc85159ee187ef4ad8e.20120806182733BST.87wr1cylq2.fsf@bsb.me.uk>
In reply to#24307
pozzugno@gmail.com (pozz) writes:
<snip>
> And what if my "very old microcontroller" compiler doesn't support
> variadic macros?

In the common include write this:

  STRINGLIST(strlist_month) { "Jan", "Feb", "Mar" } EOL));

and so on for each list.  To get the .c file use:

  #define KILL(x)
  #define STRINGLIST(name) const char *name[] =
  #define EOL KILL((

and to get the .h file use:

  #define KILL(x)
  #define STRINGLIST(name) extern const char *name[] KILL((
  #define EOL

The "KILL" macro is the same.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#24394

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2012-08-10 11:35 +0300
Message-ID<87mx23400u.fsf@bazspaz.fatphil.org>
In reply to#24311
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> pozzugno@gmail.com (pozz) writes:
> <snip>
> > And what if my "very old microcontroller" compiler doesn't support
> > variadic macros?
> 
> In the common include write this:
> 
>   STRINGLIST(strlist_month) { "Jan", "Feb", "Mar" } EOL));
> 
> and so on for each list.  To get the .c file use:
> 
>   #define KILL(x)
>   #define STRINGLIST(name) const char *name[] =
>   #define EOL KILL((
> 
> and to get the .h file use:
> 
>   #define KILL(x)
>   #define STRINGLIST(name) extern const char *name[] KILL((
>   #define EOL
> 
> The "KILL" macro is the same.

I find that a little perverse with the parentheses divorced from their partners, 
but not actually wrong. Perhaps "clever" is the most appropriate way of expressing
my worries about it.


For variety, I'm sure I encountered something like this in the past:

In one location define:

#define INTRO(name) const char *name[] = {
#define ELEMENT(s) s,
#define OUTRO };

In a different location define:

#define INTRO(name) extern const char *name[];
#define ELEMENT(s)
#define OUTRO

Which permits you do have files such as

INTRO(strlist_month)
ELEMENT("Jan")
ELEMENT("Feb")
...
OUTRO


I think when I saw it, the first thing that went through my mind was 

#define INTRO(name) extern const char *name[0
#define ELEMENT(s) +1
#define OUTRO ]

such that the clients can know the size of the array, which means you don't need a
sentinal at the end, or a redundantly-provided source for that information.
However, I've not ever really needed to use the technique. I offer it just as 
a new way of approaching the problem.

Phil
-- 
> I'd argue that there is much evidence for the existence of a God.
Pics or it didn't happen.
-- Tom (/. uid 822)

[toc] | [prev] | [next] | [standalone]


#24395 — OT (Re: Preprocessor automation to define/declare array of strings)

FromMark Bluemel <mark_bluemel@pobox.com>
Date2012-08-10 09:56 +0100
SubjectOT (Re: Preprocessor automation to define/declare array of strings)
Message-ID<k02icj$74q$1@dont-email.me>
In reply to#24394
On 10/08/2012 09:35, Phil Carmody wrote:

>
> For variety, I'm sure I encountered something like this in the past:
>
> In one location define:
>
> #define INTRO(name) const char *name[] = {
> #define ELEMENT(s) s,
> #define OUTRO };

I suddenly heard the dulcet tones of Vivian Stanshall when I read this - 
did anyone else?

-- 
Count Basie and his Orchestra, on triangle

[toc] | [prev] | [next] | [standalone]


#24445 — Re: OT (Re: Preprocessor automation to define/declare array of strings)

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2012-08-12 02:38 +0300
SubjectRe: OT (Re: Preprocessor automation to define/declare array of strings)
Message-ID<871ujd3sp3.fsf@bazspaz.fatphil.org>
In reply to#24395
Mark Bluemel <mark_bluemel@pobox.com> writes:
> On 10/08/2012 09:35, Phil Carmody wrote:
> > For variety, I'm sure I encountered something like this in the past:
> >
> > In one location define:
> >
> > #define INTRO(name) const char *name[] = {
> > #define ELEMENT(s) s,
> > #define OUTRO };
> 
> I suddenly heard the dulcet tones of Vivian Stanshall when I read this
> - did anyone else?

Nope, but if I had all the money I'd spent ond drink, I'd spend it on drink!

Phil
-- 
> I'd argue that there is much evidence for the existence of a God.
Pics or it didn't happen.
-- Tom (/. uid 822)

[toc] | [prev] | [next] | [standalone]


#24396

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-08-10 12:45 +0100
Message-ID<0.beacfbb37bb1fffc3bae.20120810124516BST.877gt7x96b.fsf@bsb.me.uk>
In reply to#24394
Phil Carmody <thefatphil_demunged@yahoo.co.uk> writes:

> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>> pozzugno@gmail.com (pozz) writes:
>> <snip>
>> > And what if my "very old microcontroller" compiler doesn't support
>> > variadic macros?
>> 
>> In the common include write this:
>> 
>>   STRINGLIST(strlist_month) { "Jan", "Feb", "Mar" } EOL));
>> 
>> and so on for each list.  To get the .c file use:
>> 
>>   #define KILL(x)
>>   #define STRINGLIST(name) const char *name[] =
>>   #define EOL KILL((
>> 
>> and to get the .h file use:
>> 
>>   #define KILL(x)
>>   #define STRINGLIST(name) extern const char *name[] KILL((
>>   #define EOL
>> 
>> The "KILL" macro is the same.
>
> I find that a little perverse with the parentheses divorced from their
> partners, but not actually wrong. Perhaps "clever" is the most
> appropriate way of expressing my worries about it.

Yes, it's... odd looking.

> For variety, I'm sure I encountered something like this in the past:
>
> In one location define:
>
> #define INTRO(name) const char *name[] = {
> #define ELEMENT(s) s,
> #define OUTRO };
>
> In a different location define:
>
> #define INTRO(name) extern const char *name[];
> #define ELEMENT(s)
> #define OUTRO
>
> Which permits you do have files such as
>
> INTRO(strlist_month)
> ELEMENT("Jan")
> ELEMENT("Feb")
> ...
> OUTRO

I posted what I did because the OP had said:

| And what if my "very old microcontroller" compiler doesn't support
| variadic macros?

which made me think that the compiler probably did not accept trailing
commas in an initialiser list.  That can be fixed, of course, by adding
a sentinel to OUTRO:

  #define OUTRO 0 };

but it's never clear in these situations what's OK and what isn't, so I
searched for a solution that matched the __VA_ARGS__ one that had
already been posted.

> I think when I saw it, the first thing that went through my mind was 
>
> #define INTRO(name) extern const char *name[0
> #define ELEMENT(s) +1
> #define OUTRO ]

(should be ]; to match the ones above)

> such that the clients can know the size of the array, which means you
> don't need a sentinal at the end, or a redundantly-provided source for
> that information.

Now that's definitely a plus point for doing it element by element.  If
the OP's compiler does accept trailing commas, this might be
significant.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#24339

FromNick Keighley <nick_keighley_nospam@hotmail.com>
Date2012-08-07 00:16 -0700
Message-ID<467a10ce-c7a4-4730-b89e-95e3cd6bdebd@d8g2000yqj.googlegroups.com>
In reply to#24307
On Aug 6, 4:10 pm, pozzu...@gmail.com (pozz) wrote:
> Eric Sosman ha scritto:
>
> > On 8/6/2012 10:23 AM, pozz wrote:
> > > I have a lot of array of strings defined in strings.c and declared in
> > > strings.h.
>
> > > --- strings.c ---
> > > const char *strlist_month[] = { "Jan", "Feb", ... };
> > > const char *strlist_day[] = { "Mon", "Thu", ... };
>
> >      Calendar reform?
>
> Ooops... :-)
>
> > > const char *strlist_onoff[] = { "ON", "OFF" };
>
> >      It's too bad that strlist_onoff[false] is "ON" ...
>
> You are right.
>
>
>
>
>
> > >[...]
> > > As you can understand, maintain synchronized strings.c and strings.h can
> > > be tedious: when I add a list in strings.c, I have to remember to add it
> > > in strings.h also and I have to take care to use the same name.
>
> > > I was thinking to automate the declaration/definition of lists of strings
> > > through C preprocessor. For example:
>
> > > --- defstrings.def ---
> > > STRINGLIST(strlist_month, { "Jan", "Feb", ... } );
> > > STRINGLIST(strlist_day, { "Mon", "Thu", ... } );
> > > STRINGLIST(strlist_onoff, { "ON", "OFF", ... } );
> > > --- defstrings.c ---
> > > #define STRINGLIST(name, list) const char *name[] = list;
> > > #include "defstrings.def"
> > > --- defstrings.h ---
> > > #define STRINGLIST(name, list) extern const char *name[];
>
> > > Have you a better suggestion?
>
> >      You're on the right track, but the execution is faulty.  The
> > problem is the "list" piece, for which I think the best solution
> > is a C99-style variadic macro.  The two versions would be
>
> >    #define STRINGLIST(name,...)
> >        const char *name[] = { __VA_ARGS__ }  // BTW, no ;
> > and
> >    #define STRINGLIST(name,...)
> >        extern const char *name[]  // no ;
>
> > You'd invoke them as
>
> >    STRINGLIST(strlist_onoff, "ON", "OFF", "HEISENBERG");
>
> And what if my "very old microcontroller" compiler doesn't support
> variadic macros?
>
> >      See also Question 10.26 in the FAQ at <http://www.c-faq.com/>.
>
> Ok, I read 10.25. Are you suggesting to migrate toward another
> preprocessor tool instead of insisting with C preprocessor? Is my request
> so far from C preprocessor features?
> How can I use m4 to solve this problem?

another alternative is to generate both the .c and the .h
from a common definition file. Uing Perl maybe.

[toc] | [prev] | [next] | [standalone]


#26083

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-09-07 13:49 -0700
Message-ID<kfnzk51fthp.fsf@x-alumni2.alumni.caltech.edu>
In reply to#24339
Nick Keighley <nick_keighley_nospam@hotmail.com> writes:

> On Aug 6, 4:10 pm, pozzu...@gmail.com (pozz) wrote:
>> Eric Sosman ha scritto:
>>
>> > On 8/6/2012 10:23 AM, pozz wrote:
>> > > I have a lot of array of strings defined in strings.c and declared in
>> > > strings.h.
>>
>> > > --- strings.c ---
>> > > const char *strlist_month[] = { "Jan", "Feb", ... };
>> > > const char *strlist_day[] = { "Mon", "Thu", ... };
>>
>> >      Calendar reform?
>>
>> Ooops... :-)
>>
>> > > const char *strlist_onoff[] = { "ON", "OFF" };
>>
>> >      It's too bad that strlist_onoff[false] is "ON" ...
>>
>> You are right.
>>
>>
>>
>>
>>
>> > >[...]
>> > > As you can understand, maintain synchronized strings.c and strings.h can
>> > > be tedious: when I add a list in strings.c, I have to remember to add it
>> > > in strings.h also and I have to take care to use the same name.
>>
>> > > I was thinking to automate the declaration/definition of lists of strings
>> > > through C preprocessor. For example:
>>
>> > > --- defstrings.def ---
>> > > STRINGLIST(strlist_month, { "Jan", "Feb", ... } );
>> > > STRINGLIST(strlist_day, { "Mon", "Thu", ... } );
>> > > STRINGLIST(strlist_onoff, { "ON", "OFF", ... } );
>> > > --- defstrings.c ---
>> > > #define STRINGLIST(name, list) const char *name[] = list;
>> > > #include "defstrings.def"
>> > > --- defstrings.h ---
>> > > #define STRINGLIST(name, list) extern const char *name[];
>>
>> > > Have you a better suggestion?
>>
>> >      You're on the right track, but the execution is faulty.  The
>> > problem is the "list" piece, for which I think the best solution
>> > is a C99-style variadic macro.  The two versions would be
>>
>> >    #define STRINGLIST(name,...)
>> >        const char *name[] = { __VA_ARGS__ }  // BTW, no ;
>> > and
>> >    #define STRINGLIST(name,...)
>> >        extern const char *name[]  // no ;
>>
>> > You'd invoke them as
>>
>> >    STRINGLIST(strlist_onoff, "ON", "OFF", "HEISENBERG");
>>
>> And what if my "very old microcontroller" compiler doesn't support
>> variadic macros?
>>
>> >      See also Question 10.26 in the FAQ at <http://www.c-faq.com/>.
>>
>> Ok, I read 10.25. Are you suggesting to migrate toward another
>> preprocessor tool instead of insisting with C preprocessor? Is my request
>> so far from C preprocessor features?
>> How can I use m4 to solve this problem?
>
> another alternative is to generate both the .c and the .h
> from a common definition file. Uing Perl maybe.

I wrote a .c file in a perfectly ordinary way, then processed
the .c file to generate the corresponding .h file.  A four
line awk script.

[toc] | [prev] | [next] | [standalone]


#24305

FromIke Naar <ike@faeroes.freeshell.org>
Date2012-08-06 14:55 +0000
Message-ID<slrn3vfsk1vmmu.6e7.ike@faeroes.freeshell.org>
In reply to#24302
On 2012-08-06, pozz <pozzugno@gmail.com> wrote:
> I was thinking to automate the declaration/definition of lists of strings
> through C preprocessor. For example:
>
> --- defstrings.def ---
> STRINGLIST(strlist_month, { "Jan", "Feb", ... } );
> STRINGLIST(strlist_day, { "Mon", "Thu", ... } );
> STRINGLIST(strlist_onoff, { "ON", "OFF", ... } );
> --- defstrings.c ---
> #define STRINGLIST(name, list) const char *name[] = list;

This will not work. The macro takes two parameters,
but it is called with more than two arguments, e.g. in 

  STRINGLIST(strlist_onoff, { "ON", "OFF" } );

there are three arguments,

  strlist_onoff    /* first */
  { "ON"           /* second */
  "OFF" }          /* third */

This could be fixed using a variable arguments macro,

  #define STRINGLIST(name, ...) const char *name[] = __VA_ARGS__;

Another issue: perhaps it would be better to drop the terminating
semicolon from the macro definition, because if the macro is called
the way you do it, the result will have two terminating semicolons
which may cause syntax errors.

[toc] | [prev] | [next] | [standalone]


#24428

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2012-08-11 06:09 +0000
Message-ID<slrnk2btpn.ph6.grahn+nntp@frailea.sa.invalid>
In reply to#24302
On Mon, 2012-08-06, pozz wrote:
> I have a lot of array of strings defined in strings.c and declared in
> strings.h.

...
> As you can understand, maintain synchronized strings.c and strings.h can
> be tedious: when I add a list in strings.c, I have to remember to add it
> in strings.h also and I have to take care to use the same name.

Why?  As far as I can tell, you'll get a compilation/linking error if
you make any significant mistake here.

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web