Define simple configuration on INI files.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

94 lignes
3.0 KiB

  1. #include "int.h"
  2. #define INI_CONFIG_IMPLEMENT_INT_TYPE(ID, T) \
  3. typedef bool INI_ConfigValidate##ID(T); \
  4. \
  5. typedef T INI_ConfigDeserialize##ID(const char*, void*); \
  6. \
  7. typedef void INI_ConfigSerialize##ID(T, const char[128], void*); \
  8. \
  9. void INI_ConfigEnsureValid##ID(INI_ConfigItem* item, T raw_value, T default_value) { \
  10. T* dest = item->dest; \
  11. if (item->validator) { \
  12. INI_ConfigValidate##ID* validate = item->validator; \
  13. if (validate(raw_value)) { \
  14. *dest = raw_value; \
  15. return; \
  16. } \
  17. *dest = default_value; \
  18. return; \
  19. } \
  20. *dest = raw_value; \
  21. } \
  22. \
  23. void INI_ConfigLoad##ID(INI_ConfigItem* item, const char* config_path, void* item_array) { \
  24. static T raw_value; \
  25. static T default_value; \
  26. default_value = *((T*) item->default_value); \
  27. if (item->transformer.deserialize && item->transformer.serialize) { \
  28. INI_ConfigDeserialize##ID* deserialize = item->transformer.deserialize; \
  29. INI_ConfigSerialize##ID* serialize = item->transformer.serialize; \
  30. const char serialized_default_value[128]; \
  31. if (default_value) { \
  32. serialize(default_value, serialized_default_value, item_array); \
  33. } \
  34. char buffer[128]; \
  35. ini_gets(item->section, item->key, serialized_default_value, buffer, 128, config_path); \
  36. raw_value = deserialize(buffer, item_array); \
  37. } else { \
  38. raw_value = ini_getl(item->section, item->key, default_value, config_path); \
  39. } \
  40. INI_ConfigEnsureValid##ID(item, raw_value, default_value); \
  41. } \
  42. \
  43. INI_ConfigSaveItemResult INI_ConfigSave##ID(INI_ConfigItem* item, const char* config_path, void* item_array) { \
  44. T dest = *((T*) item->dest); \
  45. if (item->validator) { \
  46. INI_ConfigValidate##ID* validate = item->validator; \
  47. if (!validate(dest)) { \
  48. dest = *((const T*) item->default_value); \
  49. } \
  50. } \
  51. \
  52. if (item->transformer.deserialize && item->transformer.serialize) { \
  53. INI_ConfigSerialize##ID* serialize = item->transformer.serialize; \
  54. const char serialized_value[128]; \
  55. serialize(dest, serialized_value, item_array); \
  56. if (!ini_puts(item->section, item->key, serialized_value, config_path)) { \
  57. return -1; \
  58. } \
  59. return 0; \
  60. } \
  61. \
  62. if (!ini_putl(item->section, item->key, dest, config_path)) { \
  63. return -1; \
  64. } \
  65. \
  66. return 0; \
  67. } \
  68. \
  69. void INI_ConfigOverride##ID(INI_ConfigItem* item, uint8_t argc, const char* argv[]) { \
  70. if (!item->cmdline_option) { \
  71. return; \
  72. } \
  73. const char* cmdline_buffer; \
  74. char* rest_of_string; \
  75. static T dest; \
  76. static T config_value; \
  77. config_value = *((T*) item->dest); \
  78. if ((cmdline_buffer = INI_ConfigGetCommandlineOption(argc, argv, item->cmdline_option))) { \
  79. dest = strtol(cmdline_buffer, &rest_of_string, 10); \
  80. if (strcmp(cmdline_buffer, rest_of_string) != 0) { \
  81. INI_ConfigEnsureValid##ID(item, dest, config_value); \
  82. return; \
  83. } \
  84. } \
  85. }
  86. INI_CONFIG_IMPLEMENT_INT_TYPE(U8, uint8_t);
  87. INI_CONFIG_IMPLEMENT_INT_TYPE(U16, uint16_t);
  88. INI_CONFIG_IMPLEMENT_INT_TYPE(U32, uint32_t);
  89. INI_CONFIG_IMPLEMENT_INT_TYPE(I8, int8_t);
  90. INI_CONFIG_IMPLEMENT_INT_TYPE(I16, int16_t);
  91. INI_CONFIG_IMPLEMENT_INT_TYPE(I32, int32_t);