Skip to content

Commit 235a4ba

Browse files
committed
Read compiler definitions when importing config
Dealing with the raw TOML is error-prone, so when reading from file the TOML is converted into objects with defined members. The from_toml() conversion routines in each object are also used to encapsulate logic specific to handling custom actions, etc. Signed-off-by: John Pennycook <john.pennycook@intel.com>
1 parent ab2b802 commit 235a4ba

File tree

1 file changed

+88
-1
lines changed

1 file changed

+88
-1
lines changed

codebasin/config.py

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,21 @@
99
import collections
1010
import logging
1111
import os
12+
import pkgutil
1213
import re
1314
import string
14-
from dataclasses import asdict, dataclass
15+
import tomllib
16+
from dataclasses import asdict, dataclass, field
17+
from pathlib import Path
18+
from typing import Self
1519

1620
from codebasin import CompilationDatabase, util
1721

1822
log = logging.getLogger(__name__)
1923

2024

2125
_importcfg = None
26+
_compilers = None
2227

2328

2429
def _parse_compiler_args(argv: list[str]):
@@ -151,6 +156,88 @@ def __call__(
151156
dest.extend(matches)
152157

153158

159+
@dataclass
160+
class _CompilerMode:
161+
name: str
162+
defines: list[str] = field(default_factory=list)
163+
include_paths: list[str] = field(default_factory=list)
164+
include_files: list[str] = field(default_factory=list)
165+
166+
@classmethod
167+
def from_toml(cls, toml: object) -> Self:
168+
return _CompilerMode(**toml)
169+
170+
171+
@dataclass
172+
class _CompilerPass:
173+
name: str
174+
defines: list[str] = field(default_factory=list)
175+
include_paths: list[str] = field(default_factory=list)
176+
include_files: list[str] = field(default_factory=list)
177+
modes: list[str] = field(default_factory=list)
178+
179+
@classmethod
180+
def from_toml(cls, toml: object) -> Self:
181+
return _CompilerPass(**toml)
182+
183+
184+
@dataclass
185+
class _Compiler:
186+
alias_of: str | None = None
187+
options: list[str] = field(default_factory=list)
188+
parser: list[dict] = field(default_factory=list)
189+
modes: dict[str, _CompilerMode] = field(default_factory=dict)
190+
passes: dict[str, _CompilerPass] = field(default_factory=dict)
191+
192+
@classmethod
193+
def from_toml(cls, toml: object) -> Self:
194+
kwargs = toml.copy()
195+
if "parser" in kwargs:
196+
for option in kwargs["parser"]:
197+
if option["action"] == "store_split":
198+
option["action"] = _StoreSplitAction
199+
if option["action"] == "extend_match":
200+
option["action"] = _ExtendMatchAction
201+
if "modes" in toml:
202+
kwargs["modes"] = {
203+
m["name"]: _CompilerMode.from_toml(m) for m in kwargs["modes"]
204+
}
205+
if "passes" in toml:
206+
kwargs["passes"] = {
207+
p["name"]: _CompilerPass.from_toml(p) for p in kwargs["passes"]
208+
}
209+
return _Compiler(**kwargs)
210+
211+
212+
def _load_compilers():
213+
"""
214+
Load the configuration from the following files:
215+
- ${PACKAGE}/compilers/*.toml
216+
"""
217+
global _compilers
218+
_compilers = {}
219+
220+
# Load the package-provided configuration files.
221+
for compiler in ["clang", "gnu", "intel", "nvidia"]:
222+
filename = str((Path("compilers") / compiler).with_suffix(".toml"))
223+
toml = tomllib.loads(
224+
pkgutil.get_data("codebasin", filename).decode(),
225+
)
226+
try:
227+
util._validate_toml(toml, "cbiconfig")
228+
except ValueError as e:
229+
log.error(str(e))
230+
return
231+
232+
for name, definition in toml["compiler"].items():
233+
_compilers[name] = _Compiler.from_toml(definition)
234+
235+
236+
# Load the compiler configuration when this module is imported.
237+
if not _compilers:
238+
_load_compilers()
239+
240+
154241
@dataclass
155242
class PreprocessorConfiguration:
156243
"""

0 commit comments

Comments
 (0)