AxlConfig — Configuration

See AxlSys — System Utilities for an overview of all utility modules including the configuration framework.

Header: <axl/axl-config.h>

API Reference

Defines

AXL_CFG_BOOL

“true”/”false”/”1”/”0”

axl-config.h:

Live object property bag. Declare typed options once in a descriptor table; mutate at runtime via axl_config_set; retrieve via typed getters. Supports auto-apply into a target struct via offsetof, dynamic-key callbacks (for namespaces like “header.*”), and parent inheritance for cascading defaults.

For command-line argument parsing, use axl_args_run from <axl/axl-args.h>. AxlConfig used to do that too; the CLI surface was retired once AxlArgs landed.

AXL_CFG_INT

signed integer

AXL_CFG_UINT

unsigned integer

AXL_CFG_STRING

arbitrary string

AXL_CFG_MULTI

repeatable string (array)

Typedefs

typedef struct AxlConfig AxlConfig
typedef int (*AxlConfigApplyFunc)(void *target, const char *key, const char *value)

Callback invoked when an option is set.

Called BEFORE descriptor lookup — handles dynamic keys (e.g. “header.*”) that aren’t in the descriptor table.

Return values:

  • 0: accepted, proceed with descriptor lookup + auto-apply

  • 1: handled by callback (value stored, auto-apply skipped)

  • -1: rejected (set returns -1)

Functions

AxlConfig *axl_config_new(const AxlConfigDesc *descs, AxlConfigApplyFunc apply_fn, void *target)

Create a config object from descriptors.

Defaults from descriptors are applied immediately. If target is non-NULL and descriptors have offset/field_size, defaults are written into the target struct.

Parameters:
  • descs – descriptor table (borrowed, not copied)

  • apply_fn – change callback (NULL for auto-only)

  • target – opaque pointer for apply_fn + auto-apply

Returns:

new config, or NULL on allocation failure.

void axl_config_free(AxlConfig *cfg)

Free a config object. NULL-safe.

Parameters:
  • cfg – config to free

int axl_config_set(AxlConfig *cfg, const char *key, const char *value)

Set a config option.

Validates type, calls apply_fn (if set), then auto-applies via offsetof (if descriptor has offset). Stores the string value internally for later retrieval.

Parameters:
  • cfg – config

  • key – option key

  • value – value as string

Returns:

AXL_OK on success, AXL_ERR on unknown key, type mismatch, or callback rejection.

int axl_config_setv(AxlConfig *cfg, ...)

Set multiple options in one call.

Accepts key/value string pairs terminated by NULL. Stops at the first failure and returns -1.

axl_config_setv(cfg,
    "port", "8080",
    "verbose", "true",
    NULL);
Parameters:
  • cfg – config

Param :

key, value pairs terminated by NULL

Returns:

AXL_OK on success, AXL_ERR on first error.

const char *axl_config_get(AxlConfig *cfg, const char *key)

Get an option value as string.

Parameters:
  • cfg – config

  • key – option key

Returns:

stored value, default, or NULL if unknown key.

bool axl_config_get_bool(AxlConfig *cfg, const char *key)

Get a boolean option.

Accepts “true”/”1”/”yes” as true, everything else as false.

Parameters:
  • cfg – config

  • key – option key

int64_t axl_config_get_int(AxlConfig *cfg, const char *key)

Get a signed integer option.

Parameters:
  • cfg – config

  • key – option key

Returns:

parsed value, or 0 if unset or not a number.

uint64_t axl_config_get_uint(AxlConfig *cfg, const char *key)

Get an unsigned integer option.

Parameters:
  • cfg – config

  • key – option key

Returns:

parsed value, or 0 if unset or not a number.

size_t axl_config_get_multi_count(AxlConfig *cfg, const char *key)

Get the count of values for a MULTI option.

Parameters:
  • cfg – config

  • key – option key

const char *axl_config_get_multi(AxlConfig *cfg, const char *key, size_t index)

Get a value from a MULTI option by index.

Parameters:
  • cfg – config

  • key – option key

  • index – 0-based index

Returns:

value string, or NULL if index out of range.

int axl_config_to_string(AxlConfig *cfg, char *out, size_t out_size)

Serialize all set values to a URL query string.

