/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Mupen64plus - ini_reader.c * * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * * Copyright (C) 2008 slougi * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include "ini_reader.h" #define BUF_MAX 4096 static int iscomment(char *line); static ini_entry *parse_entry(char *line); static ini_section *parse_section(char *line); static void dump_entries(ini_section *s, list_t entries); static void dump_sections(ini_file* ini, list_t sections); static ini_entry *parse_entry(char *line) { int i; char *equals_sign = NULL; ini_entry *entry = NULL; char key[BUF_MAX]; char value[BUF_MAX]; memset(key, '\0', BUF_MAX); memset(value, '\0', BUF_MAX); if ((equals_sign = strstr(line, "=")) != NULL) { entry = malloc(sizeof(ini_entry)); for (i = 0; line != equals_sign; i++, line++) { key[i] = *line; } line = equals_sign + 1; strncpy(value, line, BUF_MAX); trim(key); entry->key = malloc(strlen(key) + 1); strcpy(entry->key, key); trim(value); entry->value = malloc(strlen(value) + 1); strcpy(entry->value, value); } return entry; } static ini_section *parse_section(char *line) { int i = 0; char buf[BUF_MAX]; char *opening_bracket = NULL; char *closing_bracket = NULL; ini_section *section = NULL; memset(buf, '\0', BUF_MAX); if ((opening_bracket = strstr(line, "[")) == line) { if ((closing_bracket = strstr(line, "]")) != NULL) { while (++opening_bracket != closing_bracket) { buf[i++] = *opening_bracket; } section = malloc(sizeof(ini_section)); section->title = malloc(strlen(buf) + 1); strcpy(section->title, buf); section->entries = NULL; } } return section; } static int iscomment(char *line) { int result = 0; if (strstr(line, "//") == line) { result = 1; } else if (strstr(line, "#") == line) { result = 1; } return result; } ini_file* ini_file_parse(const char* filename) { int i = 0; ini_file *res = NULL; list_t sections = NULL; ini_entry* entry = NULL; ini_section* section = NULL; FILE *fp = fopen(filename, "r"); char buf[BUF_MAX]; if (!fp) { return NULL; } while (fgets(buf, BUF_MAX, fp)) { i++; trim(buf); if (strlen(buf) == 0) { continue; } if ((section = parse_section(buf))) { list_append(§ions, section); } else if ((entry = parse_entry(buf))) { section = list_last_data(sections); if (section) { list_append(§ion->entries, entry); } } else if (iscomment(buf)) { continue; } else { fprintf(stderr, "Couldn't parse line %d in file %s: %s", i, filename, buf); } } if (!list_empty(sections)) { res = malloc(sizeof(ini_file)); res->filename = malloc(strlen(filename) + 1); strcpy(res->filename, filename); res->sections = sections; } fclose(fp); return res; } void ini_file_free(ini_file **ini) { list_t p1, p2; ini_section* section; ini_entry* entry; free((*ini)->filename); list_foreach((*ini)->sections, p1) { section = p1->data; free(section->title); list_foreach(section->entries, p2) { entry = p2->data; free(entry->key); free(entry->value); } } free(*ini); *ini = 0; }