diff --git a/interfaces/sourcegen/sourcegen/clib/_CLibSourceGenerator.py b/interfaces/sourcegen/sourcegen/clib/_CLibSourceGenerator.py index bf8bd6563d..020bf5406d 100644 --- a/interfaces/sourcegen/sourcegen/clib/_CLibSourceGenerator.py +++ b/interfaces/sourcegen/sourcegen/clib/_CLibSourceGenerator.py @@ -60,7 +60,7 @@ def param(item: Param): def _handle_crosswalk(self, what: str, crosswalk: dict, derived: list[str]) -> str: """Crosswalk for object handle.""" cabinet = None - classes = self._config.cabinets + derived + classes = list(self._config.includes.keys()) + derived for base in classes: ret_type = what.replace(f"<{base}>", "") if ret_type in crosswalk: @@ -107,7 +107,7 @@ def _ret_crosswalk( return returns, buffer if "shared_ptr" in what: - # check for crosswalk with object from cabinets + # check for crosswalk with object from includes handle = self._handle_crosswalk( what, self._config.ret_type_crosswalk, derived) returns = Param( @@ -425,7 +425,8 @@ def _write_header(self, header: HeaderFile) -> None: def _write_implementation(self, header: HeaderFile) -> None: """Parse header specification and generate implementation file.""" - loader = Environment(loader=BaseLoader) + loader = Environment(loader=BaseLoader, trim_blocks=True, lstrip_blocks=True) + filename = header.output_name(suffix=".cpp", auto="3") _logger.info(f" scaffolding {filename.name!r}") @@ -438,11 +439,17 @@ def _write_implementation(self, header: HeaderFile) -> None: implementations.append( template.render(declaration=c_func.declaration(),body=body)) other |= bases + implementations = "\n\n".join(implementations) + str_utils = "copyString" in implementations + + includes = [] + for obj in [header.cabinet] + list(other): + includes += self._config.includes[obj] template = loader.from_string(self._templates["clib-source-file"]) output = template.render( - name=filename.stem, source_entries=implementations, - base=header.cabinet, other=other) + name=filename.stem, implementations=implementations, + includes=includes, base=header.cabinet, other=other, str_utils=str_utils) if self._out_dir: out = Path(self._out_dir) / "src" / filename.name diff --git a/interfaces/sourcegen/sourcegen/clib/_Config.py b/interfaces/sourcegen/sourcegen/clib/_Config.py index 7798f507aa..dec6e4d386 100644 --- a/interfaces/sourcegen/sourcegen/clib/_Config.py +++ b/interfaces/sourcegen/sourcegen/clib/_Config.py @@ -35,9 +35,9 @@ class Config: "const vector>&": 'int[]', } - cabinets: list[str] + includes: dict[str,list[str]] @classmethod - def from_parsed(cls, *, cabinets=None) -> 'Config': + def from_parsed(cls, *, includes=None) -> 'Config': """Ensure that configurations are correct.""" - return cls(cabinets or []) + return cls(includes or {}) diff --git a/interfaces/sourcegen/sourcegen/clib/config.yaml b/interfaces/sourcegen/sourcegen/clib/config.yaml index d9d760383a..bc0153ae20 100644 --- a/interfaces/sourcegen/sourcegen/clib/config.yaml +++ b/interfaces/sourcegen/sourcegen/clib/config.yaml @@ -10,10 +10,15 @@ ignore_files: [] ignore_funcs: ctsoln_auto.yaml: [newInterface, adjacent] -# Cabinets holding objects -cabinets: -- Solution -- ThermoPhase -- Kinetics -- Transport -- Func1 +# Cabinets with associated includes +includes: + Solution: + - cantera/base/Solution.h + ThermoPhase: + - cantera/thermo/ThermoFactory.h + Kinetics: + - cantera/kinetics/KineticsFactory.h + Transport: + - cantera/transport/TransportFactory.h + Func1: + - cantera/numerics/Func1Factory.h diff --git a/interfaces/sourcegen/sourcegen/clib/templates.yaml b/interfaces/sourcegen/sourcegen/clib/templates.yaml index 9d820d2892..c32dc0229c 100644 --- a/interfaces/sourcegen/sourcegen/clib/templates.yaml +++ b/interfaces/sourcegen/sourcegen/clib/templates.yaml @@ -226,20 +226,29 @@ clib-source-file: |- // This file is part of Cantera. See License.txt in the top-level directory or // at https://cantera.org/license.txt for license and copyright information. - #include "../include/clib3_defs.h" - #include "../include/{{ name }}.h" + #include "cantera/clib_experimental/{{ name }}.h" + #include "cantera/clib_experimental/clib3_defs.h" + #include "../clib/Cabinet.h" + + {% if str_utils %} + #include "cantera/base/stringUtils.h" + {% endif %} + {% for entry in includes %} + #include "{{ entry }}" + {% endfor %} using namespace Cantera; typedef Cabinet<{{ base }}> {{ base }}Cabinet; template<> {{ base }}Cabinet* {{ base }}Cabinet::s_storage = 0; {% if other %} - {% for entry in other -%} + + {% for entry in other %} typedef Cabinet<{{ entry }}> {{ entry }}Cabinet; // initialized elsewhere - {% endfor -%} + {% endfor %} {% endif %} + extern "C" { - {% for entry in source_entries %} - {{ entry | indent(4) }} - {% endfor %} + + {{ implementations | indent(4) }} }