开发者

How to import constants from .h file into python module

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.


I'd suggest the other way round, if possible: define all your constants in a Python dict or module and auto-generate the .h in Python. It will be much, much easier.


Create a script/program that is called from make and creates the necessary python file. If you only need #define and enum it shouldn't be too hard to write. Then remember NOT to check this python file into source control as you want the build process to force the regeneration of the file every time.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