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
def __str__(self): message = "Input program contains multiple (" + str(len(self.loops)) + ") main loops in function " \ + self.main_function_name + ", namely:\n" for i, loop in enumerate(self.loops): message += str(i) + ")\n" + GnuCGenerator().visit(loop) + "\n" return message
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