Using C macros in Swift - swift

Have my own macro defined in myProject.pch file,
For example:
#define Enable_Analytics
And i want to enclose few statements of code at multiple places inside
#ifdef Enable_Analytics
// Code statements which has to executed only if Enable_Analytics is defined
#endif
This is useful to include/remove code based on the macro.
In Objective-C this works but in swift i get error. How to use #ifdef in swift?

You can call the C preprocessor on just about and kind of file even if it is not C or a C like language.
It is usually available as cpp on most Unix like systems. Just run cpp your-file.swift and the C preprocessor should preprocess the file just as it would C.
However I do not know of a way to make the preprocessor use defines within a project file. So you probably will have to manually specify them on the command line like -DMACRO_NAME=somevalue.
Alternatively you could #include a file containing the defines within each of your swift files and the preprocessor will insert them.

Related

Concatenating an expanded macro and a word using the Fortran preprocessor

I'm trying to concatenate a word in the source code with the expansion of a preprocessor macro. Basically I have foo somewhere in the code, and with a #define EXPANSION bar I want to obtain foobar. However, I'm struggling to find a way to do this, which works with all compilers. For the moment I would be happy if it works with gfortran and ifort.
According to its documentation, the gfortran preprocessor is a C preprocessor running in "traditional mode", which does not have the ## token paste operator. However, the same effect can be obtained with an empty C-style /**/ comment. The ifort preprocessor seems to behave more like the normal C preprocessor, so normal token pasting does the trick in ifort. Unfortunately the empty /**/ comment does not work in ifort, as the comment is replaced by a single space instead.
Here is a little example:
#define EXPANSION bar
#define CAT(x,y) PASTE(x,y)
#define PASTE(x,y) x ## y
foo/**/EXPANSION
CAT(foo,EXPANSION)
For which gfortran produces:
foobar
foo ## bar
While ifort gives me:
foo bar
foobar
Of course I could choose the right way by checking the predefined macros for both compilers:
#ifdef __GFORTRAN__
foo/**/EXPANSION
#else
CAT(foo,EXPANSION)
#endif
This works for both of them, but it's rather ugly to have the preprocessor conditional for every expansion. I would much rather avoid this and have some macro magic only once in the beginning.
I have seen this answer to another question, which would probably allow me to work around this issue, but I would rather find a solution that does not invoke the preprocessor separately.
I'm not too familiar with the C preprocessor. Maybe there is a simple way to do what I want. Any ideas?
EDIT: I've already tried something like this:
#define EXPANSION bar
#define CAT(x,y) PASTE(x,y)
#ifdef __GFORTRAN__
#define PASTE(x,y) x/**/y
#else
#define PASTE(x,y) x ## y
#endif
CAT(foo,EXPANSION)
Unfortunately this does not work in gfortran where it produces fooEXPANSION. I'm not entirely sure how this works, but apparently the expansion of the CAT macro prevents the expansion of EXPANSION in the same line. I suspect that this is a feature of the "traditional" C preprocessor ...
I have done some research and it seems that basically most Fortran compilers (i.e. Intel and PGI) use a relatively normal C-preprocessor with a token pasting operator. We only need a special treatment for gfortran, which uses a C preprocessor in traditional mode without a token pasting operator.
Thanks to an entry on c-faq.com I found this definition of a CAT macro that works with all compilers I tested so far:
#ifdef __GFORTRAN__
#define PASTE(a) a
#define CAT(a,b) PASTE(a)b
#else
#define PASTE(a) a ## b
#define CAT(a,b) PASTE(a,b)
#endif
Another solution (that still uses the /**/ trick) was posted by Jonathan Leffler in this answer to a related question.

How to store a macro in another macro?

I have a macro DDLogDebug(...) and I would like to do the following
#define _DDLogDebug(arg...) DDLogDebug(args)
#undef DDLogDebug
#define DDLogDebug(args...) doSomething(); _DDLogDebug(arg...)
But it does not work. Instead of #define _DDLogDebug(arg...) DDLogDebug(args), I would need a command that "stores" the content of the macro DDLogDebug to _DDLogDebug.
Does something like that exist?
How should one do when one wants to modify a macro whose definition is not exposed?
You can't do something like this with the purely standard preprocessor.
The reason is that macro definition doesn't work like e.g. function definition in the main language: at the time when you define _DDLogDebug, it isn't actually linking to the definition of DDLogDebug - it's storing exactly what you wrote. It won't attempt to actually find an expansion for any names until the macro is being used in the program outside of any definitions. By that point, the definition for DDLogDebug is already gone.
This is actually a valuable and intended behaviour, because it allows the use of techniques like X-macros: one definition can provide a framework and let different calling contexts decide how to actually use it in different ways. Not only is the outer macro not dependent on definitions available at the time it was written, but meaning of its contents can change throughout the program without having to change its structure.
If you can't work around this problem, you might have some luck with the non-standard but widely-supported push_macro and pop_macro directives.
Example of the use of push and pop:
#define FOO 123
#pragma push_macro("FOO")
#undef FOO
FOO
#pragma pop_macro("FOO")
FOO
Run this through gcc -E and you'll see it emits FOO (newline) 123. Works with Clang.

How can I reference #defines in a C file from python?

