2D Run-and-gun shooter inspired by One Man's Doomsday, Counter-Strike, and Metal Slug.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

260 lines
6.7 KiB

  1. #include "IZ_config.h"
  2. const char* IZ_ConfigGetCommandlineOption(u8 argc, const char* argv[], const char* val) {
  3. size_t n = strlen(val);
  4. int c = argc;
  5. while (--c > 0) {
  6. if (!strncmp(argv[c], val, n)) {
  7. if (!*(argv[c] + n) && c < argc - 1) {
  8. /* coverity treats unchecked argv as "tainted" */
  9. if (!argv[c + 1] || strlen(argv[c + 1]) > 1024)
  10. return NULL;
  11. return argv[c + 1];
  12. }
  13. if (argv[c][n] == '=')
  14. return &argv[c][n + 1];
  15. return argv[c] + n;
  16. }
  17. }
  18. return NULL;
  19. }
  20. typedef bool IZ_ConfigLoadParamsStringValidator(const char*);
  21. typedef bool IZ_ConfigLoadParamsU16Validator(u16);
  22. typedef bool IZ_ConfigLoadParamsU8Validator(u8);
  23. void IZ_ConfigEnsureValidString(IZ_ConfigItem item, const char* buffer) {
  24. char dest[item.dest_size];
  25. if (item.validator) {
  26. IZ_ConfigLoadParamsStringValidator* validator = item.validator;
  27. if (validator(buffer)) {
  28. memcpy_s(dest, item.dest_size, buffer, item.dest_size);
  29. item.dest = &dest;
  30. return;
  31. }
  32. memcpy_s(dest, item.dest_size, item.default_value, item.dest_size);
  33. item.dest = &dest;
  34. return;
  35. }
  36. memcpy_s(dest, item.dest_size, buffer, item.dest_size);
  37. item.dest = &dest;
  38. }
  39. void IZ_ConfigLoadString(IZ_ConfigItem item, const char* config_path) {
  40. char buffer[item.dest_size];
  41. ini_gets(item.section, item.key, item.default_value, buffer, (i32) item.dest_size, config_path);
  42. IZ_ConfigEnsureValidString(item, buffer);
  43. }
  44. void IZ_ConfigEnsureValidU8(IZ_ConfigItem item, u8 raw_value, u8 default_value) {
  45. if (item.validator) {
  46. IZ_ConfigLoadParamsU8Validator* validator = item.validator;
  47. if (validator(raw_value)) {
  48. item.dest = &raw_value;
  49. return;
  50. }
  51. item.dest = &default_value;
  52. return;
  53. }
  54. item.dest = &raw_value;
  55. }
  56. void IZ_ConfigLoadU8(IZ_ConfigItem item, const char* config_path) {
  57. static u8 raw_value;
  58. static u8 default_value;
  59. default_value = *((u8*) item.default_value);
  60. raw_value = ini_getl(item.section, item.key, default_value, config_path);
  61. IZ_ConfigEnsureValidU8(item, raw_value, default_value);
  62. }
  63. void IZ_ConfigEnsureValidU16(IZ_ConfigItem item, u16 raw_value, u16 default_value) {
  64. if (item.validator) {
  65. IZ_ConfigLoadParamsU16Validator* validator = item.validator;
  66. if (validator(raw_value)) {
  67. item.dest = &raw_value;
  68. return;
  69. }
  70. item.dest = &default_value;
  71. return;
  72. }
  73. item.dest = &raw_value;
  74. }
  75. void IZ_ConfigLoadU16(IZ_ConfigItem item, const char* config_path) {
  76. static u16 raw_value;
  77. static u16 default_value;
  78. default_value = *((u16*) item.default_value);
  79. raw_value = ini_getl(item.section, item.key, default_value, config_path);
  80. IZ_ConfigEnsureValidU16(item, raw_value, default_value);
  81. }
  82. void IZ_ConfigLoad(IZ_ConfigItem item[], const char* config_path) {
  83. u8 i;
  84. for (i = 0; item[i].type != IZ_CONFIG_TYPE_VOID; i += 1) {
  85. switch (item[i].type) {
  86. case IZ_CONFIG_TYPE_STRING:
  87. IZ_ConfigLoadString(item[i], config_path);
  88. break;
  89. case IZ_CONFIG_TYPE_U8:
  90. IZ_ConfigLoadU8(item[i], config_path);
  91. break;
  92. case IZ_CONFIG_TYPE_U16:
  93. IZ_ConfigLoadU16(item[i], config_path);
  94. break;
  95. default:
  96. break;
  97. }
  98. }
  99. }
  100. IZ_ProcedureResult IZ_ConfigSaveU8(IZ_ConfigItem item, const char* config_path) {
  101. u8 dest = *((u8*) item.dest);
  102. if (item.validator) {
  103. IZ_ConfigLoadParamsU8Validator* validator = item.validator;
  104. if (!validator(dest)) {
  105. dest = *((const u8*) item.default_value);
  106. }
  107. }
  108. if (!ini_putl(item.section, item.key, dest, config_path)) {
  109. return -1;
  110. }
  111. return 0;
  112. }
  113. IZ_ProcedureResult IZ_ConfigSaveU16(IZ_ConfigItem item, const char* config_path) {
  114. u16 dest = *((u16*) item.dest);
  115. if (item.validator) {
  116. IZ_ConfigLoadParamsU8Validator* validator = item.validator;
  117. if (!validator(dest)) {
  118. dest = *((const u16*) item.default_value);
  119. }
  120. }
  121. if (!ini_putl(item.section, item.key, dest, config_path)) {
  122. return -1;
  123. }
  124. return 0;
  125. }
  126. IZ_ProcedureResult IZ_ConfigSaveString(IZ_ConfigItem item, const char* config_path) {
  127. const char* dest = (const char*) item.dest;
  128. if (item.validator) {
  129. IZ_ConfigLoadParamsStringValidator* validator = item.validator;
  130. if (!validator(dest)) {
  131. dest = (const char*) item.default_value;
  132. }
  133. }
  134. if (!ini_puts(item.section, item.key, dest, config_path)) {
  135. return -1;
  136. }
  137. return 0;
  138. }
  139. IZ_ProcedureResult IZ_ConfigSave(IZ_ConfigItem item[], const char* config_path) {
  140. u8 i;
  141. u16 problems = 0;
  142. for (i = 0; item[i].type != IZ_CONFIG_TYPE_VOID; i += 1) {
  143. switch (item[i].type) {
  144. case IZ_CONFIG_TYPE_STRING:
  145. IZ_ConfigSaveString(item[i], config_path);
  146. break;
  147. case IZ_CONFIG_TYPE_U8:
  148. IZ_ConfigSaveU8(item[i], config_path);
  149. break;
  150. case IZ_CONFIG_TYPE_U16:
  151. IZ_ConfigSaveU16(item[i], config_path);
  152. break;
  153. default:
  154. break;
  155. }
  156. }
  157. return -problems;
  158. }
  159. void IZ_ConfigOverrideU8(IZ_ConfigItem item, u8 argc, const char* argv[]) {
  160. if (!item.cmdline_option) {
  161. return;
  162. }
  163. const char* cmdline_buffer;
  164. char* rest_of_string;
  165. static u8 dest;
  166. static u8 default_value;
  167. default_value = *((u16*) item.default_value);
  168. if ((cmdline_buffer = IZ_ConfigGetCommandlineOption(argc, argv, item.cmdline_option))) {
  169. dest = strtol(cmdline_buffer, &rest_of_string, 10);
  170. if (strcmp(cmdline_buffer, rest_of_string) != 0) {
  171. IZ_ConfigEnsureValidU8(item, dest, default_value);
  172. return;
  173. }
  174. item.dest = &default_value;
  175. }
  176. }
  177. void IZ_ConfigOverrideU16(IZ_ConfigItem item, u8 argc, const char* argv[]) {
  178. if (!item.cmdline_option) {
  179. return;
  180. }
  181. const char* cmdline_buffer;
  182. char* rest_of_string;
  183. static u16 dest;
  184. static u16 default_value;
  185. default_value = *((u16*) item.default_value);
  186. if ((cmdline_buffer = IZ_ConfigGetCommandlineOption(argc, argv, item.cmdline_option))) {
  187. dest = strtol(cmdline_buffer, &rest_of_string, 10);
  188. if (strcmp(cmdline_buffer, rest_of_string) != 0) {
  189. IZ_ConfigEnsureValidU16(item, dest, default_value);
  190. return;
  191. }
  192. item.dest = &default_value;
  193. }
  194. }
  195. void IZ_ConfigOverrideString(IZ_ConfigItem item, u8 argc, const char* argv[]) {
  196. if (!item.cmdline_option) {
  197. return;
  198. }
  199. const char* cmdline_buffer;
  200. if ((cmdline_buffer = IZ_ConfigGetCommandlineOption(argc, argv, item.cmdline_option))) {
  201. IZ_ConfigEnsureValidString(item, cmdline_buffer);
  202. }
  203. }
  204. void IZ_ConfigOverride(IZ_ConfigItem item[], u8 argc, const char* argv[]) {
  205. u8 i;
  206. for (i = 0; item[i].type != IZ_CONFIG_TYPE_VOID; i += 1) {
  207. switch (item[i].type) {
  208. case IZ_CONFIG_TYPE_U8:
  209. IZ_ConfigOverrideU8(item[i], argc, argv);
  210. break;
  211. case IZ_CONFIG_TYPE_U16:
  212. IZ_ConfigOverrideU16(item[i], argc, argv);
  213. break;
  214. case IZ_CONFIG_TYPE_STRING:
  215. IZ_ConfigOverrideString(item[i], argc, argv);
  216. break;
  217. default:
  218. break;
  219. }
  220. }
  221. }
  222. void IZ_ConfigInit(IZ_ConfigItem item[], const char* config_path, u8 argc, const char* argv[]) {
  223. IZ_ConfigLoad(item, config_path);
  224. if (IZ_ConfigSave(item, config_path)) {
  225. // TODO log errors in saving
  226. }
  227. IZ_ConfigOverride(item, argc, argv);
  228. }