Walks every value currently set in the config (single and MULTI), emits key=value&... with both key and value URL-percent-encoded. Defaults that haven’t been overridden are NOT emitted (the parsing side will re-apply defaults from its own descriptor table).

Parameters:
  • cfg – config to serialize

  • out – output buffer

  • out_size – capacity of out in bytes

Returns:

AXL_OK on success, AXL_ERR on out_size overflow or NULL args. On overflow out is left in an unspecified state.

int axl_config_target_to_string(const AxlConfigDesc *descs, const void *target, char *out, size_t out_size)

Serialize a target struct directly via its descriptor table.

Walks descs, reads each option’s current value from target via offsetof, formats it, URL-encodes the pair, appends to out. Independent of any AxlConfig instance — useful for cross-binary marshalling where the consumer populates target through CLI parsing (axl_args_*) without ever creating an AxlConfig.

Skips MULTI options (offset/field_size are 0 for those by convention; serializing requires walking an opaque list the descriptor doesn’t reach). Skips entries with field_size == 0.

Parameters:
  • descs – descriptor table (terminated by {0})

  • target – struct to read fields from

  • out – output buffer

  • out_size – capacity of out in bytes

Returns:

AXL_OK on success, AXL_ERR on overflow or NULL args.

int axl_config_from_string(AxlConfig *cfg, const char *in)

Parse a URL query string into the config.

Splits on ‘&’ into pairs, splits each pair on the first ‘=’, URL-decodes both halves, calls axl_config_set on each. A value with no ‘=’ is treated as the empty string. Repeated keys are fed to axl_config_set in order (which appends to MULTI options and overwrites scalar ones).

Stops at the first axl_config_set failure and returns AXL_ERR — callers that need partial-parse-on-error semantics should split the string themselves and call axl_config_set in a loop.

Parameters:
  • cfg – config to populate

  • in – URL query string (NUL-terminated)

Returns:

AXL_OK on success, AXL_ERR on NULL args, malformed encoding, or any axl_config_set failure.

size_t axl_config_descs_net(AxlConfigDesc *out, size_t cap, uint32_t kinds, size_t base_offset)

Emit the standard NIC / static-IP / port / listen-IP descriptors into a consumer-owned accumulator.

kinds is a bitmask of AxlNetOptKind values (see <axl/axl-net-opts.h>) selecting which subset to emit; the AXL_NET_OPT_CLIENT / _SERVER presets are the common cases.

Each emitted descriptor’s offset is added to base_offset — the offsetof of the consumer’s embedded AxlNetOpts sub-struct in its own options type — so AxlConfig’s auto-apply lands the parsed value in the right place. field_size is set from the corresponding AxlNetOpts member, including the uint16_t port (so AXL_CFG_UINT auto-apply doesn’t write past the field).

Writes consecutively into out starting at index 0. Does NOT append a terminating zeroed entry — callers compose with axl_config_descs_append and terminate the combined table themselves.

Parameters:
  • out – accumulator (caller-owned, written at [0..])

  • cap – capacity of out in entries

  • kinds – bitmask of AxlNetOptKind

  • base_offset – offsetof(consumer-Opts, AxlNetOpts-sub-struct)

Returns:

number of descriptors written. Returns 0 (no partial write) and logs a warning via log domain "net" if cap is too small or out is NULL.

size_t axl_config_descs_net_static(AxlConfigDesc *out, size_t cap, size_t base_offset)

Emit the static-IP / DNS / hostname (IP4Config2 policy) descriptors into a consumer-owned accumulator.

The policy-group sibling of axl_config_descs_net: it injects the descriptors an on-box ifconfig UI hand-authors today — mode (a "dhcp"/"static" two-choice picker), ip, netmask, gateway, dns, dns2, hostname — bound to a consumer-embedded AxlNetStaticOpts (see <axl/axl-net-opts.h>). Each emitted descriptor’s offset is added to base_offset (the offsetof of the embedded AxlNetStaticOpts), so AxlConfig auto-apply lands the parsed value in the right field. Unlike axl_config_descs_net there is no kinds selector — the policy form is taken as a whole.

Writes 7 descriptors consecutively into out starting at index 0. Does NOT append a terminating zeroed entry — compose with axl_config_descs_append and terminate the combined table yourself.

