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_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.