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.

100 lignes
2.8 KiB

  1. #include "string.h"
  2. typedef bool INI_ConfigLoadParamsStringValidator(const char*);
  3. void INI_ConfigEnsureValidString(INI_ConfigItem* item, const char* buffer) {
  4. if (item->validator) {
  5. INI_ConfigLoadParamsStringValidator* validator = item->validator;
  6. if (validator(buffer)) {
  7. memcpy(item->dest, buffer, item->type.size);
  8. return;
  9. }
  10. memcpy(item->dest, item->default_value, item->type.size);
  11. return;
  12. }
  13. memcpy(item->dest, buffer, item->type.size);
  14. }
  15. void INI_ConfigLoadString(INI_ConfigItem* item, const char* config_path) {
  16. char buffer[item->type.size];
  17. ini_gets(item->section, item->key, item->default_value, buffer, (int32_t) item->type.size, config_path);
  18. INI_ConfigEnsureValidString(item, buffer);
  19. }
  20. INI_ConfigSaveItemResult INI_ConfigSaveString(INI_ConfigItem* item, const char* config_path) {
  21. const char* dest = (const char*) item->dest;
  22. if (item->validator) {
  23. INI_ConfigLoadParamsStringValidator* validator = item->validator;
  24. if (!validator(dest)) {
  25. dest = (const char*) item->default_value;
  26. }
  27. }
  28. if (!ini_puts(item->section, item->key, dest, config_path)) {
  29. return INI_CONFIG_SAVE_ITEM_ERROR;
  30. }
  31. return INI_CONFIG_SAVE_ITEM_OK;
  32. }
  33. void INI_ConfigOverrideString(INI_ConfigItem* item, uint8_t argc, const char* argv[]) {
  34. if (!item->cmdline_option) {
  35. return;
  36. }
  37. const char* cmdline_buffer;
  38. if ((cmdline_buffer = INI_ConfigGetCommandlineOption(argc, argv, item->cmdline_option))) {
  39. INI_ConfigEnsureValidString(item, cmdline_buffer);
  40. }
  41. }
  42. void INI_ConfigLoad(INI_ConfigItem item[], const char* config_path) {
  43. uint8_t i;
  44. for (i = 0; item[i].type.size > 0; i += 1) {
  45. if (!item[i].type.load) {
  46. continue;
  47. }
  48. item[i].type.load(&item[i], config_path);
  49. }
  50. }
  51. INI_ConfigSaveResult INI_ConfigSave(INI_ConfigItem item[], const char* config_path) {
  52. uint8_t i;
  53. int32_t problems = 0;
  54. for (i = 0; item[i].type.size > 0; i += 1) {
  55. int32_t result = item[i].type.save ? item[i].type.save(&item[i], config_path) : 0;
  56. if (result < 0) {
  57. problems |= (1 << (int32_t) i);
  58. }
  59. }
  60. return -problems;
  61. }
  62. void INI_ConfigOverride(INI_ConfigItem item[], uint8_t argc, const char* argv[]) {
  63. uint8_t i;
  64. for (i = 0; item[i].type.size > 0; i += 1) {
  65. if (!item[i].type.override) {
  66. continue;
  67. }
  68. item[i].type.override(&item[i], argc, argv);
  69. // TODO specify command-line arg external from config item?
  70. }
  71. }
  72. INI_ConfigInitializeResult INI_ConfigInitialize(INI_ConfigItem item[], const char* config_path, uint8_t argc, const char* argv[]) {
  73. INI_ConfigLoad(item, config_path);
  74. INI_ConfigSaveResult save_result = INI_ConfigSave(item, config_path);
  75. if (save_result < 0) {
  76. return INI_CONFIG_INITIALIZE_RESULT_ERROR;
  77. }
  78. INI_ConfigOverride(item, argc, argv);
  79. if (save_result > 0) {
  80. return INI_CONFIG_INITIALIZE_RESULT_WARNING;
  81. }
  82. return INI_CONFIG_INITIALIZE_RESULT_OK;
  83. }