From 82774bdf613702c7e0af5cbb292b9ec49d14b3db Mon Sep 17 00:00:00 2001 From: Kuba Sunderland-Ober Date: Tue, 20 Jun 2023 00:09:29 -0400 Subject: [PATCH 1/2] Make sure doc writer doesn't mangle encodings on non-utf8 systems like Windows. --- hpy/devel/__init__.py | 2 +- hpy/tools/autogen/autogenfile.py | 2 +- hpy/tools/autogen/doc.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hpy/devel/__init__.py b/hpy/devel/__init__.py index e59dd027a..3b7f6e6d1 100644 --- a/hpy/devel/__init__.py +++ b/hpy/devel/__init__.py @@ -428,7 +428,7 @@ def write_stub(self, output_dir, ext, compile=False): ext_file = os.path.basename(ext._file_name) module_name = ext_file.split(".")[0] if not self.dry_run: - with open(stub_file, 'w') as f: + with open(stub_file, 'w', encoding='utf-8') as f: f.write(_HPY_UNIVERSAL_MODULE_STUB_TEMPLATE.format( ext_file=ext_file, module_name=module_name) ) diff --git a/hpy/tools/autogen/autogenfile.py b/hpy/tools/autogen/autogenfile.py index 0f6d51549..d4fddb74c 100644 --- a/hpy/tools/autogen/autogenfile.py +++ b/hpy/tools/autogen/autogenfile.py @@ -27,7 +27,7 @@ def generate(self): def write(self, root): cls = self.__class__ clsname = '%s.%s' % (cls.__module__, cls.__name__) - with root.join(self.PATH).open('w') as f: + with root.join(self.PATH).open('w', encoding='utf-8') as f: if self.DISCLAIMER is not None: f.write(self.DISCLAIMER.format(clsname=clsname)) f.write('\n') diff --git a/hpy/tools/autogen/doc.py b/hpy/tools/autogen/doc.py index 5b481d63d..982476886 100644 --- a/hpy/tools/autogen/doc.py +++ b/hpy/tools/autogen/doc.py @@ -64,7 +64,7 @@ def write(self, root): if not self.BEGIN_MARKER or not self.END_MARKER: raise RuntimeError("missing BEGIN_MARKER or END_MARKER") n_begin = len(self.BEGIN_MARKER) - with root.join(self.PATH).open('r') as f: + with root.join(self.PATH).open('r', encoding='utf-8') as f: content = f.read() start = content.find(self.BEGIN_MARKER) if start < 0: @@ -75,7 +75,7 @@ def write(self, root): raise RuntimeError(f'end marker "{self.END_MARKER}" not found in' f'file {self.PATH}') new_content = self.generate(content[(start+n_begin):end]) - with root.join(self.PATH).open('w') as f: + with root.join(self.PATH).open('w', encoding='utf-8') as f: f.write(content[:start + n_begin] + new_content + content[end:]) From ace5fed0b59d5eb62afc895c5779e9d7e623d85a Mon Sep 17 00:00:00 2001 From: Kuba Sunderland-Ober Date: Tue, 20 Jun 2023 00:10:15 -0400 Subject: [PATCH 2/2] Detect and use MSVC compiler if available for preprocessing. Autogen has to be invoked from the MSVC command line so that cl.exe is in path. --- hpy/tools/autogen/parse.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/hpy/tools/autogen/parse.py b/hpy/tools/autogen/parse.py index ce40e2633..c349c1107 100644 --- a/hpy/tools/autogen/parse.py +++ b/hpy/tools/autogen/parse.py @@ -4,6 +4,7 @@ import re import py import pycparser +import shutil from pycparser import c_ast from pycparser.c_generator import CGenerator from distutils.sysconfig import get_config_var @@ -202,16 +203,27 @@ class HPyAPI: re.DOTALL | re.MULTILINE) def __init__(self, filename): - cpp_cmd = get_config_var('CC').split(' ') + cpp_cmd = get_config_var('CC') + if cpp_cmd: + cpp_cmd = cpp_cmd.split(' ') + elif sys.platform == 'win32': + cpp_cmd = [shutil.which("cl.exe")] if sys.platform == 'win32': cpp_cmd += ['/E', '/I%s' % CURRENT_DIR] else: cpp_cmd += ['-E', '-I%s' % CURRENT_DIR] + msvc = "cl.exe" in cpp_cmd[0].casefold() + csource = pycparser.preprocess_file(filename, cpp_path=str(cpp_cmd[0]), cpp_args=cpp_cmd[1:]) + # MSVC preprocesses _Pragma(foo) to __pragma(foo), + # but cparser needs to see a #pragma, not __pragma. + if msvc: + csource = re.sub(r'__pragma\(([^)]+)\)', r'#pragma \1\n', csource) + # Remove comments. NOTE: this assumes that comments are never inside # string literals, but there shouldn't be any here. def replace_keeping_newlines(m):