示例#1
0
def write_file(out_dir, header_include, node, errno, retval):
    header = """
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
#include <%s>
"""

    code_template = """
static %s %s(*%s) (%s) = NULL;
%s {
  char* var = getenv("PROB");
  float p = atof(var);
  int flip = rand_bool((double) p);
  %s = dlsym(RTLD_NEXT, "%s");
  if(flip || (%s == NULL)) {
    %s
    return %s;
  } else {
    %s
  }
}
"""

    gen = GnuCGenerator()

    new_fn = node.name
    real_fn = "real_" + new_fn

    arglist = gen.visit(node.type.args)

    is_ptr_result = isinstance(node.type.type, c_ast.PtrDecl)
    is_void_result = gen.visit(node.type.type) == "void" and not is_ptr_result

    # eliminate __extension__ and stuff like it from the function signature
    func_sig = "%s %s %s%s(%s)" % (' '.join(
        node.storage), gen.visit(
            node.type.type), '*' if is_ptr_result else '', new_fn, arglist)

    new_file = out_dir + '%s_wrapper.c' % new_fn
    with open(new_file, 'w') as f:
        f.write(header % header_include)
        f.write(code_template % (
            gen.visit(node.type.type),  # int
            '*' if isinstance(node.type.type, c_ast.PtrDecl) else '',
            real_fn,  # real_open
            gen.visit(node.type.args),  # (args with types)
            func_sig,
            real_fn,  # real_open
            new_fn,
            real_fn,  # real_open
            ("errno = %s;" % errno) if errno is not None else "",
            retval,
            "%s%s(%s);" % (  # return
                "return " if not is_void_result else "",
                real_fn,  # real_open
                ', '.join([
                    a.name if a.name is not None else ''
                    for a in node.type.args.params
                    if not isinstance(a, c_ast.EllipsisParam)
                ]),
            )))
    print 'wrote %s' % new_file
示例#2
0
def programPrint(statement):
    generator = GnuCGenerator()
    return str(generator.visit(statement))
示例#3
0
def generate_cdef():
    """Generate the cdef output file"""
    include_v4l2_path = '/usr/include/linux'
    #include_v4l2_path='.'
    #out_file = path.join(HERE, 'v4l2', 'videodev2.cdef.h')
    #out_packed_file = path.join(HERE, 'v4l2', 'videodev2.cdef_packed.h')
    #header = path.join(include_v4l2_path, 'videodev2.h')
    #header_parsed = path.join(HERE, 'v4l2', 'videodev2.h')
    #enum_file = path.join(HERE, 'v4l2', 'v4l2_enums.py')
    out_file = os.path.join(HERE, BUILDDIR, 'videodev2.cdef.h')
    out_packed_file = os.path.join(HERE, BUILDDIR, 'videodev2.cdef_packed.h')
    header = os.path.join(include_v4l2_path, 'videodev2.h')
    header_parsed = os.path.join(HERE, BUILDDIR, 'videodev2.h')
    enum_file = os.path.join(HERE, 'v4l2enums.py')

    out = open(header_parsed, 'w+')
    cpp_process = subprocess.Popen(
        [
            'cpp',
            '-P',
            #'-nostdinc',
            '-I',
            'fake-include',
            header
        ],
        stdout=out)
    cpp_process.wait()
    out.close()

    headerin = open(header_parsed, 'r')
    headersrc = headerin.read()
    from pycparserext.ext_c_parser import GnuCParser
    p = GnuCParser()
    ast = p.parse(headersrc, filename=header_parsed)
    # ast.show()
    headerin.close()
    out = open(out_file, 'w+')
    out_packed = open(out_packed_file, 'w+')
    enums = open(enum_file, 'w+')
    enums.write('import enum\nimport v4l2\n')
    from pycparserext.ext_c_generator import GnuCGenerator
    g = GnuCGenerator()
    i = 0
    for nname, astnode in ast.children():
        outthis = out
        if type(astnode) == pycparser.c_ast.Decl:
            #print('node', i)
            #print(g.visit(astnode)+'\n')
            for spec in astnode.funcspec:
                if type(spec) == pycparserext.ext_c_parser.AttributeSpecifier:
                    for att in spec.exprlist.exprs:
                        if att.name == 'packed':
                            outthis = out_packed
            if type(astnode.type) == pycparser.c_ast.Enum:
                enumnode = astnode.type
                enums.write('class ' + enumnode.name + '(enum.IntEnum):\n')
                for el in enumnode.values.enumerators:
                    enums.write('    ' + el.name + ' = v4l2.' + el.name + '\n')
                enums.write('\n')
            if type(astnode.type) != pycparserext.ext_c_parser.FuncDeclExt:
                #print(i, type(astnode.type))
                outthis.write(g.generic_visit(astnode) + ';\n')
            else:
                # for parsing ioctl(...) decalaration
                outthis.write(g.visit(astnode) + ';\n')
        else:
            outthis.write(g.visit(astnode) + ';\n')
        #print('node', i)
        #print(g.generic_visit(astnode)+'\n')
        i += 1
    out.flush()
    out.close()
    out_packed.flush()
    out_packed.close()
    enums.flush()
    enums.close()

    print('generate_cdef: generated\n      ', out_file, ',\n      ',
          out_packed_file, '\n  and', enum_file, 'from', header)
    return out_file, out_packed_file