diff options
author | cookedm <cookedm@localhost> | 2006-07-06 16:57:20 +0000 |
---|---|---|
committer | cookedm <cookedm@localhost> | 2006-07-06 16:57:20 +0000 |
commit | 6782a92fd1a7625ee48f6b2946a7d7149ab28a77 (patch) | |
tree | 177a92f0673655b58b247e663477af06ac1192b6 /lib2def.py | |
parent | 216f071ab060a6f08c22666aea33f7095f079d1e (diff) | |
download | numpy-6782a92fd1a7625ee48f6b2946a7d7149ab28a77.tar.gz |
Branch numpy.distutils to distutils-revamp
Diffstat (limited to 'lib2def.py')
-rw-r--r-- | lib2def.py | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/lib2def.py b/lib2def.py new file mode 100644 index 000000000..c42530931 --- /dev/null +++ b/lib2def.py @@ -0,0 +1,116 @@ +import re +import sys +import os +import string + +__doc__ = """This module generates a DEF file from the symbols in +an MSVC-compiled DLL import library. It correctly discriminates between +data and functions. The data is collected from the output of the program +nm(1). + +Usage: + python lib2def.py [libname.lib] [output.def] +or + python lib2def.py [libname.lib] > output.def + +libname.lib defaults to python<py_ver>.lib and output.def defaults to stdout + +Author: Robert Kern <kernr@mail.ncifcrf.gov> +Last Update: April 30, 1999 +""" + +__version__ = '0.1a' + +import sys + +py_ver = "%d%d" % tuple(sys.version_info[:2]) + +DEFAULT_NM = 'nm -Cs' + +DEF_HEADER = """LIBRARY python%s.dll +;CODE PRELOAD MOVEABLE DISCARDABLE +;DATA PRELOAD SINGLE + +EXPORTS +""" % py_ver +# the header of the DEF file + +FUNC_RE = re.compile(r"^(.*) in python%s\.dll" % py_ver, re.MULTILINE) +DATA_RE = re.compile(r"^_imp__(.*) in python%s\.dll" % py_ver, re.MULTILINE) + +def parse_cmd(): + """Parses the command-line arguments. + +libfile, deffile = parse_cmd()""" + if len(sys.argv) == 3: + if sys.argv[1][-4:] == '.lib' and sys.argv[2][-4:] == '.def': + libfile, deffile = sys.argv[1:] + elif sys.argv[1][-4:] == '.def' and sys.argv[2][-4:] == '.lib': + deffile, libfile = sys.argv[1:] + else: + print "I'm assuming that your first argument is the library" + print "and the second is the DEF file." + elif len(sys.argv) == 2: + if sys.argv[1][-4:] == '.def': + deffile = sys.argv[1] + libfile = 'python%s.lib' % py_ver + elif sys.argv[1][-4:] == '.lib': + deffile = None + libfile = sys.argv[1] + else: + libfile = 'python%s.lib' % py_ver + deffile = None + return libfile, deffile + +def getnm(nm_cmd = 'nm -Cs python%s.lib' % py_ver): + """Returns the output of nm_cmd via a pipe. + +nm_output = getnam(nm_cmd = 'nm -Cs py_lib')""" + f = os.popen(nm_cmd) + nm_output = f.read() + f.close() + return nm_output + +def parse_nm(nm_output): + """Returns a tuple of lists: dlist for the list of data +symbols and flist for the list of function symbols. + +dlist, flist = parse_nm(nm_output)""" + data = DATA_RE.findall(nm_output) + func = FUNC_RE.findall(nm_output) + + flist = [] + for sym in data: + if sym in func and (sym[:2] == 'Py' or sym[:3] == '_Py' or sym[:4] == 'init'): + flist.append(sym) + + dlist = [] + for sym in data: + if sym not in flist and (sym[:2] == 'Py' or sym[:3] == '_Py'): + dlist.append(sym) + + dlist.sort() + flist.sort() + return dlist, flist + +def output_def(dlist, flist, header, file = sys.stdout): + """Outputs the final DEF file to a file defaulting to stdout. + +output_def(dlist, flist, header, file = sys.stdout)""" + for data_sym in dlist: + header = header + '\t%s DATA\n' % data_sym + header = header + '\n' # blank line + for func_sym in flist: + header = header + '\t%s\n' % func_sym + file.write(header) + +if __name__ == '__main__': + libfile, deffile = parse_cmd() + if deffile is None: + deffile = sys.stdout + else: + deffile = open(deffile, 'w') + nm_cmd = '%s %s' % (DEFAULT_NM, libfile) + nm_output = getnm(nm_cmd) + dlist, flist = parse_nm(nm_output) + output_def(dlist, flist, DEF_HEADER, deffile) |