#include "ark_parser.h" static void strip_newline(char* str) { int len = strlen(str); while(len > 0 && (str[len-1] == '\n' || str[len-1] == '\r')) { str[len-1] = '\0'; len--; } } static char* trim_whitespace(char* str) { while(*str == ' ' || *str == '\t') str++; int len = strlen(str); while(len > 0 && (str[len-1] == ' ' || str[len-1] == '\t')) { str[len-1] = '\0'; len--; } return str; } ArkConfig* ark_parse(const char* filepath) { ArkConfig* config = (ArkConfig*)malloc(sizeof(ArkConfig)); memset(config, 0, sizeof(ArkConfig)); strncpy(config->filepath, filepath, sizeof(config->filepath)-1); FILE* f = fopen(filepath, "r"); if(!f) return config; char line[MAX_LINE_LEN]; ArkSection* curr_sec = NULL; while(fgets(line, sizeof(line), f)) { strip_newline(line); char* trimmed = trim_whitespace(line); if(strlen(trimmed) == 0 || trimmed[0] == '#') continue; // Check for section if(strncmp(trimmed, "---", 3) == 0) { char* end = strstr(trimmed + 3, "---"); if(end && config->section_count < MAX_SECTIONS) { *end = '\0'; curr_sec = &config->sections[config->section_count++]; strncpy(curr_sec->name, trim_whitespace(trimmed + 3), 255); } continue; } // Check for Key=Value or Key:Value char* sep = strchr(trimmed, '='); if(!sep) sep = strchr(trimmed, ':'); if(sep) { *sep = '\0'; char* key = trim_whitespace(trimmed); char* val = trim_whitespace(sep + 1); if(curr_sec) { if(curr_sec->pair_count < MAX_KEYS) { strncpy(curr_sec->pairs[curr_sec->pair_count].key, key, 255); strncpy(curr_sec->pairs[curr_sec->pair_count].value, val, 511); curr_sec->pair_count++; } } else { if(config->global_count < MAX_KEYS) { strncpy(config->global_pairs[config->global_count].key, key, 255); strncpy(config->global_pairs[config->global_count].value, val, 511); config->global_count++; } } } else { if(config->standalone_count < MAX_STANDALONE) { strncpy(config->standalone[config->standalone_count++], trimmed, 511); } } } fclose(f); return config; } const char* ark_get_global(ArkConfig* config, const char* key) { for(int i = 0; i < config->global_count; i++) { if(strcmp(config->global_pairs[i].key, key) == 0) { return config->global_pairs[i].value; } } return NULL; } const char* ark_get_section_val(ArkConfig* config, const char* section, const char* key) { for(int i = 0; i < config->section_count; i++) { if(strcmp(config->sections[i].name, section) == 0) { for(int j = 0; j < config->sections[i].pair_count; j++) { if(strcmp(config->sections[i].pairs[j].key, key) == 0) { return config->sections[i].pairs[j].value; } } } } return NULL; } void ark_set_global(ArkConfig* config, const char* key, const char* value) { for(int i = 0; i < config->global_count; i++) { if(strcmp(config->global_pairs[i].key, key) == 0) { strncpy(config->global_pairs[i].value, value, 511); return; } } if(config->global_count < MAX_KEYS) { strncpy(config->global_pairs[config->global_count].key, key, 255); strncpy(config->global_pairs[config->global_count].value, value, 511); config->global_count++; } } void ark_dump(ArkConfig* config, const char* filepath) { FILE* f = fopen(filepath, "w"); if(!f) return; for(int i = 0; i < config->global_count; i++) { fprintf(f, "%s = %s\n", config->global_pairs[i].key, config->global_pairs[i].value); } for(int i = 0; i < config->section_count; i++) { fprintf(f, "\n--- %s ---\n\n", config->sections[i].name); for(int j = 0; j < config->sections[i].pair_count; j++) { fprintf(f, "%s = %s\n", config->sections[i].pairs[j].key, config->sections[i].pairs[j].value); } } if(config->standalone_count > 0) { fprintf(f, "\n"); for(int i = 0; i < config->standalone_count; i++) { fprintf(f, "%s\n", config->standalone[i]); } } fclose(f); } void ark_free(ArkConfig* config) { if(config) free(config); }