1#!/usr/bin/python 2 3import sys 4import re 5import os 6 7INCLUDE_RE = re.compile('^#include "([^"]*)"$') 8 9def parse_include(line): 10 match = INCLUDE_RE.match(line) 11 return match.groups()[0] if match else None 12 13class Amalgamator: 14 def __init__(self, output_path): 15 self.include_paths = ["."] 16 self.included = set(["upb/port_def.inc", "upb/port_undef.inc"]) 17 self.output_h = open(output_path + "upb.h", "w") 18 self.output_c = open(output_path + "upb.c", "w") 19 20 self.output_c.write("/* Amalgamated source file */\n") 21 self.output_c.write('#include "upb.h"\n') 22 self.output_c.write(open("upb/port_def.inc").read()) 23 24 self.output_h.write("/* Amalgamated source file */\n") 25 self.output_h.write('#include <stdint.h>') 26 self.output_h.write(open("upb/port_def.inc").read()) 27 28 def add_include_path(self, path): 29 self.include_paths.append(path) 30 31 def finish(self): 32 self.output_c.write(open("upb/port_undef.inc").read()) 33 self.output_h.write(open("upb/port_undef.inc").read()) 34 35 def _process_file(self, infile_name, outfile): 36 file = None 37 for path in self.include_paths: 38 try: 39 full_path = os.path.join(path, infile_name) 40 file = open(full_path) 41 break 42 except IOError: 43 pass 44 if not file: 45 raise RuntimeError("Couldn't open file " + infile_name) 46 47 for line in file: 48 include = parse_include(line) 49 if include is not None and (include.startswith("upb") or 50 include.startswith("google")): 51 if include not in self.included: 52 self.included.add(include) 53 self._add_header(include) 54 else: 55 outfile.write(line) 56 57 def _add_header(self, filename): 58 self._process_file(filename, self.output_h) 59 60 def add_src(self, filename): 61 self._process_file(filename, self.output_c) 62 63# ---- main ---- 64 65output_path = sys.argv[1] 66amalgamator = Amalgamator(output_path) 67files = [] 68 69for arg in sys.argv[2:]: 70 arg = arg.strip() 71 if arg.startswith("-I"): 72 amalgamator.add_include_path(arg[2:]) 73 elif arg.endswith(".h") or arg.endswith(".inc"): 74 pass 75 else: 76 files.append(arg) 77 78for filename in files: 79 amalgamator.add_src(filename) 80 81amalgamator.finish() 82