From 197a3d9d05677de9c6e14c2ffb3a871aecab59e4 Mon Sep 17 00:00:00 2001 From: zy69guqi <richard.angersbach@fau.de> Date: Thu, 6 Mar 2025 17:47:51 +0100 Subject: [PATCH 1/9] Add composer for "extern C" prefix --- src/pystencilssfg/composer/basic_composer.py | 8 +++++++- src/pystencilssfg/emission/file_printer.py | 5 ++++- src/pystencilssfg/ir/entities.py | 6 ++++++ src/pystencilssfg/lang/expressions.py | 2 +- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/pystencilssfg/composer/basic_composer.py b/src/pystencilssfg/composer/basic_composer.py index 31337a6..9e58d78 100644 --- a/src/pystencilssfg/composer/basic_composer.py +++ b/src/pystencilssfg/composer/basic_composer.py @@ -91,6 +91,7 @@ class KernelsAdder: self._cursor = cursor self._kernel_namespace = knamespace self._inline: bool = False + self._externC: bool = False self._loc: SfgNamespaceBlock | None = None def inline(self) -> KernelsAdder: @@ -98,6 +99,11 @@ class KernelsAdder: self._inline = True return self + def externC(self) -> KernelsAdder: + """Generate kernel definitions ``extern "C"`` in the header file.""" + self._externC = True + return self + def add(self, kernel: Kernel, name: str | None = None): """Adds an existing pystencils AST to this namespace. If a name is specified, the AST's function name is changed.""" @@ -116,7 +122,7 @@ class KernelsAdder: kernel.name = kernel_name khandle = SfgKernelHandle( - kernel_name, self._kernel_namespace, kernel, inline=self._inline + kernel_name, self._kernel_namespace, kernel, inline=self._inline, externC=self._externC ) self._kernel_namespace.add_kernel(khandle) diff --git a/src/pystencilssfg/emission/file_printer.py b/src/pystencilssfg/emission/file_printer.py index 648e419..d6b9296 100644 --- a/src/pystencilssfg/emission/file_printer.py +++ b/src/pystencilssfg/emission/file_printer.py @@ -84,9 +84,12 @@ class SfgFilePrinter: ) -> str: match declared_entity: case SfgKernelHandle(kernel): + func_prefix = "extern C" if declared_entity.externC else "" + func_prefix += " inline" if declared_entity.inline else "" + kernel_printer = CAstPrinter( indent_width=self._indent_width, - func_prefix="inline" if declared_entity.inline else None, + func_prefix=func_prefix, ) return kernel_printer.print_signature(kernel) + ";" diff --git a/src/pystencilssfg/ir/entities.py b/src/pystencilssfg/ir/entities.py index 0edde22..850bbde 100644 --- a/src/pystencilssfg/ir/entities.py +++ b/src/pystencilssfg/ir/entities.py @@ -147,6 +147,7 @@ class SfgKernelHandle(SfgCodeEntity): namespace: SfgKernelNamespace, kernel: Kernel, inline: bool = False, + externC: bool = False, ): super().__init__(name, namespace) @@ -154,6 +155,7 @@ class SfgKernelHandle(SfgCodeEntity): self._parameters = [SfgKernelParamVar(p) for p in kernel.parameters] self._inline: bool = inline + self._externC: bool = externC self._scalar_params: set[SfgVar] = set() self._fields: set[Field] = set() @@ -188,6 +190,10 @@ class SfgKernelHandle(SfgCodeEntity): def inline(self) -> bool: return self._inline + @property + def externC(self) -> bool: + return self._externC + class SfgKernelNamespace(SfgNamespace): """A namespace grouping together a number of kernels.""" diff --git a/src/pystencilssfg/lang/expressions.py b/src/pystencilssfg/lang/expressions.py index 135a54e..abe863a 100644 --- a/src/pystencilssfg/lang/expressions.py +++ b/src/pystencilssfg/lang/expressions.py @@ -483,7 +483,7 @@ def includes(obj: ExprLike | PsType) -> set[HeaderFile]: case PsType(): headers = set(HeaderFile.parse(h) for h in obj.required_headers) if isinstance(obj, PsIntegerType): - headers.add(HeaderFile.parse("<cstdint>")) + headers.add(HeaderFile.parse("<cstdint>")) # TODO: switch for stdint.h return headers case SfgVar(_, dtype): -- GitLab From e1a88a201076bb1999f4ec74b505335225aaa561 Mon Sep 17 00:00:00 2001 From: zy69guqi <richard.angersbach@fau.de> Date: Mon, 10 Mar 2025 16:02:33 +0100 Subject: [PATCH 2/9] Remove extern C from kernelhandles, add EXTERNC macro, introduce c_interfacing config option --- src/pystencilssfg/composer/basic_composer.py | 17 ++++++++++------- src/pystencilssfg/config.py | 6 ++++++ src/pystencilssfg/context.py | 7 +++++++ src/pystencilssfg/emission/file_printer.py | 8 ++++---- src/pystencilssfg/generator.py | 12 ++++++++++++ src/pystencilssfg/ir/entities.py | 9 +++------ 6 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/pystencilssfg/composer/basic_composer.py b/src/pystencilssfg/composer/basic_composer.py index 9e58d78..9a870d9 100644 --- a/src/pystencilssfg/composer/basic_composer.py +++ b/src/pystencilssfg/composer/basic_composer.py @@ -91,7 +91,6 @@ class KernelsAdder: self._cursor = cursor self._kernel_namespace = knamespace self._inline: bool = False - self._externC: bool = False self._loc: SfgNamespaceBlock | None = None def inline(self) -> KernelsAdder: @@ -99,11 +98,6 @@ class KernelsAdder: self._inline = True return self - def externC(self) -> KernelsAdder: - """Generate kernel definitions ``extern "C"`` in the header file.""" - self._externC = True - return self - def add(self, kernel: Kernel, name: str | None = None): """Adds an existing pystencils AST to this namespace. If a name is specified, the AST's function name is changed.""" @@ -122,7 +116,7 @@ class KernelsAdder: kernel.name = kernel_name khandle = SfgKernelHandle( - kernel_name, self._kernel_namespace, kernel, inline=self._inline, externC=self._externC + kernel_name, self._kernel_namespace, kernel, inline=self._inline ) self._kernel_namespace.add_kernel(khandle) @@ -389,6 +383,8 @@ class SfgBasicComposer(SfgIComposer): if self._ctx.impl_file is None: seq.inline() + if self._ctx.c_interfacing: + seq.externC() return seq @@ -678,6 +674,7 @@ class SfgFunctionSequencerBase: # Qualifiers self._inline: bool = False + self._externC: bool = False self._constexpr: bool = False # Attributes @@ -704,6 +701,11 @@ class SfgFunctionSequencerBase: self._inline = True return self + def externC(self): + """Mark this function as ``extern "C"``.""" + self._externC = True + return self + def constexpr(self): """Mark this function as ``constexpr``.""" self._constexpr = True @@ -727,6 +729,7 @@ class SfgFunctionSequencer(SfgFunctionSequencerBase): tree, return_type=self._return_type, inline=self._inline, + externC=self._externC, constexpr=self._constexpr, attributes=self._attributes, required_params=self._params, diff --git a/src/pystencilssfg/config.py b/src/pystencilssfg/config.py index 34d2f27..44aaf51 100644 --- a/src/pystencilssfg/config.py +++ b/src/pystencilssfg/config.py @@ -123,6 +123,12 @@ class SfgConfig(ConfigBase): This will cause all definitions to be generated ``inline``. """ + c_interfacing: BasicOption[bool] = BasicOption(False) + """If set to `True`, generates header files compatible for interfacing with C. + + This will cause all definitions to be generated ``extern "C"``. + """ + outer_namespace: BasicOption[str | _GlobalNamespace] = BasicOption(GLOBAL_NAMESPACE) """The outermost namespace in the generated file. May be a valid C++ nested namespace qualifier (like ``a::b::c``) or `GLOBAL_NAMESPACE` if no outer namespace should be generated. diff --git a/src/pystencilssfg/context.py b/src/pystencilssfg/context.py index 1622a1e..6d76b7e 100644 --- a/src/pystencilssfg/context.py +++ b/src/pystencilssfg/context.py @@ -21,6 +21,7 @@ class SfgContext: self, header_file: SfgSourceFile, impl_file: SfgSourceFile | None, + c_interfacing: bool, namespace: str | None = None, codestyle: CodeStyle | None = None, argv: Sequence[str] | None = None, @@ -29,6 +30,8 @@ class SfgContext: self._argv = argv self._project_info = project_info + self._c_interfacing = c_interfacing + self._outer_namespace = namespace self._inner_namespace: str | None = None @@ -77,6 +80,10 @@ class SfgContext: def header_file(self) -> SfgSourceFile: return self._header_file + @property + def c_interfacing(self) -> bool: + return self._c_interfacing + @property def impl_file(self) -> SfgSourceFile | None: return self._impl_file diff --git a/src/pystencilssfg/emission/file_printer.py b/src/pystencilssfg/emission/file_printer.py index d6b9296..74ec3a2 100644 --- a/src/pystencilssfg/emission/file_printer.py +++ b/src/pystencilssfg/emission/file_printer.py @@ -84,12 +84,9 @@ class SfgFilePrinter: ) -> str: match declared_entity: case SfgKernelHandle(kernel): - func_prefix = "extern C" if declared_entity.externC else "" - func_prefix += " inline" if declared_entity.inline else "" - kernel_printer = CAstPrinter( indent_width=self._indent_width, - func_prefix=func_prefix, + func_prefix="inline" if declared_entity.inline else "", ) return kernel_printer.print_signature(kernel) + ";" @@ -195,6 +192,9 @@ class SfgFilePrinter: if func.inline and not inclass: code += "inline " + if isinstance(func, SfgFunction) and func.externC and not inclass: + code += "EXTERNC " + if isinstance(func, SfgMethod) and inclass: if func.static: code += "static " diff --git a/src/pystencilssfg/generator.py b/src/pystencilssfg/generator.py index c314d67..5110fcf 100644 --- a/src/pystencilssfg/generator.py +++ b/src/pystencilssfg/generator.py @@ -78,6 +78,7 @@ class SourceFileGenerator: config.override(sfg_config) self._header_only: bool = config.get_option("header_only") + self._c_interfacing: bool = config.get_option("c_interfacing") self._output_dir: Path = config.get_option("output_directory") output_files = config._get_output_files(basename) @@ -102,6 +103,16 @@ class SourceFileGenerator: # TODO: Find a way to not hard-code the restrict qualifier in pystencils self._header_file.elements.append("#define RESTRICT __restrict__") + # TODO: Find a way to not hard-code the 'extern" C"' qualifier in pystencils + self._header_file.elements.append( + """#ifdef __cplusplus\n + #define EXTERNC extern \"C\"\n + #else\n + #define EXTERNC \n + #endif\n + """ + ) + outer_namespace: str | _GlobalNamespace = config.get_option("outer_namespace") namespace: str | None @@ -113,6 +124,7 @@ class SourceFileGenerator: self._context = SfgContext( self._header_file, self._impl_file, + self._c_interfacing, namespace, config.codestyle, argv=script_args, diff --git a/src/pystencilssfg/ir/entities.py b/src/pystencilssfg/ir/entities.py index 850bbde..e20b2b7 100644 --- a/src/pystencilssfg/ir/entities.py +++ b/src/pystencilssfg/ir/entities.py @@ -147,7 +147,6 @@ class SfgKernelHandle(SfgCodeEntity): namespace: SfgKernelNamespace, kernel: Kernel, inline: bool = False, - externC: bool = False, ): super().__init__(name, namespace) @@ -155,7 +154,6 @@ class SfgKernelHandle(SfgCodeEntity): self._parameters = [SfgKernelParamVar(p) for p in kernel.parameters] self._inline: bool = inline - self._externC: bool = externC self._scalar_params: set[SfgVar] = set() self._fields: set[Field] = set() @@ -190,10 +188,6 @@ class SfgKernelHandle(SfgCodeEntity): def inline(self) -> bool: return self._inline - @property - def externC(self) -> bool: - return self._externC - class SfgKernelNamespace(SfgNamespace): """A namespace grouping together a number of kernels.""" @@ -228,6 +222,7 @@ class CommonFunctionProperties: parameters: tuple[SfgVar, ...] return_type: PsType inline: bool + externC: bool constexpr: bool attributes: Sequence[str] @@ -264,6 +259,7 @@ class SfgFunction(SfgCodeEntity, CommonFunctionProperties): tree: SfgCallTreeNode, return_type: PsType = void, inline: bool = False, + externC: bool = False, constexpr: bool = False, attributes: Sequence[str] = (), required_params: Sequence[SfgVar] | None = None, @@ -278,6 +274,7 @@ class SfgFunction(SfgCodeEntity, CommonFunctionProperties): parameters, return_type, inline, + externC, constexpr, attributes, ) -- GitLab From 86c4669913988222ef2a167b0afc386a742e50cc Mon Sep 17 00:00:00 2001 From: zy69guqi <richard.angersbach@fau.de> Date: Mon, 10 Mar 2025 16:11:54 +0100 Subject: [PATCH 3/9] Remove option to mark individual functions as extern C --- src/pystencilssfg/composer/basic_composer.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/pystencilssfg/composer/basic_composer.py b/src/pystencilssfg/composer/basic_composer.py index 9a870d9..75c023b 100644 --- a/src/pystencilssfg/composer/basic_composer.py +++ b/src/pystencilssfg/composer/basic_composer.py @@ -384,7 +384,7 @@ class SfgBasicComposer(SfgIComposer): if self._ctx.impl_file is None: seq.inline() if self._ctx.c_interfacing: - seq.externC() + seq._externC = True return seq @@ -701,11 +701,6 @@ class SfgFunctionSequencerBase: self._inline = True return self - def externC(self): - """Mark this function as ``extern "C"``.""" - self._externC = True - return self - def constexpr(self): """Mark this function as ``constexpr``.""" self._constexpr = True -- GitLab From fddcf9dc2596ed1decd3b7e4fe2dc1e1dd444311 Mon Sep 17 00:00:00 2001 From: zy69guqi <richard.angersbach@fau.de> Date: Wed, 12 Mar 2025 14:52:21 +0100 Subject: [PATCH 4/9] Implement hybrid include mechanism for C interfacing --- src/pystencilssfg/composer/basic_composer.py | 5 +++++ src/pystencilssfg/emission/file_printer.py | 21 +++++++++++++++++++ src/pystencilssfg/generator.py | 22 +++++++++++++++++--- src/pystencilssfg/ir/syntax.py | 11 ++++++++++ src/pystencilssfg/lang/expressions.py | 2 +- 5 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/pystencilssfg/composer/basic_composer.py b/src/pystencilssfg/composer/basic_composer.py index 75c023b..d598970 100644 --- a/src/pystencilssfg/composer/basic_composer.py +++ b/src/pystencilssfg/composer/basic_composer.py @@ -15,6 +15,7 @@ from pystencils import ( ) from pystencils.codegen import Kernel from pystencils.types import create_type, UserTypeSpec, PsType +from pystencilssfg.ir import SfgSourceFileType from ..context import SfgContext, SfgCursor from .custom import CustomGenerator @@ -716,6 +717,10 @@ class SfgFunctionSequencer(SfgFunctionSequencerBase): """Sequencer for constructing functions.""" def __call__(self, *args: SequencerArg) -> None: + # check if header is in HYBRID mode for c_interfacing enabled + if self._cursor.context.c_interfacing: + assert isinstance(self._cursor.context.header_file.file_type, SfgSourceFileType.HYBRID_HEADER) + """Populate the function body""" tree = make_sequence(*args) func = SfgFunction( diff --git a/src/pystencilssfg/emission/file_printer.py b/src/pystencilssfg/emission/file_printer.py index 74ec3a2..b2f6692 100644 --- a/src/pystencilssfg/emission/file_printer.py +++ b/src/pystencilssfg/emission/file_printer.py @@ -42,7 +42,28 @@ class SfgFilePrinter: if file.file_type == SfgSourceFileType.HEADER: code += "#pragma once\n\n" + includes = "" for header in file.includes: + incl = str(header) if header.system_header else f'"{str(header)}"' + includes += f"#include {incl}\n" + + if file.file_type == SfgSourceFileType.HYBRID_HEADER: + hybrid_includes = "" + for header in file.includes: + incl = str(header) if header.system_header else f'"{str(header)}"' + hybrid_includes += f"#include {incl}\n" + + # include different headers and wrap around guard distinguishing C++/C compilations + code += f""" + #ifdef __cplusplus\n + {includes} + #else\n + {hybrid_includes} + #endif\n""" + else: + code += includes + + for header in file.hybrid_includes: incl = str(header) if header.system_header else f'"{str(header)}"' code += f"#include {incl}\n" diff --git a/src/pystencilssfg/generator.py b/src/pystencilssfg/generator.py index 5110fcf..1eb30ce 100644 --- a/src/pystencilssfg/generator.py +++ b/src/pystencilssfg/generator.py @@ -85,9 +85,9 @@ class SourceFileGenerator: from .ir import SfgSourceFile, SfgSourceFileType - self._header_file = SfgSourceFile( - output_files[0].name, SfgSourceFileType.HEADER - ) + header_type = SfgSourceFileType.HYBRID_HEADER \ + if self._c_interfacing else SfgSourceFileType.HEADER + self._header_file = SfgSourceFile(output_files[0].name, header_type) self._impl_file: SfgSourceFile | None if self._header_only: @@ -164,6 +164,22 @@ class SourceFileGenerator: ) self._header_file.includes.sort(key=self._include_sort_key) + if self._c_interfacing: + # from: https://en.cppreference.com/w/cpp/header + c_compatibility_headers = [ + "<cassert", "<cctype>", "<cerrno>", "<cfenv>", "<cfloat>", + "<cinttypes>", "<climits>", "<clocale>", "<cmath>", + "<csetjmp>", "<csignal>", "<cstdarg>", "<cstddef>", "<cstdint>", + "<cstdio>", "<cstdlib>", "<cstring>", "<ctime>", "<cuchar>", + "<cwchar>", "<cwctype>" + ] + + for inc in self._header_file.includes: + if inc.system_header and inc.__str__() in c_compatibility_headers: + c_header = inc.__str__().replace("<c", "<") + self._header_file.hybrid_includes += HeaderFile( + c_header, system_header=True) + if self._impl_file is not None: impl_includes = collect_includes(self._impl_file) # If some header is already included by the generated header file, do not duplicate that inclusion diff --git a/src/pystencilssfg/ir/syntax.py b/src/pystencilssfg/ir/syntax.py index cdbd4c2..71d7fd0 100644 --- a/src/pystencilssfg/ir/syntax.py +++ b/src/pystencilssfg/ir/syntax.py @@ -181,6 +181,7 @@ SfgNamespaceElement = ( class SfgSourceFileType(Enum): HEADER = auto() + HYBRID_HEADER = auto() TRANSLATION_UNIT = auto() @@ -200,6 +201,7 @@ class SfgSourceFile: self._file_type: SfgSourceFileType = file_type self._prelude: str | None = prelude self._includes: list[HeaderFile] = [] + self._hybrid_includes: list[HeaderFile] = [] self._elements: list[SfgNamespaceElement] = [] @property @@ -230,6 +232,15 @@ class SfgSourceFile: def includes(self, incl: Iterable[HeaderFile]): self._includes = list(incl) + @property + def hybrid_includes(self) -> list[HeaderFile]: + """Sequence of header files to be included at the top of this file""" + return self._hybrid_includes + + @hybrid_includes.setter + def hybrid_includes(self, incl: Iterable[HeaderFile]): + self._hybrid_includes = list(incl) + @property def elements(self) -> list[SfgNamespaceElement]: """Sequence of source elements comprising the body of this file""" diff --git a/src/pystencilssfg/lang/expressions.py b/src/pystencilssfg/lang/expressions.py index abe863a..135a54e 100644 --- a/src/pystencilssfg/lang/expressions.py +++ b/src/pystencilssfg/lang/expressions.py @@ -483,7 +483,7 @@ def includes(obj: ExprLike | PsType) -> set[HeaderFile]: case PsType(): headers = set(HeaderFile.parse(h) for h in obj.required_headers) if isinstance(obj, PsIntegerType): - headers.add(HeaderFile.parse("<cstdint>")) # TODO: switch for stdint.h + headers.add(HeaderFile.parse("<cstdint>")) return headers case SfgVar(_, dtype): -- GitLab From 41d1276c057cc3f747c8cdcab2f6ac114b2abcca Mon Sep 17 00:00:00 2001 From: zy69guqi <richard.angersbach@fau.de> Date: Wed, 12 Mar 2025 16:10:42 +0100 Subject: [PATCH 5/9] Fix lint --- src/pystencilssfg/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pystencilssfg/config.py b/src/pystencilssfg/config.py index 44aaf51..7ced262 100644 --- a/src/pystencilssfg/config.py +++ b/src/pystencilssfg/config.py @@ -125,7 +125,7 @@ class SfgConfig(ConfigBase): c_interfacing: BasicOption[bool] = BasicOption(False) """If set to `True`, generates header files compatible for interfacing with C. - + This will cause all definitions to be generated ``extern "C"``. """ -- GitLab From 34012b361ae2800ce55e56ed3065f34e4deacf63 Mon Sep 17 00:00:00 2001 From: zy69guqi <richard.angersbach@fau.de> Date: Wed, 12 Mar 2025 16:12:31 +0100 Subject: [PATCH 6/9] Fix typcheck --- src/pystencilssfg/composer/basic_composer.py | 2 +- src/pystencilssfg/generator.py | 4 ++-- src/pystencilssfg/ir/entities.py | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/pystencilssfg/composer/basic_composer.py b/src/pystencilssfg/composer/basic_composer.py index d598970..cdf425d 100644 --- a/src/pystencilssfg/composer/basic_composer.py +++ b/src/pystencilssfg/composer/basic_composer.py @@ -719,7 +719,7 @@ class SfgFunctionSequencer(SfgFunctionSequencerBase): def __call__(self, *args: SequencerArg) -> None: # check if header is in HYBRID mode for c_interfacing enabled if self._cursor.context.c_interfacing: - assert isinstance(self._cursor.context.header_file.file_type, SfgSourceFileType.HYBRID_HEADER) + assert self._cursor.context.header_file.file_type == SfgSourceFileType.HYBRID_HEADER """Populate the function body""" tree = make_sequence(*args) diff --git a/src/pystencilssfg/generator.py b/src/pystencilssfg/generator.py index 1eb30ce..b3916f4 100644 --- a/src/pystencilssfg/generator.py +++ b/src/pystencilssfg/generator.py @@ -177,8 +177,8 @@ class SourceFileGenerator: for inc in self._header_file.includes: if inc.system_header and inc.__str__() in c_compatibility_headers: c_header = inc.__str__().replace("<c", "<") - self._header_file.hybrid_includes += HeaderFile( - c_header, system_header=True) + self._header_file.hybrid_includes += [HeaderFile( + c_header, system_header=True)] if self._impl_file is not None: impl_includes = collect_includes(self._impl_file) diff --git a/src/pystencilssfg/ir/entities.py b/src/pystencilssfg/ir/entities.py index e20b2b7..41f5daa 100644 --- a/src/pystencilssfg/ir/entities.py +++ b/src/pystencilssfg/ir/entities.py @@ -383,6 +383,8 @@ class SfgMethod(SfgClassMember, CommonFunctionProperties): self._virtual = virtual self._override = override + externC = False + parameters = self.collect_params(tree, required_params) CommonFunctionProperties.__init__( @@ -391,6 +393,7 @@ class SfgMethod(SfgClassMember, CommonFunctionProperties): parameters, return_type, inline, + externC, constexpr, attributes, ) -- GitLab From 0c03bf061766c2f3faf5f990d77763199e5d6837 Mon Sep 17 00:00:00 2001 From: zy69guqi <richard.angersbach@fau.de> Date: Wed, 12 Mar 2025 16:51:55 +0100 Subject: [PATCH 7/9] Fix tests --- src/pystencilssfg/context.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pystencilssfg/context.py b/src/pystencilssfg/context.py index 6d76b7e..4815650 100644 --- a/src/pystencilssfg/context.py +++ b/src/pystencilssfg/context.py @@ -21,7 +21,7 @@ class SfgContext: self, header_file: SfgSourceFile, impl_file: SfgSourceFile | None, - c_interfacing: bool, + c_interfacing: bool = False, namespace: str | None = None, codestyle: CodeStyle | None = None, argv: Sequence[str] | None = None, -- GitLab From b5645502823c72194418002e43f9eff9f868f773 Mon Sep 17 00:00:00 2001 From: zy69guqi <richard.angersbach@fau.de> Date: Wed, 12 Mar 2025 17:02:04 +0100 Subject: [PATCH 8/9] Fix emission of hybrid header includes --- src/pystencilssfg/emission/file_printer.py | 6 +----- src/pystencilssfg/generator.py | 5 ++--- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/pystencilssfg/emission/file_printer.py b/src/pystencilssfg/emission/file_printer.py index b2f6692..ed1c073 100644 --- a/src/pystencilssfg/emission/file_printer.py +++ b/src/pystencilssfg/emission/file_printer.py @@ -49,7 +49,7 @@ class SfgFilePrinter: if file.file_type == SfgSourceFileType.HYBRID_HEADER: hybrid_includes = "" - for header in file.includes: + for header in file.hybrid_includes: incl = str(header) if header.system_header else f'"{str(header)}"' hybrid_includes += f"#include {incl}\n" @@ -63,10 +63,6 @@ class SfgFilePrinter: else: code += includes - for header in file.hybrid_includes: - incl = str(header) if header.system_header else f'"{str(header)}"' - code += f"#include {incl}\n" - if file.includes: code += "\n" diff --git a/src/pystencilssfg/generator.py b/src/pystencilssfg/generator.py index b3916f4..8f720b4 100644 --- a/src/pystencilssfg/generator.py +++ b/src/pystencilssfg/generator.py @@ -176,9 +176,8 @@ class SourceFileGenerator: for inc in self._header_file.includes: if inc.system_header and inc.__str__() in c_compatibility_headers: - c_header = inc.__str__().replace("<c", "<") - self._header_file.hybrid_includes += [HeaderFile( - c_header, system_header=True)] + c_header = inc.__str__().replace("<c", "<").replace(">", ".h>") + self._header_file.hybrid_includes += [HeaderFile.parse(c_header)] if self._impl_file is not None: impl_includes = collect_includes(self._impl_file) -- GitLab From 3912add0d1ff9b99704dc3e4e55288c30dc92407 Mon Sep 17 00:00:00 2001 From: zy69guqi <richard.angersbach@fau.de> Date: Wed, 12 Mar 2025 17:03:36 +0100 Subject: [PATCH 9/9] Revert unnecessary change --- src/pystencilssfg/emission/file_printer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pystencilssfg/emission/file_printer.py b/src/pystencilssfg/emission/file_printer.py index ed1c073..ebd89cc 100644 --- a/src/pystencilssfg/emission/file_printer.py +++ b/src/pystencilssfg/emission/file_printer.py @@ -103,7 +103,7 @@ class SfgFilePrinter: case SfgKernelHandle(kernel): kernel_printer = CAstPrinter( indent_width=self._indent_width, - func_prefix="inline" if declared_entity.inline else "", + func_prefix="inline" if declared_entity.inline else None, ) return kernel_printer.print_signature(kernel) + ";" -- GitLab