blob: 31ab3e56799f96b8e8303d96dd4118c992b4f661 [file] [log] [blame]
#!/usr/bin/env python
"""
(c) 2002, 2003, 2004, 2005 Simon Burton <simon@arrowtheory.com>
Released under GNU LGPL license.
version 0.xx
"""
import sys
import os
import cparse
import ir
def callcmd(cmd):
try:
from subprocess import call
try:
retcode = call(cmd, shell=True)
assert retcode == 0, "command failed: %s"%cmd
except OSError, e:
assert False, "command failed: %s"%e
except ImportError:
status = os.system( cmd )
assert status == 0, "command failed: %s"%cmd
class WorkUnit(object):
def __init__(self, files, modname, filename,
std=False, strip=False, mark_cb=None,
extradefs="", use_header=None, CC="gcc", CPP="gcc -E",
CPPFLAGS=""):
self.files = tuple(files)
self.modname = modname
self.filename = filename
self.CPPFLAGS = CPPFLAGS
self.CPP = CPP
if CC == 'g++':
self.CPPFLAGS += " -D__cplusplus"
self.std = std
self.strip = strip
self.mark_cb = mark_cb
self.node = None
self.extradefs = extradefs
self.CC = CC
self.use_header = use_header
def mkheader( self ):
if self.use_header:
return self.use_header
tmpname = str(abs(hash( (self.files,self.CPPFLAGS) )))
name = '.tmp/%s' % tmpname
ifile = open( name+'.h', "w" )
ifile.write( """
#define __attribute__(...)
#define __const const
#define __restrict
#define __extension__
#define __asm__(...)
#define __asm(...)
#define __inline__
#define __inline
""" )
for filename in self.files:
if self.std:
line = '#include <%s>\n'%filename
else:
line = '#include "%s"\n'%filename
ifile.write( line )
print line,
ifile.close()
cmd = '%s %s %s > %s'%(self.CPP,name+'.h',self.CPPFLAGS,name+'.E')
sys.stderr.write( "# %s\n" % cmd )
callcmd( cmd )
assert open(name+'.E').read().count('\n') > 10, "failed to run preprocessor"
cmd = '%s -dM %s %s > %s'%(self.CPP,name+'.h',self.CPPFLAGS,name+'.dM')
sys.stderr.write( "# %s\n" % cmd )
callcmd( cmd )
assert open(name+'.dM').read().count('\n') > 10, "failed to run preprocessor with -dM"
return name
def parse(self, verbose=False):
sys.stderr.write( "# parse %s\n" % str(self.files) )
name = self.mkheader()
# read macros
f = open(name+'.dM')
macros = {}
for line in f.readlines():
if line:
macro = line.split()[1]
if macro.count('('):
macro = macro[:macro.index('(')]
macros[macro] = None
#keys = macros.keys()
#keys.sort()
#for key in keys:
#print key
self.macros = macros
# parse preprocessed code
f = open(name+'.E')
s = f.read() + self.extradefs
self.node = cparse.TransUnit(verbose = verbose)
sys.stderr.write( "# parsing %s lines\n" % s.count('\n') )
self.node.parse( s )
if self.strip:
self.node.strip(self.files)
def transform(self, verbose=False, test_parse=False, test_types=False):
sys.stderr.write( "# processing...\n" )
self.node = ir.TransUnit( self.node )
self.node.transform(verbose, test_parse, test_types)
#self.node[0].psource()
if self.mark_cb is not None:
self.node.mark(self.mark_cb,verbose=False)
def output( self, func_cb = None ):
sys.stderr.write( "# pyxstr...\n" )
decls = self.node.pyx_decls(self.files, self.modname, macros = self.macros, func_cb = func_cb, names={}, cprefix="" )
name = self.filename
assert name.endswith(".pyx")
pxi = name[:-3]+'pxi'
file = open( pxi, "w" )
file.write(decls)
sys.stderr.write( "# wrote %s, %d lines\n" % (pxi,decls.count('\n')) )
def pprint(self):
for decl in self.node:
#decl.psource()
#cstr = decl.cstr()
#cstr = cstr.replace( '\n', '\n# ' )
print
#print '#', cstr
print decl.deepstr()
def file_exists(path):
try:
os.stat(path)
return True
except OSError:
return False
if sys.platform.count('darwin'):
shared_ext = '.dylib'
else:
shared_ext = '.so'
def get_syms(libs, libdirs):
# XX write interface to objdump -t XX
libnames = []
for lib in libs:
for ext in shared_ext,'.a':
libname = 'lib'+lib+ext
for libdir in libdirs:
path = libdir+'/'+libname
if file_exists(path):
libnames.append(path)
break
#else:
#print "cannot find %s lib as %s in %s" % ( lib, libname, libdir )
print 'libnames:', libnames
syms = {}
accept = [ ' %s '%c for c in 'TVWBCDGRS' ]
#f = open('syms.out','w')
for libname in libnames:
try:
from subprocess import Popen, PIPE
p = Popen(['nm', libname], bufsize=1, stdout=PIPE)
fout = p.stdout
except ImportError:
fin, fout = os.popen2( 'nm %s' % libname )
for line in fout.readlines():
for acc in accept:
if line.count(acc):
left, right = line.split(acc)
sym = right.strip()
if sys.platform.count('darwin'):
if sym[0] == '_':
sym = sym[1:] # remove underscore prefix
if sym.endswith('.eh'):
sym = sym[:-len('.eh')]
syms[sym] = None
#f.write( '%s: %s %s\n' % (sym,line[:-1],libname) )
break
return syms