This isn't really clearly documented, but a shallow search reveals that RIM's RAPC compiler does support preprocessor statements (with some project file modification).
We've been using the simple #ifdef, #else, and #endif directives for quite some time now, as supporting platforms 4.1 through 4.7 with one code base is nearly impossible without them, but I began wondering recently if there are other supported directives which aren't quite as well documented; something akin to C's #elif for example, or even rudimentary equivalency directives?
Here's a complete listing of commands for the RAPC preprocessor. The preprocessor's not very robust, but that's on purpose.
//#preprocess - Used to specify that the file should be preprocessed. It must be the first line of the file.
//#implicit tag - This needs to be on the second line of the file. If tag is part of the command line, then the whole file should be compiled. If not, then it should be excluded.
Then there's the //#ifdef tag ... #else ... #endif and the //#ifndef tag ... #else ... #endif directives that you mentioned.
Also note, there is no nesting of preprocessed blocks and no macros.
RIM Help Center Doc:
http://docs.blackberry.com/en/developers/deliverables/21065/Specifying_preprocessor_directives_657636_11.jsp
Related
I'd like for the clang-format to check that each of my headers have the proper include guard.
For example, for the file dopelib/dopestuff/whatitisyo.h, I'd like the code to be formatted like this:
#ifndef DOPELIB_DOPESTUFF_WHATITISYO_H
#define DOPELIB_DOPESTUFF_WHATITISYO_H
/** Code here. **/
#endif // DOPELIB_DOPESTUFF_WHATITISYO_H
Can clnag-format check this structure and make sure that the include guard is there and that it is named appropriately with the file name in the #ifndef (sort of what cpplint does)?
As far as I know, clang-format doesn't currently support this.
However, you can do exactly this with clang-tidy (documented here). Invoke it like this:
clang-tidy -checks='-*,llvm-header-guard' -fix-errors myIncludeFile.h
Explanation:
The -* tells clang-tidy to disable all checks
The llvm-header-guard tells clang-tidy to enable the check which deals with include guards (documented here)
The -fix-errors tells clang-tidy to fix any resulting issues, even if it runs into other errors parsing the file
The llvm-header-guard expected format of the include-guards is exactly what you requested above; for example the file mydir/myfile.h would use MYDIR_MYFILE_H. I don't see any documentation which actually specifies that this is the format it uses, but I've verified at least version 6.0.0 does use that format.
Also see: clang include fixer, which does something similar.
The accepted solution may not work if
The project has a different file structure
Uses some extensions that clang does not understand
I have a script here: https://github.com/milasudril/texpainter/blob/master/devtools/include_guard_fix.py
I need to add headers to an already existing program by transforming it with LLVM and Clang.
I have used clang's rewriter to accomplish a similar thing in the changing function names and arguments, etc.
But the header files aren't present in clang's AST. I already know we need to use PPCallbacks (https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html) but I am in dire need of some examples on how to make it work with the rewriter if at all possible.
Alternatively, adding a #include statement just before the first
using namespace <namespace>;
Also works. I would like to know an example of this as well.
Any help would be appreciated.
There is a bit of confusion in your question. You need to understand in details how the preprocessor works. Be aware that most of C++ compilation happens after the preprocessing phase (so most C++ static analyzers work after that phase).
In other words, the C++ specification (and also the C specification) defines first what is preprocessing, and then what is the syntax and the semantics of the preprocessed form.
In other words, when compiling foo.cc your compiler see the preprocessed form foo.ii that you could obtain with clang++ -C -E foo.cc > foo.ii
In the 1980s the preprocessor /lib/cpp was a separate program forked by the compiler (and some temporary foo.ii was sitting on the disk and removed at end of compilation). Today, it is -for performance reasons- some initial processing done inside the compiler. But you could reason as if it was still separate.
Either you want to alter the Clang compiler, and it deals (like every other C++ compiler or C++ static analyzer) mostly with the preprocessed form. Then you don't want to add new #include-s, but you want to alter the flow of AST given to the compiler (after preprocessing), and that is a different question: you then want to add some AST between existing AST elements (independently of any preprocessor directives).
Or you want to automatically change the C++ source code. The hard part is determining what you want to change and at what place. I suppose that you have used complex stuff to determine that a #include <vector> has to be inserted after line 34 of file foo.cc. Once you've got that information (and getting it is the hard thing), doing the insertion is pretty trivial. For example, you could read every C++ source line, and insert your line when you have read enough lines.
I'm developing a C/C++ library that uses ImageMagick (using/supporting both libMagickCore and libMagick++), for reading and writing image data (not for processing).
Now, I would also like to support IM's GraphicsMagick fork (e.g. using Debian's graphicsmagick-libmagick-dev-compat package).
Unfortunately, the APIs have diverged enough, so that I cannot use one as a drop-in replacement of the other. Since they are still quite similar, I plan to use a number of #ifdefs for the API specific parts.
Now my problem is, that it seems quite complicated to detect which API is actually used via pre-processor directives, right after including the generic header (which is called the same for both variants).
Basically, I'm looking for something like a #define (provided by the IM/GM headers) that can be used to tell the two APIs apart. Something like:
#include <Magick++.h>
#ifdef GRAPHICSMAGIC_DEFINE
// GM-specific code
#else
// IM-specific code
#endif
or, for the C-API:
#include <magick/MagickCore.h>
#ifdef GRAPHICSMAGIC_DEFINE2
/* GM-specific code */
#else
/* IM-specific code */
#endif
Ideas?
Autoconf, or CMake.
Really - there's no simpler way around it, but you need to package your solution with something that will ask the system what library is present, and will then generate config.h with the correct pre-processor definitions.
The difference between GraphicsMagick & ImageMagick seem simple enough to do something clever, BUT now that we're a year into the release of IM 7, we now need to check which version & adjust definitions as needed. For example
// IM 6
#include <magick/MagickCore.h>
// IM 7
#include <MagickCore/MagickCore.h>
I would suggest reviewing existing m4 scripts used by other projects available online.
So back to the original question, the generic include headers my look something like this... (and I quote from Imagick library, but can be expanded to cover GM)
#if defined (IM_MAGICKWAND_HEADER_STYLE_SEVEN)
# include <MagickWand/MagickWand.h>
#elif defined (IM_MAGICKWAND_HEADER_STYLE_OLD)
# include <wand/magick-wand.h>
#else
# include <wand/MagickWand.h>
#endif
In my project there's a file enclosed in an ifdef preprocessor directive
#ifdef SOME_SYMBOL
... entire file ...
#endif
SOME_SYMBOL is defined by another file that's compiled before this one, and the code works as expected, but the static analyzer isn't aware of this symbol and so it treats SOME_SYMBOL is undefined. The entire file has no syntax highlighting and some of the analysis is just skipped (e.g. syntax error highlighting).
Is there a way to tell the analyzer to treat this symbol as defined without defining it in CMakeLists.txt?
I don't have the option of defining SOME_SYMBOL in CMakeLists.txt since the project depends on it being undefined in some compilation paths (changing this would be near impossible).
Update:
Seems like this is currently an open issue with JetBrains. See Issue CPP-2286
Clion now has a macro which you can use to detect the IDE:
https://youtrack.jetbrains.com/issue/CPP-1296#comment=27-1846360
#ifdef __JETBRAINS_IDE__
// Stuff that only clion will see goes here
#endif
This allows you to put in defines to make clion render your code properly in cases where it can't be clever enough to figure it out.
The __JETBRAINS_IDE__ macro's value is a version string for the IDE. Specific versions of the macro exist for different Jetbrains IDEs: __CLION_IDE__, __STUDIO_IDE__ (for Android Studio), and __APPCODE_IDE__ (for AppCode).
Yay!
To get syntax highlighting:
Go to Settings ⇒ Editor ⇒ Colors&Fonts ⇒ C/C++ and remove all ticks for 'Conditionally non-compiled code'. This way all code will show up with the usual highlighting.
The task has no solution for common case.
But! You can find the target and related resolve context, where SOME_SYMBOL is defined.
...in the status bar you can find the Resolve Context chooser for switching between the Debug, Release, RelWithDebInfo and MinSizeRel contexts to resolve your code in the IDE with the desired definitions.
FSI version: 11.0.50727.1
So I was working on an F# shell script and I ran across something that sort of surprised me.
When I did this:
#if INTERACTIVE
#r "System.Data.dll"
#r "FSharp.Data.TypeProviders.dll"
#r "System.Data.Linq.dll"
#endif
open System
I got an FS0010 error when I pasted the block into the FSI. But if I did not indent the #r lines, no FS0010 error. I'm just sort of surprised that preprocessor lines would be indentation sensitive. Is this a compiler issue or is there something else at work here?
I think the specification and documentation are quite unclear on this topic, but the specification makes a notable distinction between lexical preprocessor directives and compiler directives (see §12.4):
Compiler directives are declarations in non-nested modules or namespace declaration groups in the following form:
# id string ... string
The lexical preprocessor directives #if, #else, #endif and #indent "off" are similar to compiler directives. For details on #if, #else, #endif, see §3.3. The #indent "off" directive is described in §18.4.
My interpretation is that lexical preprocessor directives are actually hanled by some pre-processor before running the main compilation and so the indentation does not matter for these.
On the other hand, directives like #r, #load, #time etc. are processed later by the compiler and so they need to match the usual F# indentation guidelines.
As #unwind says, the documentation states "Indentation is not significant for preprocessor directives", but I think this applies only to the preprocessor directives listed on that documentation page (which are lexical preprocessor directives and not compiler directives).
According to the documentation, it must be something else at work:
Indentation is not significant for preprocessor directives.