#pragma once #include #include "error.h" /* * INI-style config file loader with schema-driven defaults and validation. * * File format: * [section] * key = value ; inline comments with ; or # * key = value # same * * Whitespace around keys and values is stripped. * Commas in values are treated as whitespace (useful for flag lists). */ typedef enum Config_Type { CONFIG_STRING, /* arbitrary string value */ CONFIG_UINT16, /* decimal integer, fits u16 */ CONFIG_UINT32, /* decimal integer, fits u32 */ CONFIG_FLAGS, /* space/comma-separated tokens mapped via a flag table */ } Config_Type; /* * One entry in a flags table — maps a token string to a bitmask value. * The table must be terminated by an entry with token = NULL. */ struct Config_Flag_Def { const char *token; uint32_t value; }; /* * One entry in a config schema. * Provide a table of these terminated by an entry with section = NULL. */ struct Config_Def { const char *section; const char *key; Config_Type type; const char *default_val; /* string form of the default */ const struct Config_Flag_Def *flags; /* required when type = CONFIG_FLAGS */ }; struct Config; /* * Load a config file and validate it against the schema. * Keys present in the file but absent from the schema are ignored. * Keys absent from the file are filled with their schema default. */ struct App_Error config_load(struct Config **out, const char *path, const struct Config_Def *schema); /* * Load defaults only (no file). Useful when no config file is present * but you still want schema-driven defaults. */ struct App_Error config_defaults(struct Config **out, const struct Config_Def *schema); void config_free(struct Config *cfg); /* * Typed getters. Return the effective value (file value or default). * Caller must not free the returned string — it is owned by the Config. */ const char *config_get_str (struct Config *cfg, const char *section, const char *key); uint16_t config_get_u16 (struct Config *cfg, const char *section, const char *key); uint32_t config_get_u32 (struct Config *cfg, const char *section, const char *key); uint32_t config_get_flags(struct Config *cfg, const char *section, const char *key); /* Print all effective key/value pairs to stdout — useful for diagnostics. */ void config_dump(struct Config *cfg);