ark_parser.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include "ark_parser.h"
  2. static void strip_newline(char* str) {
  3. int len = strlen(str);
  4. while(len > 0 && (str[len-1] == '\n' || str[len-1] == '\r')) {
  5. str[len-1] = '\0';
  6. len--;
  7. }
  8. }
  9. static char* trim_whitespace(char* str) {
  10. while(*str == ' ' || *str == '\t') str++;
  11. int len = strlen(str);
  12. while(len > 0 && (str[len-1] == ' ' || str[len-1] == '\t')) {
  13. str[len-1] = '\0';
  14. len--;
  15. }
  16. return str;
  17. }
  18. ArkConfig* ark_parse(const char* filepath) {
  19. ArkConfig* config = (ArkConfig*)malloc(sizeof(ArkConfig));
  20. memset(config, 0, sizeof(ArkConfig));
  21. strncpy(config->filepath, filepath, sizeof(config->filepath)-1);
  22. FILE* f = fopen(filepath, "r");
  23. if(!f) return config;
  24. char line[MAX_LINE_LEN];
  25. ArkSection* curr_sec = NULL;
  26. while(fgets(line, sizeof(line), f)) {
  27. strip_newline(line);
  28. char* trimmed = trim_whitespace(line);
  29. if(strlen(trimmed) == 0 || trimmed[0] == '#') continue;
  30. // Check for section
  31. if(strncmp(trimmed, "---", 3) == 0) {
  32. char* end = strstr(trimmed + 3, "---");
  33. if(end && config->section_count < MAX_SECTIONS) {
  34. *end = '\0';
  35. curr_sec = &config->sections[config->section_count++];
  36. strncpy(curr_sec->name, trim_whitespace(trimmed + 3), 255);
  37. }
  38. continue;
  39. }
  40. // Check for Key=Value or Key:Value
  41. char* sep = strchr(trimmed, '=');
  42. if(!sep) sep = strchr(trimmed, ':');
  43. if(sep) {
  44. *sep = '\0';
  45. char* key = trim_whitespace(trimmed);
  46. char* val = trim_whitespace(sep + 1);
  47. if(curr_sec) {
  48. if(curr_sec->pair_count < MAX_KEYS) {
  49. strncpy(curr_sec->pairs[curr_sec->pair_count].key, key, 255);
  50. strncpy(curr_sec->pairs[curr_sec->pair_count].value, val, 511);
  51. curr_sec->pair_count++;
  52. }
  53. } else {
  54. if(config->global_count < MAX_KEYS) {
  55. strncpy(config->global_pairs[config->global_count].key, key, 255);
  56. strncpy(config->global_pairs[config->global_count].value, val, 511);
  57. config->global_count++;
  58. }
  59. }
  60. } else {
  61. if(config->standalone_count < MAX_STANDALONE) {
  62. strncpy(config->standalone[config->standalone_count++], trimmed, 511);
  63. }
  64. }
  65. }
  66. fclose(f);
  67. return config;
  68. }
  69. const char* ark_get_global(ArkConfig* config, const char* key) {
  70. for(int i = 0; i < config->global_count; i++) {
  71. if(strcmp(config->global_pairs[i].key, key) == 0) {
  72. return config->global_pairs[i].value;
  73. }
  74. }
  75. return NULL;
  76. }
  77. const char* ark_get_section_val(ArkConfig* config, const char* section, const char* key) {
  78. for(int i = 0; i < config->section_count; i++) {
  79. if(strcmp(config->sections[i].name, section) == 0) {
  80. for(int j = 0; j < config->sections[i].pair_count; j++) {
  81. if(strcmp(config->sections[i].pairs[j].key, key) == 0) {
  82. return config->sections[i].pairs[j].value;
  83. }
  84. }
  85. }
  86. }
  87. return NULL;
  88. }
  89. void ark_set_global(ArkConfig* config, const char* key, const char* value) {
  90. for(int i = 0; i < config->global_count; i++) {
  91. if(strcmp(config->global_pairs[i].key, key) == 0) {
  92. strncpy(config->global_pairs[i].value, value, 511);
  93. return;
  94. }
  95. }
  96. if(config->global_count < MAX_KEYS) {
  97. strncpy(config->global_pairs[config->global_count].key, key, 255);
  98. strncpy(config->global_pairs[config->global_count].value, value, 511);
  99. config->global_count++;
  100. }
  101. }
  102. void ark_dump(ArkConfig* config, const char* filepath) {
  103. FILE* f = fopen(filepath, "w");
  104. if(!f) return;
  105. for(int i = 0; i < config->global_count; i++) {
  106. fprintf(f, "%s = %s\n", config->global_pairs[i].key, config->global_pairs[i].value);
  107. }
  108. for(int i = 0; i < config->section_count; i++) {
  109. fprintf(f, "\n--- %s ---\n\n", config->sections[i].name);
  110. for(int j = 0; j < config->sections[i].pair_count; j++) {
  111. fprintf(f, "%s = %s\n", config->sections[i].pairs[j].key, config->sections[i].pairs[j].value);
  112. }
  113. }
  114. if(config->standalone_count > 0) {
  115. fprintf(f, "\n");
  116. for(int i = 0; i < config->standalone_count; i++) {
  117. fprintf(f, "%s\n", config->standalone[i]);
  118. }
  119. }
  120. fclose(f);
  121. }
  122. void ark_free(ArkConfig* config) {
  123. if(config) free(config);
  124. }