I want to preprocess C++ header files keeping all macros verbatim in the output text.
For that, I need a C preprocessor-like program that performs these tasks:
store in memory macros from #define directives;
recursively follow #include directives;
evaluate conditions in #if and #ifdef directives;
suppress the code in inactive portions of #if .. #else .. #endif blocks;
(optionally) remove /* .. */ and // comments;
remove all remaining directives lines.
But the macros must not be replaced in the output. Or alternatively, the preprocessor may take in argument a list of macro names that shall not be replaced.
This may sound weird, but I have a good reason for that. I have a series of Perl scripts able to analyze preprocessed C++ class headers. And I use some macros to tell them for example which methods to export.
I haven't found a preprocessor program able to perform what I need, so I wrote a Perl
script. The latter actually works, but is slow and non standard. I am looking for a better alternative.
Use gcc -E to run the preprocessor manually. This will expand all the macros but that's not a problem.
What you want is special macros for the time when you need the output for your Perl scripts. Try this:
#ifdef PERL_PREPROCESSING
# define EXPORT(...) PERL_EXPORT
#else
# define EXPORT(...) ...normal C code...
#endif
So the idea is that you call gcc -E -DPERL_PREPROCESSING to switch some of the macros to produce output that your perl scripts can locate. The macros will be expanded as usual.
[EDIT] If you don't want to pollute your sources with Perl-specific macros, use this trick: Create a folder which contains the header file with the Perl versions of the macros and include this folder before every other folder with -I. gcc will then ignore the standard header file.
If you are using *nix you can use the grep command to find all the #defines in the directory
grep -R . '#define'
For the preprocessing required, use gcc -E.
Related
I want to ask if I can make a file of macros that basically defined at compile time and use these macros in my c++ code which compiles specific code if the condition is true. SO what is basically the extension for that file is it a .txt file or a .h file. and how to put this file in CmakeList.txt to make it executable at compile time. for example like this in a specific file?
#define melodic 1
#define noetic 2
A C++ macro is a shortcut for writing code, what happens when you compile your project is that this code:
#define SOMETHING 32
int i = SOMETHING
Is changed to before it is compiled:
int i = 32
So a macro just substitutes text wherever you place it. There is also another use of macros that maybe is what you are looking for. You can use the preprocessing directive #ifdef MACRO to compile some code conditionally. For example, let's say that you have a function that is only there for debugging, but you don't want that code to make it to release. You could define it like:
void hello() {
#ifdef DEBUG
print("debug");
#endif
}
Then, if that file has a #define DEBUG before the #ifdef macro, the code will be included. Otherwise, the code will be discarded. Note that to use #ifdef the macro body may be empty or not, it just checks if the defined directive was used.
What you might want to accomplish is to have a series of preprocessor macros that you either set or don't in a separate configuration file to change the code produced. They are a very powerful tool, but they must be use with caution since having too many can make code not very readable.
To accomplish that, you need to include the #define MACRO in the same file that you are checking if it is defined, and before you check it. If you are only using that macro in that file, it would be good to place it at the top of it, but if you use it on multiple files you can create a header file (.h) and use #include "name.h", since include copies the contents of the header file there, therefore adding the macro definitions to your file.
The preprocessor directives are dependent on the compiler, so the version and type of compiler you use (gcc, clang...) will have different support for them. However, defined and ifdef are very widely spread and most if not all compilers have them. I recommend reading more about directives, for example here.
Finally, in case you go the route of the .h file, you would add it like any other header file you have in your project to the CmakeList.txt.
I have a C++ code which needs to include a certain library in some servers and not in other servers. I build my code using bjam.
Code example:
if server in server_list:
include <header-file.h>
int function();
else:
int function();
And during build using bjam:
if server in server_list:
-llibrary
else:
...
Header file inclusion is a compile time activity not run time. So you can't use if conditions for the same
use #ifdefs
#define SERVER_IN_LIST
#ifdef SERVER_IN_LIST
#include<...>
#endif
In C and C++ any line that begins with a # is a pre-processor directive. The pre-processor is a text parser that parses a source code file before it is compiled. It understands particular directives such as #include, #define and #ifdef but it treats normal C++ code as if it were text. For this reason, you can't use normal C++ code to alter the interpretation of the pre-processor directives.
Let's look at an example:
if (x == 4){
#include "x4.h"
}
The above is wrong because the if statement and its braces are part of the C++ code so will be ignored by the pre-processor. The pre-processor will go straight ahead and interpret the #include directive, which will cause the contents of x4.h to be pasted into that position in the file.
The correct way to write this is to use conditional pre-processor directives such as #if or #ifdef. For example...
#ifdef INCLUDE_X4
# include "x4.h"
#endif
Note that the indentation in this code is optional.
More information about pre-processor directives can be found here.
Does there exists a flag that I can pass to one of these preprocessors that causes the preprocessor to not resolve any macros in the code? I"m trying to use it just to concatenate any included header files into one file. Thanks!
From the manual
-fdirectives-only
When preprocessing, handle directives, but do not expand macros.
Read the full entry for complete details.
Add the -P option to suppress #line directives, e.g.
g++ -E -P -fdirectives-only ... file.cpp
or:
cpp -P -fdirectives-only ... file.cpp
AFAIK there is no such flag. If you only want to concatenate header files - go ahead and write a short program for this.
You may anyway need sch program as the preprocessor does more than including headers and extending macros. It is also responsible e.g. for concatenating string literals, so e.g. "This""And""That" is turned into "ThisAndThat". So you will get some unexpected changes in your sources anyway.
I can see
#ifdef <token>
code;
#endif
to be included, but I can't find it defined in any of the headers it includes. Is there any other mechanism with which the token could be defined?
Firstly, there are macros that are implicitly defined by the compiler (for example, __cplusplus). Some of these are standard, and some are compiler-specific extensions. See your compiler manual for the full list.
Additionally, most compilers allow defining macros on the command line. The exact mechanism is compiler-dependent, but often takes the form of a -D or /D command-line option. For example, see the gcc manual:
-D name
Predefine name as a macro, with definition 1.
-D name=definition
The contents of definition are tokenized and processed as if they appeared during translation phase three in a `#define' directive. In particular, the definition will be truncated by embedded newline characters.
If you are invoking the preprocessor from a shell or shell-like program you may need to use the shell's quoting syntax to protect characters such as spaces that have a meaning in the shell syntax.
If you wish to define a function-like macro on the command line, write its argument list with surrounding parentheses before the equals sign (if any). Parentheses are meaningful to most shells, so you will need to quote the option. With sh and csh, -D'name(args...)=definition' works.
For Microsoft Visual C++, see http://msdn.microsoft.com/en-us/library/hhzbb5c8(v=vs.80).aspx
Some compilers provide convenient tools for figuring out where a particular preprocessor macro is defined. See, for example, How to know (in GCC) when given macro/preprocessor symbol gets declared?
Most (all?) compilers allow defining values with flags (-D in gcc), also some may be set by the compiler itself.
Yes, of course, preprocessor directives can be set with the compiler. For example, gcc lets you add directives in the command line, you can specify directives in the project settings in Visual Studio. Also think about __cplusplus, or _LINE_ of _FILE_. Those aren't defined anywhere, yet they exist. Also _DEBUG or UNICODE which are set up by the MSVS environment.
I have a C++ program that processes an input file. I want to add pre-processing ability to my program. That is say the input file looks like :
%pre-processing section
#include <some_parent_file>
#define x y
#ifdef 0
some useless text
#endif
%actual file-contents
... lots of text ...
Then my program should automatically include the text from parent file, do the #define stuff and other pre-processing. I could use a script (with g++ -E) before calling my program but I would like to be able to do this within my program as that allows more flexibility.
Also "g++ -E" will assume a pre-processor directive when lines in the "actual file-contents" section start with a hash (g++ -E doesn't know that I want to separate my code into 2 sections!).
Moreover, if I can use just the ifdef functionality within "actual file contents" section, that would be amazing.
Can I embed C++ code within my program to use only the features I want from pre-processing capability of gcc compiler ?
How about a library like Wave or cpplib?
A simple possibility would be to use popen to read from a command pipe, which could be cpp (or gcc -C -E) or m4.
A related possibility is to embed a scripting interpreter in your program, e.g. lua. A related solution is to make your application embedded in an interpreter like Python or Ocaml.
At last, you could use ordinary lexing and parsing techniques, perhaps with ANTLR and process yourself your include directives. You can also use library for configuration files, like libconfig
If you want to turn on/off features at compile time, it is best to stick to standard preprocessor macros or use templates. You can also look at how Qt parses the standard C++ code to generate additional code. At runtime, you can achieve this with scripting or maybe a plug-in system.