def parse_prototype(sigparser, decl, prototypes): """Get the C++ prototype for a given function declaration.""" # poor man's scanner :-) tokens = re.sub(r'[,()]', lambda m: ' ' + m.group(0) + ' ', decl).split() tokens, ret_type = sigparser.get_type(tokens) name = tokens[0] if tokens[1] != '(': error("unknown token '" + tokens[1] + "' while processing '" + decl + "': '(' expected") sys.exit(1) tokens = tokens[2:] params = [] if tokens[0] != ')': while True: tokens, t = sigparser.get_type(tokens) paramname = tokens[0] tokens = tokens[1:] if tokens[0] == '=': # default argument defarg, tokens = eat_until({',': None, ')': None}, tokens[1:]) else: defarg = [] params.append((t, paramname, ''.join(defarg))) if tokens[0] == ')': break if tokens[0] != ',': error("unknown token '" + tokens[1] + "' while processing '" + decl + "': ',' expected") sys.exit(1) # skip the comma tokens = tokens[1:] # For array returns, add one pointer parameter per array element if "[" in ret_type: match = re.match("([^[]+)\[(\d+)\]", ret_type) if match: elem_type = match.group(1) num_elems = int(match.group(2)) for i in range(num_elems): params.append((elem_type + "*", "res_%d" % i, [])) ret_type = "void" prototype = "%s %s(%s);" % (ret_type, name, ", ".join( map(format_param, params))) if "[" in ret_type or name == "transpose" or "[<N>]" in prototype: prototype = "// %s (not supported yet)" % prototype prototypes.append(prototype)
def main(args): """Process one file and generate signatures.""" if len(args) != 3: return usage(args) stdlib_dir = args[1] out_name = args[2] strict = True prototypes = [] # monkey patch SignatureParser to generate signature names suitable for C++ header files SignatureParser.get_signature = ( lambda self, decl: parse_prototype(self, decl, prototypes)) try: parser = SignatureParser(args[0], stdlib_dir, out_name, strict) # copy the copyright from first 3 lines of state.cpp state_cpp_path = os.path.join(os.path.dirname(out_name), "state.cpp") with open(state_cpp_path) as f: copyright = "".join([next(f) for x in xrange(3)]) with open(out_name, "w") as f: parser.write(f, copyright) parser.write( f, "\n#ifndef MDL_USER_MODULES_MDL_RUNTIME_H\n" "#define MDL_USER_MODULES_MDL_RUNTIME_H\n") for module_name in ["math", "debug"]: # clear list before parsing next module del prototypes[:] parser.parse(module_name) parser.write(f, "\nnamespace %s\n" % module_name) parser.write(f, "{\n") parser.indent += 1 for prototype in prototypes: print_wrapped(parser, f, prototype) parser.indent -= 1 parser.write(f, "}\n") parser.write(f, "\n#endif // MDL_USER_MODULES_MDL_RUNTIME_H\n") except Exception as e: error(str(e)) return 1 return 0
def parse_prototype(sigparser, decl, prototypes): """Get the C++ prototype for a given function declaration.""" # poor man's scanner :-) tokens = re.sub(r'[,()]', lambda m: ' ' + m.group(0) + ' ', decl).split() tokens, ret_type = sigparser.get_type(tokens) name = tokens[0] if tokens[1] != '(': error("unknown token '" + tokens[1] + "' while processing '" + decl + "': '(' expected") sys.exit(1) tokens = tokens[2:] params = [] if tokens[0] != ')': while True: tokens, t = sigparser.get_type(tokens) paramname = tokens[0] tokens = tokens[1:] if tokens[0] == '=': # default argument defarg, tokens = eat_until({',': None, ')': None}, tokens[1:]) else: defarg = [] params.append((t, paramname, ''.join(defarg))) if tokens[0] == ')': break if tokens[0] != ',': error("unknown token '" + tokens[1] + "' while processing '" + decl + "': ',' expected") sys.exit(1) # skip the comma tokens = tokens[1:] ret_type = type_map.get(ret_type, ret_type) prototype = "%s %s(%s);" % (ret_type, name, ", ".join( map(format_param, params))) if "[" in ret_type or name == "transpose" or "[<N>]" in prototype or "color " in prototype: prototype = "// %s (not supported yet)" % prototype prototypes.append(prototype)