Settings
Settings is a small named set of values a program reads at startup and
writes back when it changes — the NSUserDefaults-shaped hole in the library.
The store itself is memory; persistence is the platform’s own settings store
or a text file, so the same source works on a Mac, on Windows, in a browser and
on a machine with no filesystem at all.
#import "Settings.xc"Overview
Section titled “Overview”Three constructors, each a superset of the one before:
Settings.memory() | in memory only. Every target, including those with no filesystem. |
Settings.open(path) | memory plus a file: read once here, rewritten whole by save. |
Settings.standard(name) | the platform’s own settings store (macOS and iOS preferences, the Windows registry, a browser’s localStorage), else open at the conventional per-user path, else memory. |
Values are read with get (a String*, or null) or the typed
getInt / getBool, each of which takes a fallback so a
missing key needs no test. Writes go through set and its typed
siblings; remove drops one key.
The store keeps insertion order, so serialise writes what was
set, in the order it was set, and saving an unchanged store rewrites the same
bytes.
The file format
Section titled “The file format”Text, one setting per line:
# a commentalpha = onebeta=two#at the start of a line begins a comment; blank lines are ignored.- A line with no
=is not a setting and is dropped. - Both sides of the
=are trimmed. - A value cannot contain a newline; a key cannot contain
=or#.
loadText reads that format and serialise writes
it. Comments and blank lines are not preserved across a load-then-save: the
file is a settings file, not a document.
Where standard keeps the values
Section titled “Where standard keeps the values”When $XCC_SETTINGS_DIR is set and non-empty, standard keeps
its values in the text file $XCC_SETTINGS_DIR/<name>.conf on every platform;
a test or a script uses it to say exactly where the settings go. Otherwise the
store is the platform’s:
| Platform | Store | To look at it |
|---|---|---|
| macOS, iOS | the user’s preferences, domain <name> (CFPreferences, what NSUserDefaults uses) | defaults read <name> |
| Windows | the registry key HKEY_CURRENT_USER\Software\<name>, one REG_SZ value per setting | reg query HKCU\Software\<name> |
| a browser (wasm32) | the page’s localStorage item <name>, a JSON object of strings | JSON.parse(localStorage.getItem(name)) |
| Linux, Android | the text file $XDG_CONFIG_HOME/<name>.conf, or $HOME/.config/<name>.conf when that is not set | cat ~/.config/<name>.conf |
| arm9, m68k | the same text file when the target gives a home directory ($HOME); else a memory store | the file |
| xt6502 | none: a memory store, whose save returns false | — |
path is 0 for the three native stores and names the file for the
others. On macOS a reverse-DNS name such as com.example.demo is the
convention, as it is for any app’s preferences.
The platform stores hold only text, as Settings does. A value some other
program put there as a number or a boolean (defaults write <name> k -int 3,
a registry DWORD) reads back in decimal or as true/false. A value with
no text form (an array, binary data) is not read, and save leaves it
where it is.
Topics
Section titled “Topics”Construction · memory · open · standard
Reading · get · has · getInt · getBool · count · keys
Writing · set · setInt · setBool · remove · removeAll
Persistence · path · serialise · loadText · save · reload
Construction
Section titled “Construction”memory
Section titled “memory”static Settings* memory(void)A store with no backing file. It works everywhere, and save reports
false because there is nowhere to write.
static Settings* open(String* path)A store backed by path. An existing file is read now; a missing one is an
empty store, not an error — the first save creates it. A null or
empty path is the same as memory.
standard
Section titled “standard”static Settings* standard(String* name)The settings of an app called name, kept where this platform keeps them: see
Where standard keeps the values. The rest
of the API is the same whichever store is underneath.
Settings* s = Settings.standard(String.withCString("demo"));Reading
Section titled “Reading”String* get(String* key)String* get(String* key, String* fallback)The value stored under key. The one-argument form returns 0 when the key
is absent; the two-argument form returns fallback instead, so a default needs
no test at the call site.
bool has(String* key)true when key is present, whatever its value.
getInt
Section titled “getInt”i32 getInt(String* key, i32 fallback)The value parsed as a decimal integer. Returns fallback when the key is absent
or the text is not an integer (a leading - or + is accepted). The stored text
is not changed by reading it.
getBool
Section titled “getBool”bool getBool(String* key, bool fallback)The value as a boolean: true for true, yes or 1, false for false,
no or 0, and fallback for anything else or an absent key.
u32 count(void)How many settings are stored.
Array* keys(void)A fresh Array of the keys, in insertion order.
Writing
Section titled “Writing”void set(String* key, String* value)Stores value under key, replacing any previous value in place — the key
keeps its original position. A null value stores the empty string; a null or
empty key stores nothing.
setInt
Section titled “setInt”void setInt(String* key, i32 value)set with the value written out as a decimal.
setBool
Section titled “setBool”void setBool(String* key, bool value)set with the value written as true or false.
remove
Section titled “remove”void remove(String* key)Drops the setting, if it is there.
removeAll
Section titled “removeAll”void removeAll(void)Empties the store. The backing file is untouched until the next
save.
Persistence
Section titled “Persistence”String* path(void)The backing file, or 0 for a memory-only store or one kept in the platform’s own
store (see standard).
serialise
Section titled “serialise”String* serialise(void)The whole store as file text — one key = value per line, in insertion order.
This is exactly what save writes.
loadText
Section titled “loadText”void loadText(String* text)Replaces the store with what text says, in the format described in
The file format. 0 empties the store.
bool save(void)Writes the store out. A store from standard kept in the
platform’s own store is written there: a key removed since it was read is
removed there too, and the change is flushed. A file-backed store rewrites its
file, first creating any directory above it that is missing, so the first save
to ~/.config/<name>.conf works on a machine that has never had one. false
when there is nowhere to write — a memory-only store, or a target with no
filesystem — so a caller can say the settings did not persist instead of
believing they did.
reload
Section titled “reload”bool reload(void)Re-reads the platform store or the backing file. The store is the truth: a
file that has since gone leaves the store empty rather than stale. false when
there is nothing to read from.