Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > how to do two-stage preprocessing of one file

Reply
Thread Tools

how to do two-stage preprocessing of one file

 
 
andreyvul
Guest
Posts: n/a
 
      11-12-2007
What I'm trying to do is have the preprocessor parse one file twice.
The file has three parts, and each is dependent on the previous.
Example (file name is foo.c):
#ifndef ONCE /* first part */
#define D #define
#define ONCE
#include "foo.c"
#endif
#ifdef ONCE /* second part */
D x int
#ifndef TWICE
#define TWICE
#include "foo.c"
#endif
#endif
#ifdef TWICE /* third part */
x y;
#endif

The problem is that the preprocessor just adds the third part to the
second part, but doesn't preprocess the third part in the process.
How do I make my #includes and #ifedefs so that the third part will be
preprocessed?

 
Reply With Quote
 
 
 
 
Walter Roberson
Guest
Posts: n/a
 
      11-13-2007
In article <(E-Mail Removed). com>,
andreyvul <(E-Mail Removed)> wrote:
>What I'm trying to do is have the preprocessor parse one file twice.


You cannot do that using the facilities defined by the C preprocessor.

Your particular implementation -probably- offers a way to
preprocess files. For example, on the system I am using at the
moment, the sequence would look something like,

cc -P myfile.c
mv myfile.i myfile_preprocessed.c
cc -o outputfile myfile_preprocessed.c

But it would also not be uncommon on a Unix system for the sequence
to look something closer to

cc -E myfile.c | egrep -v '^#line' > myfile_preprocessed.c
cc -o outfile myfile_preprocessed.c

Many unix C compilers offer some option as in the second example,
to preprocess and send the result to standard output; it may
or may not be necessary in your toolchain to remove #line directives
from the preprocessed output before you can push the file back
through the C parseer.

If you are using one of the Windows compilers... there is probably
some similar option, but probably not named -P or -E .
--
"Is there any thing whereof it may be said, See, this is new? It hath
been already of old time, which was before us." -- Ecclesiastes
 
Reply With Quote
 
 
 
 
andreyvul
Guest
Posts: n/a
 
      11-13-2007
On Nov 12, 7:11 pm, (E-Mail Removed)-cnrc.gc.ca (Walter Roberson)
wrote:
> In article <(E-Mail Removed). com>,
>
> andreyvul <(E-Mail Removed)> wrote:
> >What I'm trying to do is have the preprocessor parse one file twice.

>
> You cannot do that using the facilities defined by the C preprocessor.

Oh, I meant _recursively_ preprocess the file twice.
That's why I was asking about proper #include/#ifdef structure, so
that it preprocesses like this:

#block 1
|->#block 2 (via recursive include)
|->#block 3 (via recursive include)

however, it doesn't get to |->#block 3

 
Reply With Quote
 
Ark Khasin
Guest
Posts: n/a
 
      11-13-2007
andreyvul wrote:
> On Nov 12, 7:11 pm, (E-Mail Removed)-cnrc.gc.ca (Walter Roberson)
> wrote:
>> In article <(E-Mail Removed). com>,
>>
>> andreyvul <(E-Mail Removed)> wrote:
>>> What I'm trying to do is have the preprocessor parse one file twice.

>> You cannot do that using the facilities defined by the C preprocessor.

> Oh, I meant _recursively_ preprocess the file twice.
> That's why I was asking about proper #include/#ifdef structure, so
> that it preprocesses like this:
>
> #block 1
> |->#block 2 (via recursive include)
> |->#block 3 (via recursive include)
>
> however, it doesn't get to |->#block 3
>

I didn't try it but something along these lines might do it:

#ifndef REC_COUNT
#define REC_COUNT 2
#elif REC_COUNT == 2
#undef REC_COUNT
#define REC_COUNT 1
#elif REC_COUNT == 1
#undef REC_COUNT
#define REC_COUNT 0
#endif
/* Here is the meat */
#if REC_COUNT == 2
/* first iteration */
#elif REC_COUNT == 1
/* second iteration */
#else
/* third and last iteration */
#if REC_COUNT != 0
#include __FILE__
#endif

--
Ark
 
Reply With Quote
 