Parameters:
  • out – accumulator (caller-owned, written at [0..])

  • cap – capacity of out in entries (>= 7)

  • base_offset – offsetof(consumer-Opts, AxlNetStaticOpts-sub-struct)

Returns:

number of descriptors written (7). Returns 0 (no partial write) and logs a warning via log domain "net" if cap is too small or out is NULL.

size_t axl_config_descs_append(AxlConfigDesc *out, size_t cap, const AxlConfigDesc *src)

Copy a consumer-owned NULL-terminated descriptor fragment onto the end of an accumulator.

Walks src until the first zeroed entry (key == NULL), copying each preceding descriptor into out. The terminator is NOT copied — the caller writes the final zeroed entry once, after all fragments have been appended.

Parameters:
  • out – accumulator (write position)

  • cap – remaining capacity in entries

  • src – NULL-terminated fragment to copy

Returns:

number of descriptors copied. Returns 0 (no partial write) if out or src is NULL; an under-capacity request also returns 0 and logs a warning via log domain "config".

void axl_config_set_parent(AxlConfig *cfg, AxlConfig *parent)

Set a parent config for cascading defaults.

When axl_config_get finds no value for a key, it falls through to the parent. Useful for per-connection configs that inherit server-level defaults.

Parameters:
  • cfg – child config

  • parent – parent config (borrowed, not owned)

struct AxlConfigDesc
#include <axl-config.h>

Option descriptor. Define a static array terminated by {0}.

AxlConfig itself only consumes key, type, default_value, offset, and field_size — the parser doesn’t care whether an option also has a CLI short flag or a closed set of allowed values. The remaining fields exist so consumers can use a single descriptor table to drive both AxlConfig auto-apply AND a synthesized AxlArgDesc[] CLI surface (see axl_service_main, which walks this table to build its argv parser). The CLI-only fields are ignored by AxlConfig parsing.

Public Members

const char *key

dotted name (e.g. “timeout.ms”)

int type

AXL_CFG_BOOL, _INT, _UINT, _STRING, _MULTI.

const char *default_value

default as string (NULL = no default)

const char *description

help text (logged in debug mode)

size_t offset

offsetof into target struct

size_t field_size

sizeof the target field (0 = no auto-apply)

char short_name

CLI short flag (single char), 0 = none. Used by axl_service_main when synthesizing its AxlArgDesc[]; AxlConfig parsing ignores.

const char *const *choices

NULL-terminated allowed-value list for STRING-typed options. When set, the axl_service_main synthesizer emits AXL_ARG_CHOICE instead of AXL_ARG_STRING so the CLI parser validates and the &#8212;help text lists the values. NULL = no restriction. Trailing position keeps the struct’s existing zero-init layout compatible.

int64_t min

