montaukos.org - docs - add docs page for TOML config API
This commit is contained in:
@@ -0,0 +1,236 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="MontaukOS userspace configuration and TOML API">
|
||||
<title>Configuration and TOML - MontaukOS</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Open Sans', Arial, sans-serif;
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
padding: 1em;
|
||||
line-height: 1.5;
|
||||
display: flex;
|
||||
gap: 2em;
|
||||
}
|
||||
p { margin: 0 0 0.75em; }
|
||||
h2 { margin: 1.25em 0 0.5em; }
|
||||
h3 { margin: 1em 0 0.35em; }
|
||||
.sidebar { width: 160px; flex-shrink: 0; }
|
||||
.sidebar ul { list-style: none; padding: 0; }
|
||||
.sidebar li { margin: 0.5em 0; }
|
||||
.sidebar a { color: #0066CC; text-decoration: none; font-weight: 600; }
|
||||
.sidebar a:hover { color: #004499; text-decoration: underline; }
|
||||
.sidebar .current { color: #004499; }
|
||||
.sidebar hr { border: none; border-top: 1px solid #999; margin: 0.75em 0; }
|
||||
.main { flex: 1; min-width: 0; }
|
||||
a { color: #0000EE; }
|
||||
a:visited { color: #0066CC; }
|
||||
hr { border-style: solid; border-width: 1px 0 0 0; border-color: #999; }
|
||||
.center { text-align: center; }
|
||||
pre {
|
||||
background: #f4f4f4;
|
||||
border: 1px solid #ccc;
|
||||
padding: 0.75em;
|
||||
overflow-x: auto;
|
||||
}
|
||||
code { font-family: monospace; }
|
||||
@media (max-width: 700px) {
|
||||
body { flex-direction: column; gap: 1em; padding: 1em 0.75em; }
|
||||
.sidebar { width: auto; }
|
||||
.sidebar ul { display: flex; flex-wrap: wrap; gap: 0 1em; }
|
||||
.sidebar hr { width: 100%; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="sidebar">
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a></li>
|
||||
<li><a href="../../downloads.html">Downloads</a></li>
|
||||
<li><a href="../index.html">Documentation</a></li>
|
||||
<li><a href="https://git.montaukos.org/daniel/MontaukOS/issues">Issue tracker</a></li>
|
||||
<li><a href="https://git.montaukos.org/daniel/MontaukOS">Git</a></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<ul>
|
||||
<li><a href="index.html">Application Programming Manual</a></li>
|
||||
<li><a href="config.html" class="current">Configuration and TOML</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
<div class="center">
|
||||
<h1>Configuration and TOML</h1>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>MontaukOS provides a small header-only C++ API for reading and writing
|
||||
TOML configuration files from userspace. Include
|
||||
<code><montauk/config.h></code> for file-backed configuration and
|
||||
<code><montauk/toml.h></code> for the in-memory TOML document model.</p>
|
||||
|
||||
<h2>Configuration locations</h2>
|
||||
|
||||
<p>System configuration is stored in <code>0:/config</code>. The API accepts a
|
||||
name without the <code>.toml</code> extension:</p>
|
||||
|
||||
<pre><code>0:/config/desktop.toml
|
||||
0:/config/network.toml</code></pre>
|
||||
|
||||
<p>Per-user configuration is stored below the user directory:</p>
|
||||
|
||||
<pre><code>0:/users/<username>/config/<name>.toml</code></pre>
|
||||
|
||||
<h2>Loading and saving</h2>
|
||||
|
||||
<pre><code>#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();</code></pre>
|
||||
|
||||
<p><code>load()</code> returns an initialized empty document if the file does
|
||||
not exist. <code>save()</code> creates the configuration directory and returns
|
||||
<code>0</code> on success or a negative value on error. Saving rewrites the
|
||||
whole file.</p>
|
||||
|
||||
<h3>System configuration API</h3>
|
||||
|
||||
<pre><code>toml::Doc config::load(const char* name);
|
||||
int config::save(const char* name, toml::Doc* doc);
|
||||
int config::remove(const char* name);</code></pre>
|
||||
|
||||
<h3>Per-user configuration API</h3>
|
||||
|
||||
<pre><code>toml::Doc config::load_user(const char* username, const char* name);
|
||||
int config::save_user(const char* username,
|
||||
const char* name,
|
||||
toml::Doc* doc);</code></pre>
|
||||
|
||||
<p>For example:</p>
|
||||
|
||||
<pre><code>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();</code></pre>
|
||||
|
||||
<h2>Reading values</h2>
|
||||
|
||||
<p>Keys may use dotted paths corresponding to TOML tables:</p>
|
||||
|
||||
<pre><code>[server]
|
||||
host = "pool.ntp.org"
|
||||
port = 123
|
||||
enabled = true</code></pre>
|
||||
|
||||
<pre><code>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);</code></pre>
|
||||
|
||||
<p>Typed getters return their default when the key is absent or has another
|
||||
type. The available value types are:</p>
|
||||
|
||||
<pre><code>toml::Type::String
|
||||
toml::Type::Int
|
||||
toml::Type::Bool
|
||||
toml::Type::Array
|
||||
toml::Type::Table</code></pre>
|
||||
|
||||
<p>Arrays and tables are returned as <code>toml::Value*</code>. Their children
|
||||
are available through <code>value->array.items</code> and
|
||||
<code>value->array.count</code>:</p>
|
||||
|
||||
<pre><code>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);
|
||||
}
|
||||
}</code></pre>
|
||||
|
||||
<h2>Modifying documents</h2>
|
||||
|
||||
<pre><code>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);</code></pre>
|
||||
|
||||
<p>The setters overwrite an existing value or append a new one. The
|
||||
<code>unset()</code> return value is <code>true</code> when a matching key was
|
||||
removed.</p>
|
||||
|
||||
<h2>Parsing and serialization</h2>
|
||||
|
||||
<p>Use <code>toml::parse()</code> when TOML is already available in memory:</p>
|
||||
|
||||
<pre><code>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();</code></pre>
|
||||
|
||||
<p>A document can be serialized to newly allocated TOML text:</p>
|
||||
|
||||
<pre><code>char* text = montauk::config::serialize(&doc);
|
||||
// Use text...
|
||||
montauk::mfree(text);</code></pre>
|
||||
|
||||
<p>Serialization produces normalized TOML and does not preserve comments or
|
||||
the original formatting.</p>
|
||||
|
||||
<h2>Memory ownership</h2>
|
||||
|
||||
<p><code>toml::Doc</code> owns its parsed values and strings. Every document
|
||||
returned by <code>load()</code>, <code>load_user()</code>, or
|
||||
<code>toml::parse()</code> must eventually be released with
|
||||
<code>doc.destroy()</code>.</p>
|
||||
|
||||
<p>When constructing a document manually, initialize it before using the
|
||||
mutation helpers:</p>
|
||||
|
||||
<pre><code>montauk::toml::Doc doc;
|
||||
doc.init();
|
||||
montauk::config::set_bool(&doc, "enabled", true);
|
||||
montauk::config::save("example", &doc);
|
||||
doc.destroy();</code></pre>
|
||||
|
||||
<h2>Supported TOML features</h2>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="center">
|
||||
<a href="index.html">Back to Application Programming Manual</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -140,6 +140,9 @@ MontaukOS documentation is reorganised, and does not have any content yet.</p>
|
||||
<li>
|
||||
<a href="api.html">Montauk API</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="config.html">Configuration and TOML</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="libc.html">C library</a>
|
||||
</li>
|
||||
|
||||
Reference in New Issue
Block a user