diff -r 76ed5454b09d PC/python3defgen.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PC/python3defgen.py Thu Apr 09 22:41:00 2015 -0500 @@ -0,0 +1,91 @@ +import os +import re +import sys +from importlib.machinery import SourceFileLoader + +src_root = os.path.dirname(os.path.dirname(__file__)) +clinic_cpp_path = os.path.join(src_root, 'Tools', 'clinic', 'cpp.py') + +clinic_cpp = SourceFileLoader('cpp', clinic_cpp_path).load_module() + +header = """\ +; This file specifies the import forwarding for python3.dll +; It is used when building python3dll.vcxproj +; Generated by python3defgen.py, DO NOT modify directly! +LIBRARY "python3" +EXPORTS +""" + +version_limited_re = re.compile(r'Py_LIMITED_API\s*\+\s*0\s*>') + +class Parser(clinic_cpp.Monitor): + def is_for_windows(self): + for token, condition in self.stack: + if "!defined(MS_WINDOWS)" in condition: + return False + else: + return True + + def is_limited(self): + # if 'abstract.h' in self.filename: + # print(self.stack) + for token, condition in self.stack: + if version_limited_re.search(condition): + return True + if "!defined(Py_LIMITED_API)" in condition: + return False + if "defined(Py_LIMITED_API)" in condition: + return True + else: + return True + +func_re = re.compile(r'PyAPI_FUNC\(.+\)\s*(_?Py\w+)\(') +data_re = re.compile(r'PyAPI_DATA\(.+\).*?(_?Py\w+)') + +exports = {} + +for fn in os.listdir(os.path.join(src_root, 'Include')): + if fn == 'pgenheaders.h': + # special case to skip couple of unavoidable duplicates + continue + fn = os.path.join(src_root, 'Include', fn) + with open(fn) as f: + parser = Parser(fn) + for lineno, line in enumerate(f): + parser.writeline(line) + if (parser.in_comment or + not parser.is_limited() or + not parser.is_for_windows()): + continue + export = None + m = func_re.search(line) + if m is not None: + export = m.group(1) + type = 'func' + else: + m = data_re.search(line) + if m is not None: + export = m.group(1) + type = 'data' + if export is not None: + if export not in exports: + exports[export] = [(type, fn, lineno)] + else: + exports[export].append((type, fn, lineno)) + +lines = [] +for name, occurrances in exports.items(): + if len(occurrances) > 1: + print('Duplicates found:') + for type, fn, lineno in occurrances: + print(' {} {}, {}:{}'.format(type, name, fn, lineno)) + type = occurrances[0][0] + if type == 'func': + lines.append(' {0}=python35.{0}\n'.format(name)) + elif type == 'data': + lines.append(' {0}=python35.{0} DATA\n'.format(name)) + +with open(os.path.join(os.path.dirname(__file__), 'python3.def.tmp'), 'w') as f: + f.write(header) + f.writelines(sorted(lines)) + f.write('\n')