static int config_parse(struct darray *sections, const char *file, bool always_open) { char *file_data; struct lexer lex; struct base_token token; struct strref section_name; FILE *f; f = os_fopen(file, "rb"); if (always_open && !f) f = os_fopen(file, "w+"); if (!f) return CONFIG_FILENOTFOUND; os_fread_utf8(f, &file_data); fclose(f); if (!file_data) return CONFIG_SUCCESS; lexer_init(&lex); lexer_start_move(&lex, file_data); base_token_clear(&token); while (lexer_getbasetoken(&lex, &token, PARSE_WHITESPACE)) { struct config_section *section; while (token.type == BASETOKEN_WHITESPACE) { if (!lexer_getbasetoken(&lex, &token, PARSE_WHITESPACE)) goto complete; } if (*token.text.array != '[') { while (!is_newline(*token.text.array)) { if (!lexer_getbasetoken(&lex, &token, PARSE_WHITESPACE)) goto complete; } continue; } strref_clear(§ion_name); config_parse_string(&lex, §ion_name, ']'); if (!section_name.len) break; section = darray_push_back_new(sizeof(struct config_section), sections); section->name = bstrdup_n(section_name.array, section_name.len); config_parse_section(section, &lex); } complete: lexer_free(&lex); return CONFIG_SUCCESS; }
static void config_parse_section(struct config_section *section, struct lexer *lex) { struct base_token token; while (lexer_getbasetoken(lex, &token, false)) { struct strref name, value; while (token.type == BASETOKEN_WHITESPACE) { if (!lexer_getbasetoken(lex, &token, false)) return; } if (token.type == BASETOKEN_OTHER) { if (*token.text.array == '#') { do { if (!lexer_getbasetoken(lex, &token, false)) return; } while (!is_newline(*token.text.array)); continue; } else if (*token.text.array == '[') { lex->offset--; return; } } strref_copy(&name, &token.text); if (!config_parse_string(lex, &name, '=')) continue; strref_clear(&value); config_parse_string(lex, &value, 0); config_add_item(§ion->items, &name, &value); } }
void read_config(const char *configfile, config_table_t **params) { ham_status_t st; char *buf; FILE *fp; long len; hlog(LOG_DBG, "Parsing configuration file %s\n", configfile); /* read the whole file into 'buf' */ fp=fopen(configfile, "rt"); if (!fp) { hlog(LOG_FATAL, "Failed to open config file %s: %s\n", configfile, strerror(errno)); exit(-1); } fseek(fp, 0, SEEK_END); len=ftell(fp); fseek(fp, 0, SEEK_SET); buf=(char *)malloc(len+1); /* for zero-terminating byte */ if (fread(buf, 1, len, fp)!=len) { hlog(LOG_FATAL, "Failed to read config file %s: %s\n", configfile, strerror(errno)); exit(-1); } fclose(fp); buf[len]='\0'; /* parse the file */ st=config_parse_string(buf, params); if (st) { hlog(LOG_FATAL, "failed to read configuration file: %s\n", ham_strerror(st)); exit(-1); } /* clean up */ free(buf); }
static void parse_config_data(struct darray *sections, struct lexer *lex) { struct strref section_name; struct base_token token; base_token_clear(&token); while (lexer_getbasetoken(lex, &token, PARSE_WHITESPACE)) { struct config_section *section; while (token.type == BASETOKEN_WHITESPACE) { if (!lexer_getbasetoken(lex, &token, PARSE_WHITESPACE)) return; } if (*token.text.array != '[') { while (!is_newline(*token.text.array)) { if (!lexer_getbasetoken(lex, &token, PARSE_WHITESPACE)) return; } continue; } strref_clear(§ion_name); config_parse_string(lex, §ion_name, ']'); if (!section_name.len) return; section = darray_push_back_new(sizeof(struct config_section), sections); section->name = bstrdup_n(section_name.array, section_name.len); config_parse_section(section, lex); } }