#ifndef INI_CONFIG_H #define INI_CONFIG_H #include #include #include #include #ifdef __cplusplus extern "C" { #endif /** * Struct for transformer functions used for properly loading and saving the config item's value. */ typedef struct { /** * Function that formats the value from memory to a value that is write-friendly to the config file. */ void* serialize; /** * Function that formats the value from file to a value that is read-friendly to memory. */ void* deserialize; } INI_ConfigTransformer; // TODO: should we unify this with INI_ConfigType? struct INI_ConfigItem; /** * Function for loading a config item value from file to memory. */ typedef void INI_ConfigTypeLoad(struct INI_ConfigItem*, const char*); /** * Result enum for saving config items. */ typedef enum { /** * Result returned when saving a config item was not successful. */ INI_CONFIG_SAVE_ITEM_ERROR = -1, /** * Result returned when saving a config item was successful. */ INI_CONFIG_SAVE_ITEM_OK, } INI_ConfigSaveItemResult; /** * Function for saving a config item value from memory to file. */ typedef INI_ConfigSaveItemResult INI_ConfigTypeSave(struct INI_ConfigItem*, const char*); /** * Function for retrieving a config item value from the command-line to memory. */ typedef void INI_ConfigTypeOverride(struct INI_ConfigItem*, uint8_t, const char* []); /** * Struct for the config item type. */ typedef struct { /** * Size of the corresponding in-memory value of the config item. */ size_t size; /** * Load function. * @see INI_ConfigTypeLoad */ INI_ConfigTypeLoad* load; /** * Save function. * @see INI_ConfigTypeSave */ INI_ConfigTypeSave* save; /** * Override function. * @see INI_ConfigTypeOverride */ INI_ConfigTypeOverride* override; } INI_ConfigType; /** * Struct for the config item, which occuptes a single key in a specific section of the config INI file. */ typedef struct INI_ConfigItem { /** * Type of the config item. */ INI_ConfigType type; /** * Section where this config item can be found. */ const char* section; /** * Key where this config item value is serialized and stored. */ const char* key; /** * Command-line option for overriding this config item's value. */ const char* cmdline_option; // TODO: should we extract commandline parsing logic? /** * Default value of the config item, when the value could not be read from the config file. */ const void* default_value; /** * Validator function for the config item's value. */ void* validator; /** * Transformer functions. * @see INI_ConfigTransformer */ INI_ConfigTransformer transformer; /** * The memory address where the config item value will reside. This property should allow storing the amount of butes * specified under `type.size`. */ void* dest; } INI_ConfigItem; /** * Retrieves the value from a command-line option. * @return The string value from the command-line option. */ const char* INI_ConfigGetCommandlineOption(uint8_t, const char*[], const char*); /** * Result enum for initializing config items. */ typedef enum { /** * Result returned when initializing all config items was not successful. */ INI_CONFIG_INITIALIZE_RESULT_ERROR = -1, /** * Result returned when initializing all config items was successful. */ INI_CONFIG_INITIALIZE_RESULT_OK, /** * Result returned when initializing some config items was successful. */ INI_CONFIG_INITIALIZE_RESULT_WARNING } INI_ConfigInitializeResult; /** * Syncs the config file to memory. This includes the loading of the items from the config file. * @return Result of the initialization. */ INI_ConfigInitializeResult INI_ConfigInitialize(INI_ConfigItem[], const char*, uint8_t, const char*[]); typedef int32_t INI_ConfigSaveResult; /** * Saves the contents of the memory to the config file. * @return */ INI_ConfigSaveResult INI_ConfigSave(INI_ConfigItem[], const char*); #ifdef __cplusplus }; #endif #define INI_CONFIG_DECLARE_TYPE(ID) \ INI_ConfigTypeLoad INI_ConfigLoad##ID; \ INI_ConfigTypeSave INI_ConfigSave##ID; \ INI_ConfigTypeOverride INI_ConfigOverride##ID /** * Null transformer. */ #define INI_CONFIG_TRANSFORMER_NONE (INI_ConfigTransformer) { \ .serialize = NULL, \ .deserialize = NULL, \ } /** * Null item. Use this to signify the end of the config item list. */ #define INI_CONFIG_ITEM_NULL (INI_ConfigItem) { \ (INI_ConfigType) { \ .size = 0, \ .load = NULL, \ .save = NULL, \ .override = NULL, \ }, \ NULL, \ NULL, \ NULL, \ NULL, \ NULL, \ INI_CONFIG_TRANSFORMER_NONE, \ NULL, \ } #endif