# Configuration and TOML

MontaukOS provides a small header-only C++ API for reading and writing TOML configuration files from userspace. Include `<montauk/config.h>` for file-backed configuration and `<montauk/toml.h>` for the in-memory TOML document model.

## Configuration locations

System configuration is stored in `0:/config`. The API accepts a name without the `.toml` extension:

    0:/config/desktop.toml
    0:/config/network.toml

Per-user configuration is stored below the user directory:

    0:/users/<username>/config/<name>.toml

## Loading and saving

    #include <montauk/config.h>

    auto doc = montauk::config::load("desktop");
    const char* theme = doc.get_string("appearance.theme", "light");

    montauk::config::set_string(&doc, "appearance.theme", "dark");
    int result = montauk::config::save("desktop", &doc);

    doc.destroy();

`load()` returns an initialized empty document if the file does not exist. `save()` creates the configuration directory and returns `0` on success or a negative value on error. Saving rewrites the whole file.

### System configuration API

    toml::Doc config::load(const char* name);
    int       config::save(const char* name, toml::Doc* doc);
    int       config::remove(const char* name);

### Per-user configuration API

    toml::Doc config::load_user(const char* username, const char* name);
    int       config::save_user(const char* username,
                                const char* name,
                                toml::Doc* doc);

For example:

    auto doc = montauk::config::load_user("alice", "desktop");
    bool clock24 = doc.get_bool("display.clock_24h", false);

    montauk::config::set_bool(&doc, "display.clock_24h", true);
    montauk::config::save_user("alice", "desktop", &doc);
    doc.destroy();

## Reading values

Keys may use dotted paths corresponding to TOML tables:

    [server]
    host = "pool.ntp.org"
    port = 123
    enabled = true

    const char* host = doc.get_string("server.host", "localhost");
    int64_t port = doc.get_int("server.port", 80);
    bool enabled = doc.get_bool("server.enabled", false);

Typed getters return their default when the key is absent or has another type. The available value types are:

    toml::Type::String
    toml::Type::Int
    toml::Type::Bool
    toml::Type::Array
    toml::Type::Table

Arrays and tables are returned as `toml::Value*`. Their children are available through `value->array.items` and `value->array.count`:

    auto* names = doc.get_array("server.names");
    if (names) {
        for (int i = 0; i < names->array.count; ++i) {
            auto* item = names->array.items[i];
            if (item->type == montauk::toml::Type::String)
                montauk::print(item->str);
        }
    }

## Modifying documents

    void config::set_string(toml::Doc* doc,
                            const char* key, const char* value);
    void config::set_int(toml::Doc* doc,
                         const char* key, int64_t value);
    void config::set_bool(toml::Doc* doc,
                          const char* key, bool value);
    bool config::unset(toml::Doc* doc, const char* key);

The setters overwrite an existing value or append a new one. The `unset()` return value is `true` when a matching key was removed.

## Parsing and serialization

Use `toml::parse()` when TOML is already available in memory:

    const char* text =
        "[server]\n"
        "port = 8080\n"
        "enabled = true\n";

    auto doc = montauk::toml::parse(text);
    int64_t port = doc.get_int("server.port");
    doc.destroy();

A document can be serialized to newly allocated TOML text:

    char* text = montauk::config::serialize(&doc);
    // Use text...
    montauk::mfree(text);

Serialization produces normalized TOML and does not preserve comments or the original formatting.

## Memory ownership

`toml::Doc` owns its parsed values and strings. Every document returned by `load()`, `load_user()`, or `toml::parse()` must eventually be released with `doc.destroy()`.

When constructing a document manually, initialize it before using the mutation helpers:

    montauk::toml::Doc doc;
    doc.init();
    montauk::config::set_bool(&doc, "enabled", true);
    montauk::config::save("example", &doc);
    doc.destroy();

## Supported TOML features

The userspace parser supports strings, literal and multiline strings, integers (including hexadecimal, octal, and binary forms), booleans, arrays, tables, inline tables, dotted keys, and comments.

There are no typed float or datetime accessors. Callers should also treat configuration names and usernames as safe path components, since they are used to construct filesystem paths.

Back to Application Programming Manual