NO_XSLOCKS allows the usage of some error checking macros in XS code when combined with #include XSUB.h. However, its use seems to go beyond that. It was recently suggested that I add it to my XS file for better compatibility with ActiveState perl, with this issue given as an example.
What else does #define NO_XSLOCKS do, and when should I use it in my XS code?
Related
I have a messaging function that takes a variable amount of arguments because it supports string formatting in the same way printf does. My plan was to then define message code and messages with a single #define and be able to call this function by passing it a single argument for something that is tightly related.
Here is the message macro:
#define MSG(a, b, ...) message(__FILE__, __LINE__, a, b, __VA_ARGS__);
And here is an example of the message code and string define:
#define MSG_INIT 0000,"%s INITIALIZED SUCCESSFULLY"
The issue is occurring when I try to make a call in the form of:
MSG(MSG_INIT);
My IDE is giving me an error along the lines of:
'Expands to message("file.c", 1, 0000, "INITIALIZED SUCCESSFULLY",);
where the last ',' is causing the issue.
I was expecting to see:
'Expands to message("file.c", 1, 0000, "INITIALIZED SUCCESSFULLY");
If I change the call to:
MSG(MSG_INIT,NULL);
All is good but I'd rather not pass the NULL because the point of the MSG_INIT define in the first place was to pass less parameters. There are messages that make use of the __VA_ARGS__ (Example: #define MSG_CONNECT 0001,"CONNECTION TO [%s] ESTABLISHED" with matching call MSG(MSG_CONEST, server_ip);) so getting rid of that is not an option. I am just looking for the best way to fix this problem and I'm aware a lot of people suggest staying away from the preprocessor but this was the best solution I thought of.
I'm aware a lot of people suggest staying away from the preprocessor ...
I wonder why that is. Could it possibly be for the same reason you had to ask this question? :-)
Honestly, the pre-processor should be limited pretty much to including header files and doing conditional compilation. Anything else that it used to be used for, such as:
#define RC_OK 0
#define RC_NOMEM 1
#define HALF_OF(x) x / 2
is far better done with enumerations or functions.
The days of function-like macros should be put behind us, especially since modern compilers can quite easily out-optimise most hand-crafted code, and without subtle errors creeping in such as with that HALF_OF macro above (do not use it, I specifically made it buggy to illustrate a point).
It's really just a text substitution thing, one which understands the lexical elements, but not the full grammar of C. The fact that you have to perform what I call "macro gymnastics" to get it to do anything other than simple stuff is reason enough to steer clear. Use functions for this, it'll make your life a lot easier.
And apologies for not solving your specific issue, I just think any solution using the pre-processor is going to be half-baked at best. But there's plenty of precedent on SO for answering the question "How do I X?" with "Don't X, it's better to Y." Think of writing an accounting package in assembler, an operating system in object-oriented COBOL, or anything in Pascal :-)
But, if you really wanted to stick to macros against my advice, you could try starting with something like:
#include <stdio.h>
#define MSG(fmtStr, ...) printf("%s:%d> " fmtStr, __FILE__, __LINE__, __VA_ARGS__)
#define MSG_INIT "Initialised %s\n"
#define MSG_TERM "Terminated %s with values %d and %d\n"
int main(void) {
MSG("%f\n", 42.3);
MSG(MSG_INIT, "something");
MSG(MSG_TERM, "something else", 7, 42);
}
I think that's portable, and it allow you to put the heavy lifting into MSG and using a separate format string and parameters for the rest of the stuff:
testprog.c:8> 42.300000
testprog.c:9> Initialised something
testprog.c:10> Terminated something else with values 7 and 42
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.
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
I'd like to be able to ensure I don't accidentally statically link any proprietary modules into the kernel. I was thinking of making MODULE_LICENSE("Proprietary") fail at compile time if MODULE was not defined. (or even better, fail if MODULE_LICENSE("GPL") was not defined...).
But I can't find a good way to compare strings within a macro -- anyone have any good solutions to this?
I don't think you can do this.
The way it's usually done is by defining preprocessor symbols, and comparing their (integer) values:
#define LICENSE_PROPRIETARY 1
#define LICENSE_GPL 2
#define LICENSE_MIT 3
#define MODULE_LICENSE LICENSE_GPL
#if MODULE_LICENSE != LICENSE_GPL
#error "Not GPL, fail fail"
#endif
I have gone through the source code of Data::Dumper. In this package I didn't understand what's going on with DumpXS. What is the use of this DumpXS?
I have searched about this and I read that, it is equal to the Dump function and it is faster than Dump. But I didn't understand it.
The XS language is a glue between normal Perl and C. When people want to squeeze every last bit of performance out of an operation, they try to write it as close to the C code as possible. Python and Ruby have similar mechanisms for the same reason.
Some Perl modules have an XS implementation to improve performance. However, you need a C compiler to install it. Not everyone is in a position to install compiled modules, so the modules also come in a "PurePerl" or "PP" version that does the same thing just a bit slower. If you don't have the XS implementation, a module such as Data::Dumper can automatically use the pure Perl implementation. In this case, Data::Dumper also lets you choose which one you want to use.
A lot of Perl modules have "XS" versions, like JSON::XS. The XS in the name means that it partly uses C in order to increase the speed or other efficiency of the module. I don't know this particular case, but it is probably that.
And if you want a bit more info on XS go to http://perldoc.perl.org/perlxs.html
But I am curious what lead you to this question.