A streamlined preprocessor written in Fortran

It allows for templating via variable expansion using a POSIX-shell syntax which many are familiar with, and allows for plain text blocks to be written to a file, allowing markdown, HTML, and Latex to be easily incorporated straight in the code file. Uniquely to my knowledge the plain text blocks can be filtered into a CHARACTER array definition or comments, including a basic flag (just preliminary) that allows the same text block to be formatted for use with Ford or Doxygen as well as as-is comments. I use preprocessing for documentation more than for conditional compilation, which is the focus of preprocessors like cpp and fpp. It intentionally does not use a pound prefix by default so that files (especially C) that already contain cpp(1) directives can be mixed in without collisions.

It also allows environment variables to be imported, and by default $IFNDEF|$IFDEF will test for environment variables as well as variables declared with $DEFINE. This allows for easier communication with the programming environment than fpp(1) or cpp(1) which require that kind of information to be passed in on the command line.

I would like to see fpm(1) hide the preprocessing stage more like C/cpp(1) does, where you would maintain the input files in the user space but the post-processed files would be placed in a directory in build/ much like the *.o files are now, avoiding the collision issues and file clutter most Fortran preprocessors require where you have the input files and output files both visible in user-space; and preprocessing is particularly problematic with fpm if the preprocessor is not easily bundled with fpm and useable in an environment not easily modified with external dependencies by the user. prep(1) is designed with that in mind, but I think the issues of preprocessing and fpm(1) are not near being resolved in the manner I am hoping for.

Some of the cons are it is not reversible, as is Dan Nagle’s superset of coco(1); it does not directly allow the use of popen (or any non-Fortran-standard feature) like ufpp(1); which basically allows for directly using any other shell language to generate code (a very powerful feature, but fraught with dependency issues if not used judiciously) and does not have direct macro parameters, which I am not particularly fond of. f90ppr and ufpp allow for more general logical expressions, supporting expressions and reals. I could switch in M_calculator in less than a few hours but I think there are drawbacks to making a preprocessor too language-like. I allow reuse of blocks but not true looping or a “for” statement. The preprocessor is intentionally kept to what I think is the basic core functionality , but that is limiting in some respects. Fortran pre-processing has been an issue for decades and even though there are a number of pre-processors none has seemed to win out. As Fortran has expanded in capability and standarization has become more common some of the conditional compilation issues have reduced in recent years but are not gone; and the lack of templating and documenation features is not likely to be standardized soon so I am trying to consolidate a solution for those issues into preprocessing in a sustainable but hopefully useful manner.

On the con side cpp(1) and fpp(1) are often tightly coupled with the compiler, allowing for far more pre-defined variables. Allowing for importing of environment variables addresses this to a small extent.

I am not inserting "# NNN “filename” lines for the debugger, but line counts and input files are tracked so that would be trivial to add.

I am not warning about line length nor doing automatic continuation lines. Again, easy to add but there should at least be a warning, as the changes to Fortran to eliminate the 132 column default line length limit will not be available on all compilers for a while although a lot of compilers already allow that.

2 Likes