(numeric INT/UINT) inclusive lower bound, 0 = none (each of min/max independently). Like short_name / choices, AxlConfig parsing IGNORES this; it exists so the axl_service_main synthesizer can set the matching AxlArgDesc bound (CLI range validation + &#8212;help), and so a downstream settings-UI builder can size a spinner. Signed; cast to AxlArgDesc’s uint64_t with the same convention (a UINT bound must still fit in int64_t — >= 2^63 is unrepresentable here). Trailing position keeps existing tables’ zero-init valid.

int64_t max

(numeric INT/UINT) inclusive upper bound, 0 = none. See min.

AxlConfigFile — free-form key=value map

The open-vocabulary counterpart to descriptor-bound AxlConfig: parse a key=value text file (# comments, blank lines, trimmed values) into a flat string map with typed getters that fall back to a caller default for any missing key. Use this when keys are not known at compile time (a softbmc.cfg-style file where modules invent their own prefix.key names); use AxlConfig when the option set is fixed and typed.

Header: <axl/axl-config-file.h>

Typedefs

typedef struct AxlConfigFile AxlConfigFile

A free-form key=value string map. Opaque; create with axl_config_file_load / _new, free with _free.

axl-config-file.h:

Free-form key=value config-file map. Parses a text file into a flat string map and serves typed getters that fall back to a caller-supplied default for any missing (or unparseable) key.

This is the open-vocabulary counterpart to <axl/axl-config.h> AxlConfig, which is descriptor-bound — AxlConfig validates each key against a fixed AxlConfigDesc[], types it, auto-applies it via offsetof, and REJECTS unknown keys. Use AxlConfig for a known, typed option set (e.g. a server’s tunables). Use AxlConfigFile when the keys are not known at compile time — a softbmc.cfg-style file where modules invent their own prefix.key names and read them with a runtime default.

File format:

comments start with ‘#’; blank lines are ignored

mode=handoff boot_timeout=30 ec.poll_interval_ms=5000 # the dot is just a naming convention

ASCII, case-sensitive keys/values. The value is everything after the first = to end of line, trimmed of surrounding whitespace; there is no quoting. The map is flat — a prefix.key convention is the caller’s, not the loader’s.

Functions

AxlConfigFile *axl_config_file_load(const char *path)

Load a key=value file into a flat string map.

Reads path via <axl/axl-fs.h> and parses it: lines are split on the first =, the key and value are trimmed of surrounding whitespace, # comment lines and blank lines are skipped, and a line with no = is ignored. A later assignment of the same key overrides an earlier one.

A missing or unreadable file is NOT an error — it yields an empty map, so every lookup returns its caller default. NULL is returned only on out of memory (or a NULL path).

Parameters:
  • path – file path (e.g. “FS0:\softbmc.cfg”)

Returns:

new map (possibly empty), or NULL on OOM / NULL path.

AxlConfigFile *axl_config_file_new(void)

Create an empty map (set-only / all-defaults).

Returns:

new empty map, or NULL on OOM.

void axl_config_file_free(AxlConfigFile *cf)

Free a config-file map. NULL-safe.

Parameters:
  • cf – map to free

const char *axl_config_file_get(AxlConfigFile *cf, const char *key, const char *def)

Get a string value, or def if the key is absent.

The returned pointer is owned by the map and valid until the key is overwritten (axl_config_file_set) or the map is freed. def is returned as-is (the map does not copy it).

Parameters:
  • cf – map (NULL → returns def)

  • key – key to look up

  • def – default if absent (may be NULL)

Returns:

the stored value, or def if key is not present.

uint64_t axl_config_file_get_uint(AxlConfigFile *cf, const char *key, uint64_t def)

Get a value parsed as an unsigned integer, or def.

Accepts decimal or 0x-prefixed hex. Parsing is strict: the ENTIRE value must be the number — a trailing unit or inline comment (e.g. 30s, 5 # note) does NOT parse and yields def. Returns def when the key is absent OR its value does not parse as a non-negative integer.

Parameters:
  • cf – map (NULL → returns def)

  • key – key to look up

  • def – default if absent / unparseable

Returns:

the parsed value, or def.

int64_t axl_config_file_get_int(AxlConfigFile *cf, const char *key, int64_t def)

Get a value parsed as a signed integer, or def.

Accepts an optional leading -/+, then decimal or 0x hex. Parsing is strict (the whole value must be the number; trailing characters yield def). Returns def when the key is absent OR its value does not parse.

Parameters:
  • cf – map (NULL → returns def)

  • key – key to look up

  • def – default if absent / unparseable

Returns:

the parsed value, or def.

bool axl_config_file_get_bool(AxlConfigFile *cf, const char *key, bool def)

Get a value parsed as a boolean, or def.

Accepts (case-insensitive) true/false, yes/no, on/off, 1/0. Returns def when the key is absent OR its value is none of these.

Parameters:
  • cf – map (NULL → returns def)

  • key – key to look up

  • def – default if absent / unparseable

Returns:

the parsed boolean, or def.

int axl_config_file_set(AxlConfigFile *cf, const char *key, const char *value)

Set (create or update) a key’s value.

Both key and value are copied into the map. An empty-string value is allowed; setting a key that exists overwrites it.

Parameters:
  • cf – map

  • key – key to set

  • value – value to store (copied; “” allowed)

Returns:

AXL_OK on success, AXL_ERR on bad arguments or OOM.

int axl_config_file_save(AxlConfigFile *cf, const char *path)

Serialize the map as key=value text and write it to path.

Writes one key=value\n line per entry via <axl/axl-fs.h>. Entry order is unspecified (the map is unordered). Round-trips through axl_config_file_load. Comments are not preserved (the load step discards them).

Parameters:
  • cf – map

  • path – destination file path

Returns:

AXL_OK on success, AXL_ERR on bad arguments, OOM, or write failure.