Walter Roberson
Guest
Posts: n/a
 
      11-13-2007
In article <(E-Mail Removed) .com>,
andreyvul <(E-Mail Removed)> wrote:
>On Nov 12, 7:11 pm, (E-Mail Removed)-cnrc.gc.ca (Walter Roberson)
>wrote:
>> In article <(E-Mail Removed). com>,


>> andreyvul <(E-Mail Removed)> wrote:
>> >What I'm trying to do is have the preprocessor parse one file twice.


>> You cannot do that using the facilities defined by the C preprocessor.


>Oh, I meant _recursively_ preprocess the file twice.


Oh, in that case, let me correct my statement:

The facilities of the C preprocessor are defined in such a way that
you are not guaranteed to be able to do this; if you were able to
get it to work at all, it would be due to implementation-dependant
behaviour.
--
"History is a pile of debris" -- Laurie Anderson
 
Reply With Quote
 
andreyvul
Guest
Posts: n/a
 
      11-13-2007
On Nov 12, 7:58 pm, Ark Khasin <(E-Mail Removed)> wrote:
> andreyvul wrote:
> > On Nov 12, 7:11 pm, (E-Mail Removed)-cnrc.gc.ca (Walter Roberson)
> > wrote:
> >> In article <(E-Mail Removed). com>,

>
> >> andreyvul <(E-Mail Removed)> wrote:
> >>> What I'm trying to do is have the preprocessor parse one file twice.
> >> You cannot do that using the facilities defined by the C preprocessor.

> > Oh, I meant _recursively_ preprocess the file twice.
> > That's why I was asking about proper #include/#ifdef structure, so
> > that it preprocesses like this:

>
> > #block 1
> > |->#block 2 (via recursive include)
> > |->#block 3 (via recursive include)

>
> > however, it doesn't get to |->#block 3

>
> I didn't try it but something along these lines might do it:
>
> #ifndef REC_COUNT
> #define REC_COUNT 2
> #elif REC_COUNT == 2
> #undef REC_COUNT
> #define REC_COUNT 1
> #elif REC_COUNT == 1
> #undef REC_COUNT
> #define REC_COUNT 0
> #endif
> /* Here is the meat */
> #if REC_COUNT == 2
> /* first iteration */
> #elif REC_COUNT == 1
> /* second iteration */
> #else
> /* third and last iteration */
> #if REC_COUNT != 0
> #include __FILE__
> #endif
>
> --
> Ark


Nope, doesn't work.

Great, I have now figured out it is impossible to recursively
preprocess more than one level. Is this supposed to happen per ANSI
specs, or should I go to the cpp newsgroup?

 
Reply With Quote
 
andreyvul
Guest
Posts: n/a
 
      11-13-2007
And I got it to work now:
cc foo.c -E | sed -re '/#[^di]/D' -e /^$/D' | head -7 | cc -x c - -o
foo
Kind of impossible on windows without GnuWin32, msys, or cygwin.

 
Reply With Quote
 
Ark Khasin
Guest
Posts: n/a
 
      11-13-2007
andreyvul wrote:
> On Nov 12, 7:58 pm, Ark Khasin <(E-Mail Removed)> wrote:
>> andreyvul wrote:
>>> On Nov 12, 7:11 pm, (E-Mail Removed)-cnrc.gc.ca (Walter Roberson)
>>> wrote:
>>>> In article <(E-Mail Removed). com>,
>>>> andreyvul <(E-Mail Removed)> wrote:
>>>>> What I'm trying to do is have the preprocessor parse one file twice.
>>>> You cannot do that using the facilities defined by the C preprocessor.
>>> Oh, I meant _recursively_ preprocess the file twice.
>>> That's why I was asking about proper #include/#ifdef structure, so
>>> that it preprocesses like this:
>>> #block 1
>>> |->#block 2 (via recursive include)
>>> |->#block 3 (via recursive include)
>>> however, it doesn't get to |->#block 3

