[sourcegen] Add logger implementation

This commit is contained in:
Ingmar Schoegl 2025-02-03 10:13:38 -06:00
parent 68e2d0ff4e
commit de6502750a
7 changed files with 70 additions and 16 deletions

View File

@ -32,6 +32,8 @@
enum LogLevel { INFO, WARN , ERROR };
//! Represents a callback that is invoked to produce log output.
//! TODO: Only needed in the main CLib library. Should be moved once the
//! traditional CLib is removed.
typedef void
(*LogCallback)(enum LogLevel logLevel, const char* category, const char* message);

View File

@ -12,6 +12,8 @@ recipes:
- name: getGitCommit
implements: gitCommit # inconsistent API (preexisting)
- name: getCanteraError
- name: setLogWriter
- name: setLogCallback
- name: addCanteraDirectory
implements: addDirectory # inconsistent API (preexisting)
- name: getDataDirectories
@ -42,5 +44,3 @@ recipes:
implements: epsilon_0
- name: clearStorage
- name: resetStorage
- name: setLogWriter
- name: setLogCallback

View File

@ -166,18 +166,20 @@ class CFunc(Func):
if len(lines) == 1:
return cls(*func, brief, None, "", "", [])
returns = ""
args = []
doc_args = {p.name: p for p in func.arglist}
for ix, line in enumerate(lines[:-1]):
line = line.strip().lstrip("*").strip()
if ix == 1 and not brief:
brief = line
elif line.startswith("@param"):
# assume that variables are documented in order
arg = func.arglist[len(args)].long_str()
args.append(Param.from_str(arg, line))
# match parameter name
keys = [k for k in doc_args.keys() if line.split()[1] == k]
if len(keys) == 1:
key = keys[0]
doc_args[key] = Param.from_str(doc_args[key].long_str(), line)
elif line.startswith("@returns"):
returns = line.lstrip("@returns").strip()
args = ArgList(args)
args = ArgList(list(doc_args.values()))
return cls(func.ret_type, func.name, args, brief, None, returns, "", [])
def short_declaration(self) -> str:

View File

@ -441,7 +441,8 @@ class CLibSourceGenerator(SourceGenerator):
func_name = f"{recipe.prefix}_{recipe.name}"
reserved = ["cabinetSize", "parentHandle",
"getCanteraError", "clearStorage", "resetStorage"]
"getCanteraError", "setLogWriter", "setLogCallback",
"clearStorage", "resetStorage"]
if recipe.name in reserved:
recipe.what = "reserved"
loader = Environment(loader=BaseLoader)
@ -588,11 +589,13 @@ class CLibSourceGenerator(SourceGenerator):
annotations=self._scaffold_annotation(c_func, recipe.what)))
declarations = "\n\n".join(declarations)
preamble = self._config.preambles.get(headers.base)
guard = f"__{filename.name.upper().replace('.', '_')}__"
template = loader.from_string(self._templates["clib-header-file"])
output = template.render(
name=filename.stem, guard=guard, declarations=declarations,
prefix=headers.prefix, base=headers.base, docstring=headers.docstring)
name=filename.stem, guard=guard, preamble=preamble, prefix=headers.prefix,
declarations=declarations, base=headers.base, docstring=headers.docstring)
out = (Path(self._out_dir) /
"include" / "cantera" / "clib_experimental" / filename.name)

View File

@ -43,9 +43,13 @@ class Config:
"const vector<shared_ptr<T>>&": "int[]",
}
includes: dict[str, list[str]]
preambles: dict[str, str] #: Preamble text for each header file
includes: dict[str, list[str]] #: Include directives for each implementation file
@classmethod
def from_parsed(cls: Self, *, includes: dict[str, list[str]] | None = None) -> Self:
def from_parsed(cls: Self, *,
preambles: dict[str, str] | None = None,
includes: dict[str, list[str]] | None = None) -> Self:
"""Create dataclass while including information parsed externally."""
return cls(includes or {})
return cls(preambles or {}, includes or {})

View File

@ -8,13 +8,18 @@ ignore_files: []
# Dictionary of file names and list of functions to ignore.
# Example: ctkin_auto.yaml: [phase]
ignore_funcs:
ct_auto.yaml: [setLogWriter, setLogCallback]
ignore_funcs: {}
# Cabinets with associated includes
# Cabinets with associated preambles (headers)
preambles:
"": |-
#include "../clib/clib_defs.h"
# Cabinets with associated includes (implementation files)
includes:
"":
- cantera/base/global.h
- cantera/base/ExternalLogger.h
Solution:
- cantera/base/Solution.h
Interface:

View File

@ -53,6 +53,19 @@ clib-reserved-getCanteraError-h: |-
*/
int {{ prefix }}_getCanteraError(int bufLen, char* buf);
clib-reserved-setLogWriter-h: |-
/**
* Undocumented.
*/
int {{ prefix }}_setLogWriter(void* logger);
clib-reserved-setLogCallback-h: |-
/**
* Undocumented.
* @param writer Callback that is invoked to produce log output.
*/
int {{ prefix }}_setLogCallback(LogCallback writer);
clib-reserved-resetStorage-h: |-
/**
* Delete all objects and erase mapping.
@ -98,6 +111,10 @@ clib-header-file: |-
#ifndef {{ guard }}
#define {{ guard }}
{% if preamble %}
{{ preamble }}
{% endif %}
#ifdef __cplusplus
extern "C" {
#endif
@ -449,6 +466,27 @@ clib-reserved-getCanteraError-cpp: |-
return handleAllExceptions(-1, ERR);
}
clib-reserved-setLogWriter-cpp: |-
// reserved: setLogger
try {
Logger* logwriter = (Logger*)logger;
setLogger(logwriter);
return 0;
} catch (...) {
return handleAllExceptions(-1, ERR);
}
clib-reserved-setLogCallback-cpp: |-
// reserved: setLogger
static unique_ptr<Logger> logwriter;
try {
logwriter = make_unique<ExternalLogger>(writer);
setLogger(logwriter.get());
return 0;
} catch (...) {
return handleAllExceptions(-1, ERR);
}
clib-reserved-resetStorage-cpp: |-
// reserved: void Cabinet<T>::reset()
try {