I have a C file that has a bunch of #defines for bits that I'd like to reference from python. There's enough of them that I'd rather not copy them into my python code, instead is there an accepted method to reference them directly from python?
Note: I know I can just open the header file and parse it, that would be simple, but if there's a more pythonic way, I'd like to use it.
Edit:
These are very simple #defines that define the meanings of bits in a mask, for example:
#define FOO_A 0x3
#define FOO_B 0x5
Running under the assumption that the C .h file contains only #defines (and therefore has nothing external to link against), then the following would work with swig 2.0 (http://www.swig.org/) and python 2.7 (tested). Suppose the file containing just defines is named just_defines.h as above:
#define FOO_A 0x3
#define FOO_B 0x5
Then:
swig -python -module just just_defines.h ## generates just_defines.py and just_defines_wrap.c
gcc -c -fpic just_defines_wrap.c -I/usr/include/python2.7 -I. ## creates just_defines_wrap.o
gcc -shared just_defines_wrap.o -o _just.so ## create _just.so, goes with just_defines.py
Usage:
$ python
Python 2.7.3 (default, Aug 1 2012, 05:16:07)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import just
>>> dir(just)
['FOO_A', 'FOO_B', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_just', '_newclass', '_object', '_swig_getattr', '_swig_property', '_swig_repr', '_swig_setattr', '_swig_setattr_nondynamic']
>>> just.FOO_A
3
>>> just.FOO_B
5
>>>
If the .h file also contains entry points, then you need to link against some library (or more) to resolve those entry points. That makes the solution a little more complicated since you may have to hunt down the correct libs. But for a "just defines case" you don't have to worry about this.
You might have some luck with the h2py.py script found in the Tools/scripts directory of the Python source tarball. While it can't handle complex preprocessor macros, it might be sufficient for your needs.
Here is a description of the functionality from the top of the script:
Read #define's and translate to Python code.
Handle #include statements.
Handle #define macros with one argument.
Anything that isn't recognized or doesn't translate into valid
Python is ignored.
Without filename arguments, acts as a filter.
If one or more filenames are given, output is written to corresponding
filenames in the local directory, translated to all uppercase, with
the extension replaced by ".py".
By passing one or more options of the form "-i regular_expression"
you can specify additional strings to be ignored. This is useful
e.g. to ignore casts to u_long: simply specify "-i '(u_long)'".
#defines are macros, that have no meaning whatsoever outside of your C compiler's preprocessor. As such, they are the bane of multi-language programmers everywhere. (For example, see this Ada question: Setting the license for modules in the linux kernel from two weeks ago).
Short of running your source code through the C-preprocessor, there really is no good way to deal with them. I typically just figure out what they evalutate to (in complex cases, often there's no better way to do this than to actually compile and run the damn code!), and hard-code that value into my program.
The (well one of the) annoying parts is that the C preprocessor is considered by C coders to be a very simple little thing that they often use without even giving a second thought to. As a result, they tend to be shocked that it causes big problems for interoperability, while we can deal with most other problems C throws at us fairly easily.
In the simple case shown above, by far the easiest way to handle it would be to encode the same two values in constants in your python program somewhere. If keeping up with changes is a big deal, it probably wouldn't be too much trouble to write a Python program to parse those values out of the file. However, you'd have to realise that your C code would only re-evaluate those values on a compile, while your python program would do it whenever it runs (and thus should probably only be run when the C code is also compiled).
If you're writing an extension module, use http://docs.python.org/3/c-api/module.html#PyModule_AddIntMacro
I had almost exactly this same problem so wrote a Python script to parse the C file. It's intended to be renamed to match your c file (but with .py instead of .h) and imported as a Python module.
Code: https://gist.github.com/camlee/3bf869a5bf39ac5954fdaabbe6a3f437
Example:
configuration.h
#define VERBOSE 3
#define DEBUG 1
#ifdef DEBUG
#define DEBUG_FILE "debug.log"
#else
#define NOT_DEBUGGING 1
#endif
Using from Python:
>>> import configuration
>>> print("The verbosity level is %s" % configuration.VERBOSE)
The verbosity level is 3
>>> configuration.DEBUG_FILE
'"debug.log"'
>>> configuration.NOT_DEBUGGING is None
True

Is there a way to replace an already defined preprocessor identifier?

I have a library that has several options defined as this:
#define shouldShowToolbar YES
#define shouldAlignToLeft YES
etc..
and I'm looking for a way to actually replace those from outside (without modifying the library, because the future updates will break it). Is it possible, or am I doomed to change the library source code (which I do have) every time an update comes out.
There is #undef
#include "library_header.h" /* Which defines the macro. */
#undef shouldShowToolbar /* You undef it. */
#define shouldShowToolbar NO /* If you want, you can redefine it. */
http://gcc.gnu.org/onlinedocs/cpp/Undefining-and-Redefining-Macros.html
If you don't want a particular macro to take effect for a section of code and you know that macro name too, you can use
#undef shouldShowToolbar
/* Your code */
#define shouldShowToolbar
This wont totally undef the macro, cos you never know which part of your code might actually want it
These are values that are hardcoded at compile time. If you compile the library with your project then you should be able to redefine them in a file that compiles later in the compile list, I think there is a special keyword for it. Otherwise it is like saying I want to replace YES in the library.
As far as i know, preprocessor directives executes before compilation. So after that, there's no chance to change something.

Does doxygen predefine any macros?

Apart from the PREDEFINED configuration option, where I could always put DOXYGEN=1, does doxygen predefine any preprocessor macros prior to reading C++ files?
My train of thought is that GCC predefines macros such as __GNUC__, and MSC predefines macros such as _MSC_VER. Does doxygen predefine macros at all, such as _DOXYGEN_VER?
I don't want to use the PREDEFINED configuration option at all.
No, Doxygen does not predefine any self-identifying tokens.
If you don't want to litter your code with preprocessor #ifdef _DOXYGEN_VER / #endif blocks you can use the \cond command. The \cond command is an easier way to define sections that may be conditionally included/excluded similar to what you used to have to do with the C preprocessor tokens.