>> I didn't try it but something along these lines might do it:
>>
>> #ifndef REC_COUNT
>> #define REC_COUNT 2
>> #elif REC_COUNT == 2
>> #undef REC_COUNT
>> #define REC_COUNT 1
>> #elif REC_COUNT == 1
>> #undef REC_COUNT
>> #define REC_COUNT 0
>> #endif
>> /* Here is the meat */
>> #if REC_COUNT == 2
>> /* first iteration */
>> #elif REC_COUNT == 1
>> /* second iteration */
>> #else
>> /* third and last iteration */
>> #if REC_COUNT != 0
>> #include __FILE__
>> #endif
>>
>> --
>> Ark

>
> Nope, doesn't work.
>
> Great, I have now figured out it is impossible to recursively
> preprocess more than one level. Is this supposed to happen per ANSI
> specs, or should I go to the cpp newsgroup?
>

You didn't try hard enough . The text I posted was not #balanced.
Here's a working example:
------------- iter.c -------------
#include <stdio.h>
int main()
{
#include "iter.h"
return 0;
}
------------- iter.h -------------
#ifndef REC_COUNT
# define REC_COUNT 2
/* first iteration */
puts("first iteration");
#elif REC_COUNT == 2
# undef REC_COUNT
# define REC_COUNT 1
/* second iteration */
puts("second iteration");
#elif REC_COUNT == 1
# undef REC_COUNT
# define REC_COUNT 0
/* third and last iteration */
puts("third and last iteration");
#endif
#if REC_COUNT != 0
# include __FILE__
#endif
------------ output --------------------
first iteration
second iteration
third and last iteration

.... which also disproves a claim of a nearby post that it's impossible.
In fact, you can do recursion of any fixed depth this way.
Unless of course I misunderstood what you were trying to achieve.

--
Ark
 
Reply With Quote
 
andreyvul
Guest
Posts: n/a
 
      11-13-2007
On Nov 12, 9:54 pm, Ark Khasin <(E-Mail Removed)> wrote:
> andreyvul wrote:
> > On Nov 12, 7:58 pm, Ark Khasin <(E-Mail Removed)> wrote:
> >> andreyvul wrote:
> >>> On Nov 12, 7:11 pm, (E-Mail Removed)-cnrc.gc.ca (Walter Roberson)
> >>> wrote:
> >>>> In article <(E-Mail Removed). com>,
> >>>> andreyvul <(E-Mail Removed)> wrote:
> >>>>> What I'm trying to do is have the preprocessor parse one file twice.
> >>>> You cannot do that using the facilities defined by the C preprocessor.
> >>> Oh, I meant _recursively_ preprocess the file twice.
> >>> That's why I was asking about proper #include/#ifdef structure, so
> >>> that it preprocesses like this:
> >>> #block 1
> >>> |->#block 2 (via recursive include)
> >>> |->#block 3 (via recursive include)
> >>> however, it doesn't get to |->#block 3
> >> I didn't try it but something along these lines might do it:

>
> >> #ifndef REC_COUNT
> >> #define REC_COUNT 2
> >> #elif REC_COUNT == 2
> >> #undef REC_COUNT
> >> #define REC_COUNT 1
> >> #elif REC_COUNT == 1
> >> #undef REC_COUNT
> >> #define REC_COUNT 0
> >> #endif
> >> /* Here is the meat */
> >> #if REC_COUNT == 2
> >> /* first iteration */
> >> #elif REC_COUNT == 1
> >> /* second iteration */
> >> #else
> >> /* third and last iteration */
> >> #if REC_COUNT != 0
> >> #include __FILE__
> >> #endif

>
> >> --
> >> Ark

>
> > Nope, doesn't work.

>
> > Great, I have now figured out it is impossible to recursively
> > preprocess more than one level. Is this supposed to happen per ANSI
> > specs, or should I go to the cpp newsgroup?

>
> You didn't try hard enough . The text I posted was not #balanced.
> Here's a working example:
> ------------- iter.c -------------
> #include <stdio.h>
> int main()
> {
> #include "iter.h"
> return 0;}
>
> ------------- iter.h -------------
> #ifndef REC_COUNT
> # define REC_COUNT 2
> /* first iteration */
> puts("first iteration");
> #elif REC_COUNT == 2
> # undef REC_COUNT
> # define REC_COUNT 1
> /* second iteration */
> puts("second iteration");
> #elif REC_COUNT == 1
> # undef REC_COUNT
> # define REC_COUNT 0
> /* third and last iteration */
> puts("third and last iteration");
> #endif
> #if REC_COUNT != 0
> # include __FILE__
> #endif
> ------------ output --------------------
> first iteration
> second iteration
> third and last iteration
>
> ... which also disproves a claim of a nearby post that it's impossible.
> In fact, you can do recursion of any fixed depth this way.
> Unless of course I misunderstood what you were trying to achieve.
>
> --
> Ark


