ini.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4. #include "fs.h"
  5. #include "ini.h"
  6. void ini_read(char* path, ini_read_callback_fn fn, void* user_data) {
  7. size_t src_sz;
  8. char* src, *s, *src_end, *e, *h;
  9. char* section_name = "";
  10. char* key, *value;
  11. char quote_c;
  12. src = readWholeFileExtra(path, 1, &src_sz);
  13. src[src_sz] = '\n';
  14. // technically it should handle embedded nulls
  15. src_end = src + src_sz;
  16. s = src;
  17. while(s < src_end) {
  18. char c = *s;
  19. if(isspace(c) || c == 0) {
  20. s++; continue;
  21. }
  22. // section headers
  23. if(c == '[') {
  24. e = strchr(s, ']');
  25. section_name = s + 1;
  26. *e = 0;
  27. s = e + 1;
  28. continue;
  29. }
  30. // find the end of the key
  31. h = s;
  32. e = s;
  33. key = s;
  34. value = NULL;
  35. while(1) {
  36. if(h >= src_end) {
  37. // valueless last key in the file
  38. e[1] = 0;
  39. s = h + 1;
  40. goto VALUELESS;
  41. }
  42. // key with no value
  43. if(*h == '\n') {
  44. e[1] = 0;
  45. s = h + 1;
  46. goto VALUELESS;
  47. }
  48. if(*h == '=') {
  49. // end of key
  50. break;
  51. }
  52. if(!isspace(*h)) e = h;
  53. h++;
  54. }
  55. e[1] = 0;
  56. s = h + 1;
  57. // skip to te first bit of content
  58. s += strspn(s, " \t\r\n");
  59. // find the end of the value
  60. if(*s == '"' || *s == '\'') {
  61. quote_c = *s;
  62. s++;
  63. }
  64. else quote_c = '\n';
  65. h = s;
  66. e = s;
  67. while(1) {
  68. if(h >= src_end) {
  69. // found the end
  70. break;
  71. }
  72. if(*h == quote_c) break;
  73. if(!isspace(*h)) e = h;
  74. h++;
  75. }
  76. e[1] = 0;
  77. value = s == e ? NULL : s;
  78. VALUELESS:
  79. if(fn(section_name, key, value, user_data)) break;
  80. s = e + 1;
  81. }
  82. free(src);
  83. }