7

I'm trying to compile a huge, world-renowned numerical weather prediction code - written mostly in Fortran 90 - that uses cpp extensively, and successfully, with PGI, Intel and gfortran. Now, I've inherited a version where experts have added several hundred cases of variadic macros. They use Intel and fpp, which is presumably a little more Fortran-centric, and can get it all to work. I need to use gfortran, and have not been able to get cpp to work on this code with its new additions.

A gross simplification of the problem is as follows -

Code to preprocess:

    PRINT *, "Hello" // "Don"
#define adderv(...) (myadd(__VA_ARGS__))
    sumv = adderv(1, 2, 3, 4, 5)

Using cpp without the -traditional option will handle the variadic macro, but not the Fortran concatenation:

$ cpp -P t.F90
    PRINT *, "Hello"
    sumv = (myadd(1, 2, 3, 4, 5))

On the other hand, using the -traditional flag handles the concatenation, but not the variadic macro:

$ cpp -P -traditional t.F90 
t.F90:2:0: error: syntax error in macro parameter list
 #define adderv(...) (myadd(__VA_ARGS__))
 ^
    PRINT *, "Hello" // "Don"
    sumv = adderv(1, 2, 3, 4, 5)

I'm really struggling to find a way to facilitate the processing of both.

I've started by playing with gpp, and feel like I'm getting close, but the reality is I might still be a long way from a solution. It doesn't accept the ... and, it doesn't expand __VA_ARGS__. Of course, the following isn't really a variadic macro any more...

    PRINT *, "Hello" // "Don"
#define adderv() (myadd(__VA_ARGS__))
    sumv = adderv(1, 2, 3, 4, 5)



$ gpp t.F90
    PRINT *, "Hello" // "Don"
    sumv = (myadd(__VA_ARGS__))

I've scoured the web to no avail, and the best possibility I've seen so far, which strikes me as possibly ugly and painful, is to split all my Fortran concatenation operators into separate lines. i.e.

PRINT *, "Hello" // "Don"

becomes

PRINT *, "Hello" /&
&              / "Don"

The innards of cpp and gpp are a bit intimidating to me, but if anybody sees the potential for success and might point me in the right direction, I'd be very appreciative. Restructuring this huge code really isn't an option, though an automated strategy (such as splitting those concat operators into separate lines) might be, if I'm desperate enough.


Additional information - roygvib suggested I try adding the -C flag. We had been suppressing it lately because it seemed to introduce many C comments into the Fortran code. Well, I went ahead and tried this, and I think I'm closer:

$ cat t.f90
        PRINT *, "Hello" // "Don"
    #define adderv(...) (myadd(__VA_ARGS__))
        sumv = adderv(1, 2, 3, 4, 5)

When I invoke with -P and -C flags, naturally it passes through the C++ (Fortran concat operator), but it also seems to generate some C-commented copyright text:

   $ /lib/cpp -P -C  t.F90
   /* Copyright (C) 1991-2014 Free Software Foundation, Inc.
      This file is part of the GNU C Library.
   .
   .
   .
   /* wchar_t uses ISO/IEC 10646 (2nd ed., published 2011-03-15) /       Unicode 6.0.  */
   /* We do not support C11 <threads.h>.  */
       PRINT *, "Hello" // "Don"
       sumv = (myadd(1, 2, 3, 4, 5))

A little bit of research ( Remove the comments generated by cpp ) is suggesting that this addition of the copyright may be a relatively new "feature" of cpp.

I can't see any simple way to suppress this, so I'm thinking I may need to build a wrapper script (e.g. mycpp) that calls cpp as above, filters out any C-style comments, then passes that to the next stage.

It's not optimal, and I'm a little leery because this whole package also has C code in it. Theoretically, though, I think that the worst thing that would happen would be failure to generate comments in preprocessed C code.

If anybody has knowledge as to how I might simply suppress the generation of that copyright message, I might be in business.

Community
  • 1
  • 1
DonMorton
  • 393
  • 2
  • 11
  • 1
    Attaching -C option (cpp -P -C) might help...? – roygvib Dec 26 '16 at 22:36
  • It does indeed generate the desired code, but the problem is that it also generates a bunch of C-style comments as a header. Perhaps I can find a way to suppress that part of it? – DonMorton Dec 26 '16 at 23:46
  • One way to suppress the undesired generated comments would be to modify the source of `cpp` and build your own version that does what you want. – John Zwinck Dec 27 '16 at 01:47
  • That has crossed my mind, John Zwinck. I don't know (yet) if cpp can be isolated for simple changes, or if I have to tie it in to the full gcc environment, which I'm a little reluctant to dive into. – DonMorton Dec 27 '16 at 02:49
  • CPP without `-traditional` is not compatible with Fortran. Forget variadic macros and other advanced features and study those many Q/A already available here http://stackoverflow.com/questions/tagged/fortran+c-preprocessor – Vladimir F Героям слава Dec 27 '16 at 09:11
  • Sure, understood, but that's not a realistic option for this case. The code has been deployed for over a decade in a number of international settings for research and operational weather forecasting. The reality is that "I" need to adapt to their ways as best I can. – DonMorton Dec 27 '16 at 16:26
  • Out of curiosity, could you tell us the version of your cpp (4.8.1 ?) and the platform (Ubuntu) ? I have tried cpp and cpp-6 (for gcc-6.2, via homebrew) on osx10.9 and /usr/bin/cpp, /lib/cpp (both v4.4) on Scientific Linux and cpp (v4.8.5) from the Anaconda-3 package (on that Linux), but cannot get the copyright message... – roygvib Dec 27 '16 at 20:12
  • Two different systems - cpp 4.8.4 on Ubuntu 14.04, and cpp 5.4.0 on Ubuntu 16.04. – DonMorton Dec 27 '16 at 20:57
  • If you do have a solution, it is recommended to post it as an answer. Please do no put it instead of your question. The question should really include the acual question as the main content. – Vladimir F Героям слава Dec 28 '16 at 10:36
  • BTW, if the WRF community (better to name it directly next time, many people know it here) consider having to use obsolete versions of CPP as acceptable than I have no comment... – Vladimir F Героям слава Dec 28 '16 at 10:39
  • @VladimirF - thank you for guidance - I've moved my answer to where it belongs. – DonMorton Jan 06 '17 at 00:50

2 Answers2

2

At least in the context of the simple example described below, I resolved the problem by installing an older cpp. Other research had confirmed that version 4.8 was inserting additional C comments into preprocessed Fortran code, which obviously isn't a good thing. The solution was simple, use cpp-4.7.

Installation (on Ubuntu 16.04) was more straightforward than I had anticipated. A simple

sudo apt-get install cpp-4.7
put the necessary executable in /usr/bin/cpp-4.7

and that preprocesses the following examples the way I want.

$ /usr/bin/cpp-4.7 -C -P t.F90
    PRINT *, "Hello" // "Don"
    sum = (myadd(1, 2, 3, 4, 5))  
DonMorton
  • 393
  • 2
  • 11
0

Like DonMorton, I am trying to use cpp -P with fortran files because __VA_ARGS__ and others things are used. As without -C option // are removed and comments are added.

So, I removed these extralines using the ideas of another answer :

cpp -P -C t.F90 |  sed '/\/\*.*\*\// d; /\/\*/,/\*\// d'

And, I get, as expected :

PRINT *, "Hello" // "Don"
sumv = (myadd(1, 2, 3, 4, 5))

But, there is still a problem. You could not use // (C++ style comments) in macro args : // something is replaced by /* something */

Stef1611
  • 1,978
  • 2
  • 11
  • 30