# Configuration

`config.h`/`config.cpp` implement `readConfig()`, which reads one `vacaskrc.toml` configuration file and applies its contents - include/module search path additions and paths to external tools - to the running simulator. It is a small, one-function unit: all the state it populates lives elsewhere ([`Simulator`](main.md) path lists, [`Platform`](platform.md) tool paths).

## `readConfig()`

```
bool readConfig(std::ifstream& input, const std::string& filename, Status& s=Status::ignore);
```

Parses `input` as TOML (via `toml++`) and reads two top-level tables, both optional:

- **`[Paths]`** - `include_path_prefix`/`include_path_suffix` and `module_path_prefix`/`module_path_suffix`, each a string array. Prefix arrays are prepended and suffix arrays are appended to `Simulator`'s include and module search paths (`Simulator::prependIncludePath()`/`appendIncludePath()`/`prependModulePath()`/`appendModulePath()`), so a config file processed later in the search order still inserts its own entries in the intended position relative to whatever is already there.
- **`[Binaries]`** - `openvaf` (string) and `openvaf_args` (string array) set the OpenVAF compiler path and its extra arguments (`Platform::setOpenVaf()`/`setOpenVafArgs()`); `python` (string) sets the Python interpreter path (`Platform::setPythonExecutable()`). See [Platform Entry Support](platform.md).

A TOML parse failure (`toml::parse_error`) is reported through `Status` with the file name, line, and column, and `readConfig()` returns `false`. A malformed value (e.g. a non-string entry in a path array, or a key that isn't an array where one is expected) is likewise reported and rejected without applying any of that table's other entries whose parsing was already in flight when the check failed - `readConfig()` returns as soon as `getString()`/`getStringArray()` reports an error.

## Environment variable substitution

Every string value read from the file - individual strings and array entries alike - is passed through `replaceEnvVariables()`, which rewrites each `$(NAME)` occurrence in place with the value of the `NAME` environment variable (or the empty string if it is not set). This lets a config file reference machine-specific locations, e.g. `openvaf = "$(HOME)/bin/openvaf-r"`, without hardcoding them.

## Where config files come from

`readConfig()` itself has no notion of "the" config file - it just reads whatever `std::ifstream` it is given. [`main()`](main.md) is what decides which files exist and in what order to read them (system, user, local, and an input-file-adjacent `.vacaskrc.toml`, plus command-line overrides), calling `readConfig()` once per candidate file that actually opens, each contributing its settings on top of what earlier files already set.
