145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#!/usr/bin/env python 245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org""" 445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org(c) 2002, 2003, 2004, 2005 Simon Burton <simon@arrowtheory.com> 645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgReleased under GNU LGPL license. 745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgversion 0.xx 945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org""" 1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgimport sys 1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgimport os 1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgimport cparse 1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgimport ir 1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 19a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.orgdef callcmd(cmd): 20a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org try: 21a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org from subprocess import call 22a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org try: 23a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org retcode = call(cmd, shell=True) 24a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org assert retcode == 0, "command failed: %s"%cmd 25a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org except OSError, e: 26a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org assert False, "command failed: %s"%e 27a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org except ImportError: 28a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org status = os.system( cmd ) 29a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org assert status == 0, "command failed: %s"%cmd 30a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org 3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgclass WorkUnit(object): 3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org def __init__(self, files, modname, filename, 3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org std=False, strip=False, mark_cb=None, 3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org extradefs="", use_header=None, CC="gcc", CPP="gcc -E", 3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org CPPFLAGS=""): 3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.files = tuple(files) 3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.modname = modname 3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.filename = filename 3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.CPPFLAGS = CPPFLAGS 4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.CPP = CPP 4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if CC == 'g++': 4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.CPPFLAGS += " -D__cplusplus" 4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.std = std 4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.strip = strip 4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.mark_cb = mark_cb 4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.node = None 4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.extradefs = extradefs 4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.CC = CC 4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.use_header = use_header 5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org def mkheader( self ): 5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if self.use_header: 5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return self.use_header 5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org tmpname = str(abs(hash( (self.files,self.CPPFLAGS) ))) 5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org name = '.tmp/%s' % tmpname 5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ifile = open( name+'.h', "w" ) 5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ifile.write( """ 5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define __attribute__(...) 5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define __const const 6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define __restrict 6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define __extension__ 6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define __asm__(...) 6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define __asm(...) 6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define __inline__ 6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define __inline 6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org""" ) 6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for filename in self.files: 6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if self.std: 6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = '#include <%s>\n'%filename 7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org else: 7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org line = '#include "%s"\n'%filename 7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ifile.write( line ) 7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org print line, 7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ifile.close() 7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cmd = '%s %s %s > %s'%(self.CPP,name+'.h',self.CPPFLAGS,name+'.E') 7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sys.stderr.write( "# %s\n" % cmd ) 77a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org callcmd( cmd ) 7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert open(name+'.E').read().count('\n') > 10, "failed to run preprocessor" 7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org cmd = '%s -dM %s %s > %s'%(self.CPP,name+'.h',self.CPPFLAGS,name+'.dM') 8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sys.stderr.write( "# %s\n" % cmd ) 81a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org callcmd( cmd ) 8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert open(name+'.dM').read().count('\n') > 10, "failed to run preprocessor with -dM" 8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return name 8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org def parse(self, verbose=False): 8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sys.stderr.write( "# parse %s\n" % str(self.files) ) 8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org name = self.mkheader() 8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org # read macros 8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org f = open(name+'.dM') 9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macros = {} 9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for line in f.readlines(): 9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if line: 9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro = line.split()[1] 9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if macro.count('('): 9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macro = macro[:macro.index('(')] 9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org macros[macro] = None 9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org #keys = macros.keys() 9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org #keys.sort() 9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org #for key in keys: 10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org #print key 10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.macros = macros 10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org # parse preprocessed code 10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org f = open(name+'.E') 10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org s = f.read() + self.extradefs 10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.node = cparse.TransUnit(verbose = verbose) 10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sys.stderr.write( "# parsing %s lines\n" % s.count('\n') ) 10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.node.parse( s ) 10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if self.strip: 10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.node.strip(self.files) 11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org def transform(self, verbose=False, test_parse=False, test_types=False): 11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sys.stderr.write( "# processing...\n" ) 11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.node = ir.TransUnit( self.node ) 11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.node.transform(verbose, test_parse, test_types) 11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org #self.node[0].psource() 11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if self.mark_cb is not None: 11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org self.node.mark(self.mark_cb,verbose=False) 11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org def output( self, func_cb = None ): 12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sys.stderr.write( "# pyxstr...\n" ) 12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org decls = self.node.pyx_decls(self.files, self.modname, macros = self.macros, func_cb = func_cb, names={}, cprefix="" ) 12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org name = self.filename 12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org assert name.endswith(".pyx") 12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org pxi = name[:-3]+'pxi' 12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org file = open( pxi, "w" ) 12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org file.write(decls) 12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sys.stderr.write( "# wrote %s, %d lines\n" % (pxi,decls.count('\n')) ) 13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org def pprint(self): 13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for decl in self.node: 13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org #decl.psource() 13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org #cstr = decl.cstr() 13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org #cstr = cstr.replace( '\n', '\n# ' ) 13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org print 13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org #print '#', cstr 13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org print decl.deepstr() 13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdef file_exists(path): 14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org try: 14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org os.stat(path) 14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return True 14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org except OSError: 14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return False 14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgif sys.platform.count('darwin'): 14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org shared_ext = '.dylib' 14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgelse: 15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org shared_ext = '.so' 15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgdef get_syms(libs, libdirs): 15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org # XX write interface to objdump -t XX 15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org libnames = [] 15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for lib in libs: 15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for ext in shared_ext,'.a': 15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org libname = 'lib'+lib+ext 15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for libdir in libdirs: 15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org path = libdir+'/'+libname 16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if file_exists(path): 16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org libnames.append(path) 16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break 16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org #else: 16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org #print "cannot find %s lib as %s in %s" % ( lib, libname, libdir ) 16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org print 'libnames:', libnames 16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org syms = {} 16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org accept = [ ' %s '%c for c in 'TVWBCDGRS' ] 16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org #f = open('syms.out','w') 16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for libname in libnames: 170a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org try: 171a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org from subprocess import Popen, PIPE 172a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org p = Popen(['nm', libname], bufsize=1, stdout=PIPE) 173a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org fout = p.stdout 174a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org except ImportError: 175a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org fin, fout = os.popen2( 'nm %s' % libname ) 17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for line in fout.readlines(): 17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org for acc in accept: 17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if line.count(acc): 17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org left, right = line.split(acc) 18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sym = right.strip() 18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if sys.platform.count('darwin'): 18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if sym[0] == '_': 18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sym = sym[1:] # remove underscore prefix 18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if sym.endswith('.eh'): 18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org sym = sym[:-len('.eh')] 18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org syms[sym] = None 18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org #f.write( '%s: %s %s\n' % (sym,line[:-1],libname) ) 18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org break 18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return syms 19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 193