What is a recommended way to import a bunch of constants defined in a c-style (not c++, just plain old c) .h file into python module so that it can be used in python's part of a project. In the project we use a mix of languages and in perl I can do this importing by using h2xs utility to generate .pm module.
Constants definition looks like
#define FOO 1
enum {
BAR,
BAZ
};
etc.
C-style comments are also presented an have to be properly handled.
I recently used the pyparsing library to scan for enum constants. Here it is, along with a sample string and the resulting output. Notice it also handles comments and commented out sections. With a little modification it could stuff the constants in a dictionary.
from pyparsing import *
sample = '''
stuff before
enum hello {
Zero,
One,
Two,
Three,
Five=5,
Six,
Ten=10
}
in the middle
enum blah
{
alpha, // blah
beta, /* blah blah
gamma = 10 , */
zeta = 50
}
at the end
'''
# syntax we don't want to see in the final parse tree
_lcurl = Suppress('{')
_rcurl = Suppress('}')
_equal = Suppress('=')
_comma = Suppress(',')
_enum = Suppress('enum')
identifier = Word(alphas,alphanums+'_')
integer = Word(nums)
enumValue = Group(identifier('name') + Optional(_equal + integer('value')))
enumList = Group(enumValue + ZeroOrMore(_comma + enumValue))
enum = _enum + identifier('enum') + _lcurl + enumList('list') + _rcurl
enum.ignore(cppStyleComment)
for item,start,stop in enum.scanString(sample):
id = 0
for entry in item.list:
if entry.value != '':
id = int(entry.value)
print '%s_%s = %d' % (item.enum.upper(),entry.name.upper(),id)
id += 1
OUTPUT:
HELLO_ZERO = 0
HELLO_ONE = 1
HELLO_TWO = 2
HELLO_THREE = 3
HELLO_FIVE = 5
HELLO_SIX = 6
HELLO_TEN = 10
BLAH_ALPHA = 0
BLAH_BETA = 1
BLAH_ZETA = 50
I once had to do something similar, and in the end I did something strange but highly reliable. Dealing with all the possibilities for how values might be defined is tricky... for instance, you have to handle
#include "someotherfile.h"
enum NewEnum {
A = -5,
B = SOME_OTHER_ENUM,
C,
D = 3
};
(which is really nasty and no one should ever do...)
In the end, part of my build process was a perl script that parsed the header file for all enums and defines, and then produced a .c file that included the header and was nothing more then a bunch of print statements, printing the actual value for each define. This file was compiled and executed, and the output of that was used to produce the next source file ( Java, in my case ).
This ensured that I got the right values, as I was using the C preprocessor and compiler to produce the answers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With