What if you had a macro in the third iteration that was to be expanded
by the previous iterations?

 
Reply With Quote
 
andreyvul
Guest
Posts: n/a
 
      11-13-2007
On Nov 12, 9:54 pm, Ark Khasin <(E-Mail Removed)> wrote:
> andreyvul wrote:
> > On Nov 12, 7:58 pm, Ark Khasin <(E-Mail Removed)> wrote:
> >> andreyvul wrote:
> >>> On Nov 12, 7:11 pm, (E-Mail Removed)-cnrc.gc.ca (Walter Roberson)
> >>> wrote:
> >>>> In article <(E-Mail Removed). com>,
> >>>> andreyvul <(E-Mail Removed)> wrote:
> >>>>> What I'm trying to do is have the preprocessor parse one file twice.
> >>>> You cannot do that using the facilities defined by the C preprocessor.
> >>> Oh, I meant _recursively_ preprocess the file twice.
> >>> That's why I was asking about proper #include/#ifdef structure, so
> >>> that it preprocesses like this:
> >>> #block 1
> >>> |->#block 2 (via recursive include)
> >>> |->#block 3 (via recursive include)
> >>> however, it doesn't get to |->#block 3
> >> I didn't try it but something along these lines might do it:

>
> >> #ifndef REC_COUNT
> >> #define REC_COUNT 2
> >> #elif REC_COUNT == 2
> >> #undef REC_COUNT
> >> #define REC_COUNT 1
> >> #elif REC_COUNT == 1
> >> #undef REC_COUNT
> >> #define REC_COUNT 0
> >> #endif
> >> /* Here is the meat */
> >> #if REC_COUNT == 2
> >> /* first iteration */
> >> #elif REC_COUNT == 1
> >> /* second iteration */
> >> #else
> >> /* third and last iteration */
> >> #if REC_COUNT != 0
> >> #include __FILE__
> >> #endif

>
> >> --
> >> Ark

>
> > Nope, doesn't work.

>
> > Great, I have now figured out it is impossible to recursively
> > preprocess more than one level. Is this supposed to happen per ANSI
> > specs, or should I go to the cpp newsgroup?

>
> You didn't try hard enough . The text I posted was not #balanced.
> Here's a working example:
> ------------- iter.c -------------
> #include <stdio.h>
> int main()
> {
> #include "iter.h"
> return 0;}
>
> ------------- iter.h -------------
> #ifndef REC_COUNT
> # define REC_COUNT 2
> /* first iteration */
> puts("first iteration");
> #elif REC_COUNT == 2
> # undef REC_COUNT
> # define REC_COUNT 1
> /* second iteration */
> puts("second iteration");
> #elif REC_COUNT == 1
> # undef REC_COUNT
> # define REC_COUNT 0
> /* third and last iteration */
> puts("third and last iteration");
> #endif
> #if REC_COUNT != 0
> # include __FILE__
> #endif
> ------------ output --------------------
> first iteration
> second iteration
> third and last iteration
>
> ... which also disproves a claim of a nearby post that it's impossible.
> In fact, you can do recursion of any fixed depth this way.
> Unless of course I misunderstood what you were trying to achieve.
>
> --
> Ark


What if you have a macro in the third iteration that needs expanding
in the second iteration, which needs expanding in the first iteration?
*That* was what I was trying to do.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
how to do two-stage preprocessing of one file andreyvul C Programming 1 11-13-2007 12:53 AM
Summary: translation units, preprocessing, compiling and linking? Steven T. Hatton C++ 7 06-03-2004 06:01 PM
Preprocessing directives Ron C++ 3 11-12-2003 04:45 AM
Indentation of preprocessing directives Dave C++ 2 11-03-2003 03:34 AM



Advertisments