#include "int.h" #define INI_CONFIG_IMPLEMENT_INT_TYPE(ID, T) \ typedef bool INI_ConfigValidate##ID(T); \ \ typedef T INI_ConfigDeserialize##ID(const char*, void*); \ \ typedef void INI_ConfigSerialize##ID(T, const char[128], void*); \ \ void INI_ConfigEnsureValid##ID(INI_ConfigItem* item, T raw_value, T default_value) { \ T* dest = item->dest; \ if (item->validator) { \ INI_ConfigValidate##ID* validate = item->validator; \ if (validate(raw_value)) { \ *dest = raw_value; \ return; \ } \ *dest = default_value; \ return; \ } \ *dest = raw_value; \ } \ \ void INI_ConfigLoad##ID(INI_ConfigItem* item, const char* config_path, void* item_array) { \ static T raw_value; \ static T default_value; \ default_value = *((T*) item->default_value); \ if (item->transformer.deserialize && item->transformer.serialize) { \ INI_ConfigDeserialize##ID* deserialize = item->transformer.deserialize; \ INI_ConfigSerialize##ID* serialize = item->transformer.serialize; \ const char serialized_default_value[128]; \ if (default_value) { \ serialize(default_value, serialized_default_value, item_array); \ } \ char buffer[128]; \ ini_gets(item->section, item->key, serialized_default_value, buffer, 128, config_path); \ raw_value = deserialize(buffer, item_array); \ } else { \ raw_value = ini_getl(item->section, item->key, default_value, config_path); \ } \ INI_ConfigEnsureValid##ID(item, raw_value, default_value); \ } \ \ INI_ConfigSaveItemResult INI_ConfigSave##ID(INI_ConfigItem* item, const char* config_path, void* item_array) { \ T dest = *((T*) item->dest); \ if (item->validator) { \ INI_ConfigValidate##ID* validate = item->validator; \ if (!validate(dest)) { \ dest = *((const T*) item->default_value); \ } \ } \ \ if (item->transformer.deserialize && item->transformer.serialize) { \ INI_ConfigSerialize##ID* serialize = item->transformer.serialize; \ const char serialized_value[128]; \ serialize(dest, serialized_value, item_array); \ if (!ini_puts(item->section, item->key, serialized_value, config_path)) { \ return -1; \ } \ return 0; \ } \ \ if (!ini_putl(item->section, item->key, dest, config_path)) { \ return -1; \ } \ \ return 0; \ } \ \ void INI_ConfigOverride##ID(INI_ConfigItem* item, uint8_t argc, const char* argv[]) { \ if (!item->cmdline_option) { \ return; \ } \ const char* cmdline_buffer; \ char* rest_of_string; \ static T dest; \ static T config_value; \ config_value = *((T*) item->dest); \ if ((cmdline_buffer = INI_ConfigGetCommandlineOption(argc, argv, item->cmdline_option))) { \ dest = strtol(cmdline_buffer, &rest_of_string, 10); \ if (strcmp(cmdline_buffer, rest_of_string) != 0) { \ INI_ConfigEnsureValid##ID(item, dest, config_value); \ return; \ } \ } \ } INI_CONFIG_IMPLEMENT_INT_TYPE(U8, uint8_t); INI_CONFIG_IMPLEMENT_INT_TYPE(U16, uint16_t); INI_CONFIG_IMPLEMENT_INT_TYPE(U32, uint32_t); INI_CONFIG_IMPLEMENT_INT_TYPE(I8, int8_t); INI_CONFIG_IMPLEMENT_INT_TYPE(I16, int16_t); INI_CONFIG_IMPLEMENT_INT_TYPE(I32, int32_t);